Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
AppError
✓ import { AppError } from 'addons-scanner-utils';
✗ import { ApiError } from 'addons-scanner-utils';
const { AppError } = require('addons-scanner-utils');
The error class was renamed from `ApiError` to `AppError` in version 14.0.0. This package is primarily ESM-first since Node.js 22+ is a requirement.
makeJWT
✓ import { makeJWT } from 'addons-scanner-utils';
✗ const { makeJWT } = require('addons-scanner-utils');
Introduced in version 13.1.0 to facilitate JWT generation for AMO. Ensure your project environment is configured for ES modules.
downloadFile
✓ import { downloadFile } from 'addons-scanner-utils';
✗ const { downloadFile } = require('addons-scanner-utils');
A utility function for downloading files, introduced in version 13.1.0. For older Express handler functionality for XPIs, see breaking change warnings.
This quickstart demonstrates a basic Express.js application integrating `addons-scanner-utils` for error handling (`AppError`), JWT generation (`makeJWT`), file downloading (`downloadFile`), and custom authentication logic using `safe-compare`.
import express, { Request, Response, NextFunction } from 'express';
import { AppError, makeJWT, downloadFile } from 'addons-scanner-utils';
import safeCompare from 'safe-compare'; // from peer dependency
const app = express();
const port = 3000;
// A placeholder for a secret key for HMAC-SHA256 or JWT signing
const JWT_SECRET = process.env.JWT_SECRET ?? 'super_secret_jwt_key_please_change';
const STATIC_AUTH_TOKEN = process.env.STATIC_AUTH_TOKEN ?? 'my-secure-token-123_please_change';
// Middleware to simulate an authentication check (e.g., Bearer token)
function authMiddleware(req: Request, res: Response, next: NextFunction) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return next(new AppError('Unauthorized: Bearer token missing or malformed', 401));
}
const token = authHeader.split(' ')[1];
// In a real application, validate JWT or compare with a stored secret securely.
// Using safeCompare for demonstration with a static token.
if (!safeCompare(token, STATIC_AUTH_TOKEN)) {
return next(new AppError('Unauthorized: Invalid token', 401));
}
next();
}
app.get('/', (req: Request, res: Response) => {
res.send('Addons Scanner Utils Example API');
});
app.get('/protected', authMiddleware, (req: Request, res: Response) => {
res.json({ message: 'Access granted to protected resource.' });
});
app.get('/jwt', (req: Request, res: Response, next: NextFunction) => {
try {
const issuer = 'your-service';
const expiresInMinutes = 5;
// In a production environment, ensure JWT_SECRET is a strong, securely stored key.
const jwtToken = makeJWT(issuer, JWT_SECRET, expiresInMinutes);
res.json({ jwt: jwtToken, message: `JWT created for ${issuer}, valid for ${expiresInMinutes} minutes.` });
} catch (error) {
next(new AppError('Failed to create JWT', 500, error as Error));
}
});
app.get('/download-example', async (req: Request, res: Response, next: NextFunction) => {
const fileUrl = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'; // Example URL
const destinationPath = '/tmp/downloaded-image.png'; // Ensure /tmp is writable or change path
try {
await downloadFile(fileUrl, destinationPath);
res.json({ message: `File downloaded successfully to ${destinationPath}` });
} catch (error) {
next(new AppError('Failed to download file', 500, error as Error));
}
});
// Error handling middleware
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof AppError) {
console.error(`AppError: ${err.message}`, err.originalError);
res.status(err.statusCode).json({
error: err.name,
message: err.message
});
} else {
console.error('Unhandled error:', err);
res.status(500).json({
error: 'InternalServerError',
message: 'An unexpected error occurred.'
});
}
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Errors
Common errors & fixes
ReferenceError: ApiError is not defined
The `ApiError` class was renamed to `AppError` in version 14.0.0.
fixReplace all occurrences of `ApiError` with `AppError` in your code, including import statements.
Error: This module requires Node.js version 22 or higher.
The application is running in an environment with an outdated Node.js version.
fixUpdate your Node.js runtime to version 22 or a later compatible version.
TypeError: (0 , addons_scanner_utils_1.makeJWT) is not a function
Attempting to use CommonJS `require()` syntax to import ES module named exports.
fixRefactor your import statements to use ES module syntax: `import { makeJWT } from 'addons-scanner-utils';` and ensure your project supports ESM. Unauthorized: Bearer token missing or malformed
The incoming request is missing the `Authorization` header, or its `Bearer` token format is incorrect, or the library's internal auth logic no longer supports this method (v15).
fixEnsure the client sends a correctly formatted `Authorization: Bearer YOUR_TOKEN` header. If using the library's internal auth (pre-v15), verify configuration. For v15+, implement custom Bearer token validation logic.
Audit
Dependencies
expressrequiredPeer dependency for building web APIs and integrating with middleware, crucial for handling requests and responses, especially for authentication layers. Used for HTTP server functionality.
safe-comparerequiredPeer dependency used for constant-time string comparison, important for mitigating timing attacks in authentication and security-sensitive operations.