From 4c6b499a02d46d1c7ac57a75838dcd4c078441f8 Mon Sep 17 00:00:00 2001 From: Rowan Manning <138944+rowanmanning@users.noreply.github.com> Date: Mon, 1 Jul 2024 07:18:42 +0100 Subject: [PATCH 1/2] fix: add type declarations for the logger This is the final package we need to add manual type declarations for, it's also the most complex but I decided to just replicate the existing generated types. Because we no longer need a build step I'm removing all of the build-related tooling and updating the documentation accordingly. Resolves #946 --- .circleci/config.yml | 6 - .gitignore | 1 - docs/contributing.md | 13 +- docs/design.md | 2 +- jsconfig.build.json | 13 -- package.json | 8 +- packages/logger/.npmignore | 2 - packages/logger/lib/index.js | 13 +- packages/logger/lib/logger.js | 198 +++--------------- packages/logger/lib/transforms/legacy-mask.js | 34 +-- packages/logger/package.json | 3 +- packages/logger/test/unit/lib/logger.spec.js | 6 - .../unit/lib/transforms/legacy-mask.spec.js | 8 - packages/logger/types/index.d.ts | 20 ++ packages/logger/types/logger.d.ts | 77 +++++++ .../logger/types/transforms/legacy-mask.d.ts | 18 ++ scripts/clean-generated-types.sh | 3 - 17 files changed, 159 insertions(+), 266 deletions(-) delete mode 100644 jsconfig.build.json create mode 100644 packages/logger/types/index.d.ts create mode 100644 packages/logger/types/logger.d.ts create mode 100644 packages/logger/types/transforms/legacy-mask.d.ts delete mode 100755 scripts/clean-generated-types.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index b01a4b28..d93fac67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -126,9 +126,6 @@ jobs: name: Set npm auth token command: echo "//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}" > ${HOME}/.npmrc - - run: - name: Build packages - command: npm run build - run: name: NPM publish command: ./scripts/circleci-publish.sh @@ -141,9 +138,6 @@ jobs: name: Set npm auth token command: echo "//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}" > ${HOME}/.npmrc - - run: - name: Build packages - command: npm run build - run: name: NPM publish command: ./scripts/circleci-publish.sh --tag=prerelease diff --git a/.gitignore b/.gitignore index 6e6f6664..33fe7ecc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .husky/_ -packages/logger/**/*.d.* coverage node_modules/ resources/logos/dist diff --git a/docs/contributing.md b/docs/contributing.md index 95fadd24..7cd37444 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -26,7 +26,6 @@ We're glad you want to contribute to Reliability Kit! * [Pull request scope](#pull-request-scope) * [Merging pull requests](#merging-pull-requests) * [Releasing](#releasing) - * [Generated files](#generated-files) * [Hard-coding the release version](#hard-coding-the-release-version) * [Correcting releases](#correcting-releases) * [Issue management](#issue-management) @@ -174,7 +173,7 @@ The linters are also run on pull requests and linting errors will block merging, ### Type safety -We do not write TypeScript in this project, but we _do_ write [thorough JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html) and test against it which gives us all the benefits of TypeScript ([more info](./design.md#languages)). +We do not write TypeScript code, but we _do_ write [thorough JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html) and publish type declarations, then test against it which gives us all the benefits of TypeScript ([more info](./design.md#languages)). We do not compile the code in our packages, but we do check that all variables are set to the correct types. If there are any type errors then you should see these in your editor if you're using VS Code. Otherwise type checking can be manually run as part of linting: @@ -269,16 +268,6 @@ If the PR is left alone, it will continue to be updated with new releases as mor Before approving and merging the release PR, make sure you review it. You need to check the package versions that it updates to make sure you’re only releasing the things you expect. -### Generated files - -Before publishing npm packages we do generate TypeScript type declaration files (`.d.ts`) so that TypeScript-based projects which use Reliability Kit will get correct type hinting. - -If a release has caused issues with Type hinting or TypeScript-based projects compiling, then you can inspect the generated files by running the build command locally and viewing the `.d.ts` files in your editor: - -``` -npm run build -``` - ### Hard-coding the release version Sometimes it's necessary to hard-code a release version, for example if commits have been pushed to `main` which don't match our [commit format](#commit-type-prefixes). A more common reason to do this is when you want to publish a prerelease package to experiment before marking it as stable (e.g. publishing a `v0.1.0` before `v1.0.0`). diff --git a/docs/design.md b/docs/design.md index c41fc154..0c03705b 100644 --- a/docs/design.md +++ b/docs/design.md @@ -27,7 +27,7 @@ The combination of the above allows us to work on and publish the packages in th In terms of TypeScript, the key benefits are having type safety and type hinting in your editor. We can achieve both of these without writing TypeScript. Using [JavaScript with JSDoc comments to document types](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html), VSCode (used by the majority of our engineers) offers the same level of type hinting as it does with TypeScript. It's also possible to run the TypeScript type checker against JavaScript code to verify that everything is type safe (e.g. using `tsc --checkJS`). -In order to be useful for TypeScript projects, we do still need to publish our modules with TypeScript type declaration files (`.d.ts`). We made this an automated step during publishing and when authoring modules you should still write JavaScript and JSDoc. +In order to be useful for TypeScript projects, we do still need to publish our modules with TypeScript type declaration files (`.d.ts`). ### CommonJS diff --git a/jsconfig.build.json b/jsconfig.build.json deleted file mode 100644 index f339c6c2..00000000 --- a/jsconfig.build.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "./jsconfig.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "noEmit": false, - "removeComments": true - }, - "include": [ - "packages/logger/**/*.js" - ] -} \ No newline at end of file diff --git a/package.json b/package.json index 6d6c6eab..715f4b2c 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,10 @@ "create-package": "./scripts/create-package.js", "lint": "npm run lint:eslint && npm run lint:tsc", "lint:eslint": "eslint .", - "lint:tsc": "npm run clean && tsc --project ./jsconfig.json", - "clean": "npm run clean:types", - "clean:types": "./scripts/clean-generated-types.sh", - "build": "npm run clean && npm run build:types", - "build:types": "tsc --project ./jsconfig.build.json", + "lint:tsc": "tsc --project ./jsconfig.json", "test": "npm run test:jest && npm run test:modules", "test:jest": "jest --silent", - "test:modules": "npm run build && npm run test --workspaces --if-present", + "test:modules": "npm run test --workspaces --if-present", "prepare": "husky", "postinstall": "npm run build:logos" }, diff --git a/packages/logger/.npmignore b/packages/logger/.npmignore index 5d94aeb0..4b54bd5d 100644 --- a/packages/logger/.npmignore +++ b/packages/logger/.npmignore @@ -1,5 +1,3 @@ -!*.d.ts -!*.d.ts.map CHANGELOG.md docs test diff --git a/packages/logger/lib/index.js b/packages/logger/lib/index.js index 9c4083d7..c7f15c72 100644 --- a/packages/logger/lib/index.js +++ b/packages/logger/lib/index.js @@ -2,17 +2,8 @@ const Logger = require('./logger'); const legacyMask = require('./transforms/legacy-mask'); /** - * @typedef {object} Transforms - * @property {legacyMask} legacyMask - * The legacy mask logger. - */ - -/** - * @typedef {object} DefaultLogger - * @property {typeof Logger} Logger - * The Logger class. - * @property {Transforms} transforms - * Built-in log transforms. + * @typedef {import('@dotcom-reliability-kit/logger').DefaultLogger} DefaultLogger + * @typedef {import('@dotcom-reliability-kit/logger').Transforms} Transforms */ /** @type {Transforms} */ diff --git a/packages/logger/lib/logger.js b/packages/logger/lib/logger.js index 541c7977..82c639e1 100644 --- a/packages/logger/lib/logger.js +++ b/packages/logger/lib/logger.js @@ -4,70 +4,18 @@ const clone = require('lodash.clonedeep'); const appInfo = require('@dotcom-reliability-kit/app-info'); /** - * @typedef {"silly" | "data" | "debug" | "verbose" | "info" | "warn" | "error" | "fatal"} LogLevel - */ - -/** - * @typedef {string | object | Error} LogData - */ - -/** + * @typedef {import('../types/logger').BaseLogData} BaseLogData + * @typedef {import('../types/logger').LogData} LogData + * @typedef {import('../types/logger').LoggerInterface} LoggerInterface + * @typedef {import('../types/logger').LoggerOptions} LoggerOptions + * @typedef {import('../types/logger').LogLevel} LogLevel + * @typedef {import('../types/logger').LogLevelInfo} LogLevelInfo + * @typedef {import('../types/logger').LogTransform} LogTransform + * @typedef {import('../types/logger').LogTransport} LogTransport + * @typedef {import('../types/logger').PrivateLoggerOptions} PrivateLoggerOptions * @typedef {typeof import('pino').stdTimeFunctions.isoTime} TimeFn */ -/** - * @typedef {object} LoggerOptions - * @property {LogData} [baseLogData = {}] - * Base log data which is added to every log output. - * @property {LogLevel} [logLevel = "debug"] - * The maximum log level to output during logging. Logs at levels - * beneath this will be ignored. - * @property {LogTransform[]} [transforms = []] - * Transforms to apply to logs before sending. - * @property {boolean} [withPrettifier = true] - * Whether to prettify log output if it's possible. - */ - -/** - * @typedef {object} PrivateLoggerOptions - * @property {LogTransport} [_transport] - * A transport used to perform logging. This is only for internal use. - */ - -/** - * @callback LogTransform - * @param {{[key: string]: any}} logData - * The log data to transform. - * @returns {{[key: string]: any}} - * Returns the transformed log data. - */ - -/** - * @typedef {object} LogTransport - * @property {string} [level] - * A property used to set the transport log level. - * @property {(...args: any) => any} debug - * Log debug level information. - * @property {(...args: any) => any} error - * Log error level information. - * @property {(...args: any) => any} fatal - * Log fatal level information. - * @property {(...args: any) => any} info - * Log info level information. - * @property {(...args: any) => any} warn - * Log warn level information. - * @property {() => void} [flush] - * Flush async logs ahead of time. - */ - -/** - * @typedef {object} LogLevelInfo - * @property {LogLevel} logLevel - * A canonical alternative level for a given level. - * @property {boolean} isDeprecated - * Whether the original log level is deprecated. - */ - /** * A map of log levels to the underlying log method that * should be called when a log of that level is sent, as @@ -127,15 +75,17 @@ const prettificationAllowed = appInfo.environment !== 'production'; /** * Class representing a logger. + * + * @implements {LoggerInterface} */ -class Logger { +module.exports = class Logger { /** * @type {LogLevel} */ #logLevel = 'debug'; /** - * @type {LogData} + * @type {BaseLogData} */ #baseLogData = {}; @@ -240,38 +190,20 @@ class Logger { } } - /** - * @public - * @type {LogData} - */ get baseLogData() { return this.#baseLogData; } - /** - * @public - * @type {LogLevel} - */ get logLevel() { return this.#logLevel; } - /** - * @public - * @type {LogTransport} - */ get transport() { return this.#logTransport; } /** * Create a child logger with additional base log data. - * - * @public - * @param {LogData} baseLogData - * The base log data to add. - * @returns {Logger} - * Returns a new child logger. */ createChildLogger(baseLogData) { return new Logger({ @@ -284,12 +216,6 @@ class Logger { /** * Add additional log data to all subsequent log calls. - * - * @deprecated Please create a child logger with `createChildLogger` or use the `baseLogData` option. - * @public - * @param {LogData} extraLogData - * The additional data to add to all logs from this logger. - * @returns {void} */ addContext(extraLogData) { this.#baseLogData = Object.assign({}, this.#baseLogData, extraLogData); @@ -305,12 +231,6 @@ class Logger { /** * Set the `context` property for all subsequent log calls. - * - * @deprecated Please create a child logger with `createChildLogger` or use the `baseLogData` option. - * @public - * @param {LogData} contextData - * The additional data to add to all log `context` properties. - * @returns {void} */ setContext(contextData) { this.#baseLogData.context = contextData; @@ -326,10 +246,6 @@ class Logger { /** * Clear the `context` property for all subsequent log calls. - * - * @deprecated Please create a child logger with `createChildLogger` or use the `baseLogData` option. - * @public - * @returns {void} */ clearContext() { delete this.#baseLogData.context; @@ -345,13 +261,6 @@ class Logger { /** * Send a log. - * - * @public - * @param {LogLevel} level - * The log level to output the log as. - * @param {...LogData} logData - * The log data. - * @returns {void} */ log(level, ...logData) { if (typeof level !== 'string') { @@ -414,12 +323,6 @@ class Logger { /** * Send a log with a level of "data". - * - * @deprecated Please use a log level of "debug" instead. - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ data(...logData) { this.log('data', ...logData); @@ -427,11 +330,6 @@ class Logger { /** * Send a log with a level of "debug". - * - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ debug(...logData) { this.log('debug', ...logData); @@ -439,11 +337,6 @@ class Logger { /** * Send a log with a level of "error". - * - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ error(...logData) { this.log('error', ...logData); @@ -451,11 +344,6 @@ class Logger { /** * Send a log with a level of "fatal". - * - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ fatal(...logData) { this.log('fatal', ...logData); @@ -463,11 +351,6 @@ class Logger { /** * Send a log with a level of "info". - * - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ info(...logData) { this.log('info', ...logData); @@ -475,12 +358,6 @@ class Logger { /** * Send a log with a level of "silly". - * - * @deprecated Please use a log level of "debug" instead. - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ silly(...logData) { this.log('silly', ...logData); @@ -488,12 +365,6 @@ class Logger { /** * Send a log with a level of "verbose". - * - * @deprecated Please use a log level of "debug" instead. - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ verbose(...logData) { this.log('verbose', ...logData); @@ -501,11 +372,6 @@ class Logger { /** * Send a log with a level of "warn". - * - * @public - * @param {...LogData} logData - * The log data. - * @returns {void} */ warn(...logData) { this.log('warn', ...logData); @@ -513,9 +379,6 @@ class Logger { /** * Flush any asynchronous logs in the queue when an async transport is used. - * - * @public - * @returns {void} */ flush() { if (this.transport.flush) { @@ -545,7 +408,7 @@ class Logger { * @private * @param {...LogData} logData * The log data. - * @returns {{[key: string]: any}} + * @returns {BaseLogData} * Returns a single zipped object containing all log data. */ static zipLogData(...logData) { @@ -554,20 +417,23 @@ class Logger { // rather than the last const reversedLogData = logData.reverse(); return clone( - reversedLogData.reduce((collect, item) => { - if (typeof item === 'string') { - return Object.assign(collect, { message: item }); - } - if (item instanceof Error) { - return Object.assign(collect, { error: serializeError(item) }); - } - return Object.assign(collect, item); - }, {}) + reversedLogData.reduce( + /** + * @param {BaseLogData} collect + * @param {LogData} item + * @returns {BaseLogData} + */ + (collect, item) => { + if (typeof item === 'string') { + return Object.assign(collect, { message: item }); + } + if (item instanceof Error) { + return Object.assign(collect, { error: serializeError(item) }); + } + return Object.assign(collect, item); + }, + {} + ) ); } -} - -module.exports = Logger; - -// @ts-ignore -module.exports.default = module.exports; +}; diff --git a/packages/logger/lib/transforms/legacy-mask.js b/packages/logger/lib/transforms/legacy-mask.js index 6ef42f96..1b8895dd 100644 --- a/packages/logger/lib/transforms/legacy-mask.js +++ b/packages/logger/lib/transforms/legacy-mask.js @@ -1,23 +1,5 @@ /** - * @typedef {object} LegacyMaskTransformOptions - * @property {string[]} [denyList] - * Additional field names to apply masking to. - * @property {string[]} [allowList] - * Field names to allow from the default deny list. - * @property {string} [maskString] - * The mask string to apply to discovered sensitive values. - */ - -/** - * @typedef {object} InternalMaskSettings - * @property {Set} maskedFields - * Field names to mask. - * @property {RegExp} maskRegExp - * A regular expression which applies masking to a string. - * @property {string} maskString - * The mask string to apply to discovered sensitive values. - * @property {WeakSet} references - * An internal store of references used to avoid masking the same object infinitely. + * @typedef {import('../../types/transforms/legacy-mask').InternalMaskSettings} InternalMaskSettings */ /** @@ -160,12 +142,9 @@ function maskObject(object, settings) { /** * Create a log transform function which masks sensitive fields in log data. * - * @param {LegacyMaskTransformOptions} options - * Masking options. - * @returns {import('../logger').LogTransform} - * Returns a transform function for use with the logger. + * @type {import('../../types/transforms/legacy-mask').createLegacyMaskTransform} */ -function createLegacyMaskTransform({ +module.exports = function createLegacyMaskTransform({ denyList = [], allowList = [], maskString = '*****' @@ -192,9 +171,4 @@ function createLegacyMaskTransform({ references: new WeakSet() }); }; -} - -module.exports = createLegacyMaskTransform; - -// @ts-ignore -module.exports.default = module.exports; +}; diff --git a/packages/logger/package.json b/packages/logger/package.json index 018c5000..dacca974 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -14,7 +14,8 @@ "node": "18.x || 20.x || 22.x", "npm": "8.x || 9.x || 10.x" }, - "main": "lib", + "main": "lib/index.js", + "types": "types/index.d.ts", "dependencies": { "@dotcom-reliability-kit/app-info": "^3.2.0", "@dotcom-reliability-kit/serialize-error": "^3.2.0", diff --git a/packages/logger/test/unit/lib/logger.spec.js b/packages/logger/test/unit/lib/logger.spec.js index 11547f65..c820548c 100644 --- a/packages/logger/test/unit/lib/logger.spec.js +++ b/packages/logger/test/unit/lib/logger.spec.js @@ -1127,10 +1127,4 @@ describe('@dotcom-reliability-kit/logger/lib/logger', () => { }); }); }); - - describe('.default', () => { - it('aliases the module exports', () => { - expect(Logger.default).toStrictEqual(Logger); - }); - }); }); diff --git a/packages/logger/test/unit/lib/transforms/legacy-mask.spec.js b/packages/logger/test/unit/lib/transforms/legacy-mask.spec.js index 3781a581..41b6b830 100644 --- a/packages/logger/test/unit/lib/transforms/legacy-mask.spec.js +++ b/packages/logger/test/unit/lib/transforms/legacy-mask.spec.js @@ -5,14 +5,6 @@ describe('@dotcom-reliability-kit/logger', () => { expect(createLegacyMaskTransform).toBeInstanceOf(Function); }); - describe('.default', () => { - it('aliases the module exports', () => { - expect(createLegacyMaskTransform.default).toStrictEqual( - createLegacyMaskTransform - ); - }); - }); - describe('createLegacyMaskTransform(options)', () => { let transform; diff --git a/packages/logger/types/index.d.ts b/packages/logger/types/index.d.ts new file mode 100644 index 00000000..95d7f617 --- /dev/null +++ b/packages/logger/types/index.d.ts @@ -0,0 +1,20 @@ +import { Logger } from './logger'; +import { createLegacyMaskTransform } from './transforms/legacy-mask'; + +declare module '@dotcom-reliability-kit/logger' { + export type Transforms = { + legacyMask: typeof createLegacyMaskTransform; + }; + + export type DefaultLogger = { + Logger: typeof Logger; + transforms: Transforms; + }; + + export const transforms: Transforms; + export { Logger }; + + declare const _exports: Logger & DefaultLogger; + export = _exports; + export default _exports; +} diff --git a/packages/logger/types/logger.d.ts b/packages/logger/types/logger.d.ts new file mode 100644 index 00000000..753379d9 --- /dev/null +++ b/packages/logger/types/logger.d.ts @@ -0,0 +1,77 @@ +export type LogLevel = + | 'silly' + | 'data' + | 'debug' + | 'verbose' + | 'info' + | 'warn' + | 'error' + | 'fatal'; + +export type LogLevelInfo = { + logLevel: LogLevel; + isDeprecated: boolean; +}; + +export type BaseLogData = { [key: string]: any }; +export type LogData = string | BaseLogData | Error; + +export type LogTransform = (logData: { [key: string]: any }) => { + [key: string]: any; +}; + +export type LogTransport = { + level?: string; + debug: (...args: any) => any; + error: (...args: any) => any; + fatal: (...args: any) => any; + info: (...args: any) => any; + warn: (...args: any) => any; + flush?: () => void; +}; + +export type LoggerOptions = { + baseLogData?: object; + logLevel?: LogLevel; + transforms?: LogTransform[]; + withPrettifier?: boolean; +}; + +export type PrivateLoggerOptions = { + _transport?: LogTransport; +}; + +export class Logger { + constructor(options?: LoggerOptions); + public get baseLogData(): any; + public get logLevel(): LogLevel; + public get transport(): LogTransport; + public createChildLogger(baseLogData: LogData): Logger; + public log(level: LogLevel, ...logData: LogData[]): void; + public debug(...logData: LogData[]): void; + public error(...logData: LogData[]): void; + public fatal(...logData: LogData[]): void; + public info(...logData: LogData[]): void; + public warn(...logData: LogData[]): void; + public flush(): void; + + /** @deprecated Please create a child logger with `createChildLogger` or use the `baseLogData` option. */ + public addContext(extraLogData: LogData): void; + + /** @deprecated Please create a child logger with `createChildLogger` or use the `baseLogData` option. */ + public setContext(contextData: LogData): void; + + /** @deprecated Please create a child logger with `createChildLogger` or use the `baseLogData` option. */ + public clearContext(): void; + + /** @deprecated Please use a log level of "debug" instead. */ + public data(...logData: LogData[]): void; + + /** @deprecated Please use a log level of "debug" instead. */ + public silly(...logData: LogData[]): void; + + /** @deprecated Please use a log level of "debug" instead. */ + public verbose(...logData: LogData[]): void; +} + +export interface LoggerInterface extends Logger {} diff --git a/packages/logger/types/transforms/legacy-mask.d.ts b/packages/logger/types/transforms/legacy-mask.d.ts new file mode 100644 index 00000000..4c5d4402 --- /dev/null +++ b/packages/logger/types/transforms/legacy-mask.d.ts @@ -0,0 +1,18 @@ +import { LogTransform } from '../logger'; + +export type LegacyMaskTransformOptions = { + denyList?: string[]; + allowList?: string[]; + maskString?: string; +}; + +export type InternalMaskSettings = { + maskedFields: Set; + maskRegExp: RegExp; + maskString: string; + references: WeakSet; +}; + +export type createLegacyMaskTransform = ( + options?: LegacyMaskTransformOptions +) => LogTransform; diff --git a/scripts/clean-generated-types.sh b/scripts/clean-generated-types.sh deleted file mode 100755 index 65521e98..00000000 --- a/scripts/clean-generated-types.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -find ./packages/logger -name "*.d.ts*" | xargs -r rm From 2d297bd699fb73a57fdb6d52a00f6b5043337430 Mon Sep 17 00:00:00 2001 From: Rowan Manning <138944+rowanmanning@users.noreply.github.com> Date: Mon, 1 Jul 2024 07:21:41 +0100 Subject: [PATCH 2/2] chore: migrate to TypeScript 5.5 Now that we've got manual type declarations we can _finally_ safely migrate to TypeScript 5.5. Phew. --- package-lock.json | 134 +++++++++++------- package.json | 4 +- packages/app-info/lib/index.js | 6 +- packages/crash-handler/lib/index.js | 6 +- packages/errors/lib/base-error.js | 14 +- packages/errors/lib/data-store-error.js | 6 +- packages/errors/lib/http-error.js | 16 +-- packages/errors/lib/operational-error.js | 8 +- packages/errors/lib/upstream-service-error.js | 6 +- packages/errors/lib/user-input-error.js | 6 +- packages/log-error/lib/index.js | 2 +- packages/logger/lib/index.js | 3 +- packages/logger/lib/logger.js | 21 +-- packages/logger/lib/transforms/legacy-mask.js | 5 +- packages/middleware-log-errors/lib/index.js | 9 +- .../test/end-to-end/fixtures/app.js | 1 - .../middleware-render-error-info/lib/index.js | 9 +- .../lib/render-error-page.js | 17 ++- .../lib/render-layout.js | 6 +- .../lib/config/instrumentations.js | 9 +- packages/opentelemetry/lib/config/metrics.js | 11 +- packages/opentelemetry/lib/config/resource.js | 2 +- packages/opentelemetry/lib/config/tracing.js | 11 +- packages/opentelemetry/lib/index.js | 6 +- packages/serialize-error/lib/index.js | 10 +- packages/serialize-request/lib/index.js | 22 ++- resources/logos/scripts/build.js | 1 - scripts/create-package.js | 2 - 28 files changed, 222 insertions(+), 131 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4b348cf..62a6a775 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,14 +23,14 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.7", "eslint": "^8.57.0", - "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-jsdoc": "^48.5.0", "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "jest": "^29.7.0", "lint-staged": "^15.2.2", "prettier": "^3.2.5", "release-please": "^16.10.1", - "typescript": "^5.3.3" + "typescript": "^5.5.2" }, "engines": { "node": "18.x || 20.x || 22.x", @@ -1615,11 +1615,14 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", - "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" @@ -4995,9 +4998,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/events": { @@ -5281,6 +5284,19 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -5830,18 +5846,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -6898,6 +6902,12 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -7011,20 +7021,21 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz", - "integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==", + "version": "48.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.0.tgz", + "integrity": "sha512-ukXPNpGby3KjCveCizIS8t1EbuJEHYEu/tBg8GCbn/YbHcXwphyvYCdvRZ/oMRfTscGSSzfsWoZ+ZkAP0/6YMQ==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.42.0", + "@es-joy/jsdoccomment": "~0.43.1", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", - "is-builtin-module": "^3.2.1", - "semver": "^7.6.0", - "spdx-expression-parse": "^4.0.0" + "parse-imports": "^2.1.0", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.0" }, "engines": { "node": ">=18" @@ -7055,6 +7066,22 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/synckit": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.0.tgz", + "integrity": "sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/eslint-plugin-no-only-tests": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-2.6.0.tgz", @@ -8300,21 +8327,6 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -9865,6 +9877,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -10444,6 +10457,19 @@ "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", "dev": true }, + "node_modules/parse-imports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.0.tgz", + "integrity": "sha512-JQWgmK2o4w8leUkZeZPatWdAny6vXGU/3siIUvMF6J2rDCud9aTt8h/px9oZJ6U3EcfhngBJ635uPFI0q0VAeA==", + "dev": true, + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -11598,12 +11624,9 @@ "peer": true }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -11809,6 +11832,12 @@ "node": ">=8" } }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, "node_modules/slice-ansi": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", @@ -12581,9 +12610,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -13016,7 +13045,8 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yaml": { "version": "2.3.4", diff --git a/package.json b/package.json index 715f4b2c..7c0187be 100644 --- a/package.json +++ b/package.json @@ -36,14 +36,14 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.7", "eslint": "^8.57.0", - "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-jsdoc": "^48.5.0", "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "jest": "^29.7.0", "lint-staged": "^15.2.2", "prettier": "^3.2.5", "release-please": "^16.10.1", - "typescript": "^5.3.3" + "typescript": "^5.5.2" }, "engines": { "node": "18.x || 20.x || 22.x", diff --git a/packages/app-info/lib/index.js b/packages/app-info/lib/index.js index 732b193f..139dbe1c 100644 --- a/packages/app-info/lib/index.js +++ b/packages/app-info/lib/index.js @@ -1,6 +1,10 @@ const path = require('node:path'); const { randomUUID } = require('node:crypto'); +/** + * @import { SemanticConventions } from '@dotcom-reliability-kit/app-info' + */ + // This package relies on Heroku and AWS Lambda environment variables. // Documentation for these variables is available here: // @@ -159,7 +163,7 @@ exports.herokuDynoId = process.env.HEROKU_DYNO_ID || null; exports.instanceId = randomUUID(); /** - * @type {import('@dotcom-reliability-kit/app-info').SemanticConventions} + * @type {SemanticConventions} */ exports.semanticConventions = { cloud: { diff --git a/packages/crash-handler/lib/index.js b/packages/crash-handler/lib/index.js index 88732b92..2fcc12ed 100644 --- a/packages/crash-handler/lib/index.js +++ b/packages/crash-handler/lib/index.js @@ -3,10 +3,14 @@ const { logUnhandledError } = require('@dotcom-reliability-kit/log-error'); +/** + * @import { CrashHandlerOptions } from '@dotcom-reliability-kit/crash-handler' + */ + /** * Register a crash handler on a process. * - * @param {import('@dotcom-reliability-kit/crash-handler').CrashHandlerOptions} [options] + * @param {CrashHandlerOptions} [options] */ function registerCrashHandler(options = {}) { const process = options.process || global.process; diff --git a/packages/errors/lib/base-error.js b/packages/errors/lib/base-error.js index 09cb070f..5c4d8e41 100644 --- a/packages/errors/lib/base-error.js +++ b/packages/errors/lib/base-error.js @@ -1,5 +1,5 @@ /** - * @typedef {import('@dotcom-reliability-kit/errors').BaseErrorData} ErrorData + * @import { BaseError as BaseErrorType, BaseErrorData as ErrorData } from '@dotcom-reliability-kit/errors' */ /** @@ -9,7 +9,7 @@ class BaseError extends Error { /** * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').BaseError['name']} + * @type {BaseErrorType['name']} */ name = 'BaseError'; @@ -17,7 +17,7 @@ class BaseError extends Error { * Whether the error is operational. * * @readonly - * @type {import('@dotcom-reliability-kit/errors').BaseError['isOperational']} + * @type {BaseErrorType['isOperational']} */ isOperational = false; @@ -25,7 +25,7 @@ class BaseError extends Error { * A machine-readable error code which identifies the specific type of error. * * @readonly - * @type {import('@dotcom-reliability-kit/errors').BaseError['code']} + * @type {BaseErrorType['code']} */ code = BaseError.defaultCode; @@ -33,7 +33,7 @@ class BaseError extends Error { * The root cause error instance. * * @readonly - * @type {import('@dotcom-reliability-kit/errors').BaseError['cause']} + * @type {BaseErrorType['cause']} */ cause = null; @@ -41,7 +41,7 @@ class BaseError extends Error { * Additional error information. * * @readonly - * @type {import('@dotcom-reliability-kit/errors').BaseError['data']} + * @type {BaseErrorType['data']} */ data = {}; @@ -119,7 +119,7 @@ class BaseError extends Error { static defaultMessage = 'An error occurred'; /** - * @type {(typeof import('@dotcom-reliability-kit/errors').BaseError)['isErrorMarkedAsOperational']} + * @type {(typeof BaseErrorType)['isErrorMarkedAsOperational']} */ static isErrorMarkedAsOperational(error) { // @ts-ignore Error.prototype.isOperational does not exist, but it's OK to check in this diff --git a/packages/errors/lib/data-store-error.js b/packages/errors/lib/data-store-error.js index a208c365..67e0ea0c 100644 --- a/packages/errors/lib/data-store-error.js +++ b/packages/errors/lib/data-store-error.js @@ -1,5 +1,9 @@ const OperationalError = require('./operational-error'); +/** + * @import { DataStoreError as DataStoreErrorType } from '@dotcom-reliability-kit/errors' + */ + /** * Class representing an error in an application's data store. */ @@ -7,7 +11,7 @@ class DataStoreError extends OperationalError { /** * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').DataStoreError['name']} + * @type {DataStoreErrorType['name']} */ name = 'DataStoreError'; } diff --git a/packages/errors/lib/http-error.js b/packages/errors/lib/http-error.js index c9a6c442..ee27f407 100644 --- a/packages/errors/lib/http-error.js +++ b/packages/errors/lib/http-error.js @@ -1,5 +1,9 @@ const OperationalError = require('./operational-error'); +/** + * @import { HttpError as HttpErrorType, HttpErrorData as ErrorData } from '@dotcom-reliability-kit/errors' + */ + /** * We have guards in place wherever we use this map of status messages * which means we can safely cast it to an object where every property @@ -10,10 +14,6 @@ const OperationalError = require('./operational-error'); */ const STATUS_CODES = require('http').STATUS_CODES; -/** - * @typedef {import('@dotcom-reliability-kit/errors').HttpErrorData} ErrorData - */ - /** * Class representing an HTTP error. */ @@ -21,24 +21,24 @@ class HttpError extends OperationalError { /** * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').HttpError['name']} + * @type {HttpErrorType['name']} */ name = 'HttpError'; /** * @readonly - * @type {import('@dotcom-reliability-kit/errors').HttpError['statusCode']} + * @type {HttpErrorType['statusCode']} */ statusCode; /** * @readonly - * @type {import('@dotcom-reliability-kit/errors').HttpError['statusMessage']} + * @type {HttpErrorType['statusMessage']} */ statusMessage; /** - * @type {import('@dotcom-reliability-kit/errors').HttpError['status']} + * @type {HttpErrorType['status']} */ get status() { return this.statusCode; diff --git a/packages/errors/lib/operational-error.js b/packages/errors/lib/operational-error.js index cfd911c7..f219bf81 100644 --- a/packages/errors/lib/operational-error.js +++ b/packages/errors/lib/operational-error.js @@ -1,7 +1,7 @@ const BaseError = require('./base-error'); /** - * @typedef {import('@dotcom-reliability-kit/errors').OperationalErrorData} ErrorData + * @import { OperationalError as OperationalErrorType, OperationalErrorData as ErrorData } from '@dotcom-reliability-kit/errors' */ /** @@ -11,7 +11,7 @@ class OperationalError extends BaseError { /** * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').OperationalError['name']} + * @type {OperationalErrorType['name']} */ name = 'OperationalError'; @@ -20,7 +20,7 @@ class OperationalError extends BaseError { * * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').OperationalError['isOperational']} + * @type {OperationalErrorType['isOperational']} */ isOperational = true; @@ -29,7 +29,7 @@ class OperationalError extends BaseError { * If this error is caused by one or more dependencies, include their system code here. * * @readonly - * @type {import('@dotcom-reliability-kit/errors').OperationalError['relatesToSystems']} + * @type {OperationalErrorType['relatesToSystems']} */ relatesToSystems = []; diff --git a/packages/errors/lib/upstream-service-error.js b/packages/errors/lib/upstream-service-error.js index cbbd540a..8da5eaea 100644 --- a/packages/errors/lib/upstream-service-error.js +++ b/packages/errors/lib/upstream-service-error.js @@ -1,5 +1,9 @@ const HttpError = require('./http-error'); +/** + * @import { UpstreamServiceError as UpstreamServiceErrorType } from '@dotcom-reliability-kit/errors' + */ + /** * Class representing an error in an upstream service. */ @@ -7,7 +11,7 @@ class UpstreamServiceError extends HttpError { /** * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').UpstreamServiceError['name']} + * @type {UpstreamServiceErrorType['name']} */ name = 'UpstreamServiceError'; diff --git a/packages/errors/lib/user-input-error.js b/packages/errors/lib/user-input-error.js index 8753aeb7..88e39fb7 100644 --- a/packages/errors/lib/user-input-error.js +++ b/packages/errors/lib/user-input-error.js @@ -1,5 +1,9 @@ const HttpError = require('./http-error'); +/** + * @import { UserInputError as UserInputErrorType } from '@dotcom-reliability-kit/errors' + */ + /** * Class representing an error caused by invalid user input. */ @@ -7,7 +11,7 @@ class UserInputError extends HttpError { /** * @override * @readonly - * @type {import('@dotcom-reliability-kit/errors').UserInputError['name']} + * @type {UserInputErrorType['name']} */ name = 'UserInputError'; diff --git a/packages/log-error/lib/index.js b/packages/log-error/lib/index.js index 9e64be09..f69535bd 100644 --- a/packages/log-error/lib/index.js +++ b/packages/log-error/lib/index.js @@ -4,7 +4,7 @@ const serializeError = require('@dotcom-reliability-kit/serialize-error'); const serializeRequest = require('@dotcom-reliability-kit/serialize-request'); /** - * @typedef {import('@dotcom-reliability-kit/log-error').ErrorLoggingOptions} ErrorLoggingOptions + * @import { ErrorLoggingOptions } from '@dotcom-reliability-kit/log-error' */ /** diff --git a/packages/logger/lib/index.js b/packages/logger/lib/index.js index c7f15c72..9234d353 100644 --- a/packages/logger/lib/index.js +++ b/packages/logger/lib/index.js @@ -2,8 +2,7 @@ const Logger = require('./logger'); const legacyMask = require('./transforms/legacy-mask'); /** - * @typedef {import('@dotcom-reliability-kit/logger').DefaultLogger} DefaultLogger - * @typedef {import('@dotcom-reliability-kit/logger').Transforms} Transforms + * @import { DefaultLogger, Transforms } from '@dotcom-reliability-kit/logger' */ /** @type {Transforms} */ diff --git a/packages/logger/lib/logger.js b/packages/logger/lib/logger.js index 82c639e1..0d795ef7 100644 --- a/packages/logger/lib/logger.js +++ b/packages/logger/lib/logger.js @@ -4,16 +4,17 @@ const clone = require('lodash.clonedeep'); const appInfo = require('@dotcom-reliability-kit/app-info'); /** - * @typedef {import('../types/logger').BaseLogData} BaseLogData - * @typedef {import('../types/logger').LogData} LogData - * @typedef {import('../types/logger').LoggerInterface} LoggerInterface - * @typedef {import('../types/logger').LoggerOptions} LoggerOptions - * @typedef {import('../types/logger').LogLevel} LogLevel - * @typedef {import('../types/logger').LogLevelInfo} LogLevelInfo - * @typedef {import('../types/logger').LogTransform} LogTransform - * @typedef {import('../types/logger').LogTransport} LogTransport - * @typedef {import('../types/logger').PrivateLoggerOptions} PrivateLoggerOptions - * @typedef {typeof import('pino').stdTimeFunctions.isoTime} TimeFn + * @import { + * BaseLogData, + * LogData, + * LoggerInterface, + * LoggerOptions, + * LogLevel, + * LogLevelInfo, + * LogTransform, + * LogTransport, + * PrivateLoggerOptions + * } from '../types/logger'; */ /** diff --git a/packages/logger/lib/transforms/legacy-mask.js b/packages/logger/lib/transforms/legacy-mask.js index 1b8895dd..d56b586e 100644 --- a/packages/logger/lib/transforms/legacy-mask.js +++ b/packages/logger/lib/transforms/legacy-mask.js @@ -1,5 +1,6 @@ /** - * @typedef {import('../../types/transforms/legacy-mask').InternalMaskSettings} InternalMaskSettings + * @import { InternalMaskSettings } from '../../types/transforms/legacy-mask' + * @import { createLegacyMaskTransform as CreateLegacyMaskTransform } from '../../types/transforms/legacy-mask' */ /** @@ -142,7 +143,7 @@ function maskObject(object, settings) { /** * Create a log transform function which masks sensitive fields in log data. * - * @type {import('../../types/transforms/legacy-mask').createLegacyMaskTransform} + * @type {CreateLegacyMaskTransform} */ module.exports = function createLegacyMaskTransform({ denyList = [], diff --git a/packages/middleware-log-errors/lib/index.js b/packages/middleware-log-errors/lib/index.js index fa5051f3..7f65c4b4 100644 --- a/packages/middleware-log-errors/lib/index.js +++ b/packages/middleware-log-errors/lib/index.js @@ -3,11 +3,16 @@ const { logRecoverableError } = require('@dotcom-reliability-kit/log-error'); +/** + * @import { ErrorLoggingOptions } from '@dotcom-reliability-kit/middleware-log-errors' + * @import { ErrorRequestHandler as ExpressErrorHandler } from 'express' + */ + /** * Create a middleware function to log errors. * - * @param {import('@dotcom-reliability-kit/middleware-log-errors').ErrorLoggingOptions} [options] - * @returns {import('express').ErrorRequestHandler} + * @param {ErrorLoggingOptions} [options] + * @returns {ExpressErrorHandler} */ function createErrorLoggingMiddleware(options = {}) { // Validate the included headers (this stops the request serializer from erroring diff --git a/packages/middleware-log-errors/test/end-to-end/fixtures/app.js b/packages/middleware-log-errors/test/end-to-end/fixtures/app.js index d8d32d66..e9d6b588 100644 --- a/packages/middleware-log-errors/test/end-to-end/fixtures/app.js +++ b/packages/middleware-log-errors/test/end-to-end/fixtures/app.js @@ -45,7 +45,6 @@ app.listen(undefined).then((server) => { if (process.send) { process.send({ ready: true, - // @ts-ignore port: server.address().port }); } diff --git a/packages/middleware-render-error-info/lib/index.js b/packages/middleware-render-error-info/lib/index.js index cae918dd..412c4415 100644 --- a/packages/middleware-render-error-info/lib/index.js +++ b/packages/middleware-render-error-info/lib/index.js @@ -4,11 +4,16 @@ const renderErrorPage = require('./render-error-page'); const serializeError = require('@dotcom-reliability-kit/serialize-error'); const { STATUS_CODES } = require('node:http'); +/** + * @import { ErrorRenderingOptions } from '@dotcom-reliability-kit/middleware-render-error-info' + * @import { ErrorRequestHandler as ExpressErrorHandler } from 'express' + */ + /** * Create a middleware function to render an error info page. * - * @param {import('@dotcom-reliability-kit/middleware-render-error-info').ErrorRenderingOptions} [options] - * @returns {import('express').ErrorRequestHandler} + * @param {ErrorRenderingOptions} [options] + * @returns {ExpressErrorHandler} */ function createErrorRenderingMiddleware(options = {}) { return function errorRenderingMiddleware(error, request, response, next) { diff --git a/packages/middleware-render-error-info/lib/render-error-page.js b/packages/middleware-render-error-info/lib/render-error-page.js index 7c59c48f..e784901f 100644 --- a/packages/middleware-render-error-info/lib/render-error-page.js +++ b/packages/middleware-render-error-info/lib/render-error-page.js @@ -2,6 +2,11 @@ const appInfo = require('@dotcom-reliability-kit/app-info'); const entities = require('entities'); const renderLayout = require('./render-layout'); +/** + * @import { Request as ExpressRequest, Response as ExpressResponse } from 'express' + * @import { SerializedError } from '@dotcom-reliability-kit/serialize-error' + */ + const X_API_KEY_REQUEST_PROPERTY_NAME = 'x-api-key'; const COOKIE_REQUEST_PROPERTY_NAME = 'cookie'; @@ -15,11 +20,11 @@ const CONCEALED_VALUE_MESSAGE = /** * @typedef {object} ErrorRenderingOptions - * @property {import('express').Request} request + * @property {ExpressRequest} request * An Express request object. - * @property {import('express').Response} response + * @property {ExpressResponse} response * An Express response object. - * @property {import('@dotcom-reliability-kit/serialize-error').SerializedError} serializedError + * @property {SerializedError} serializedError * The error to render. */ @@ -51,7 +56,7 @@ function renderErrorPage({ request, response, serializedError }) { * Render a serialized error to HTML. * * @private - * @param {import('@dotcom-reliability-kit/serialize-error').SerializedError} error + * @param {SerializedError} error * The error information to render. * @returns {string} * Returns the rendered error. @@ -152,7 +157,7 @@ function renderError(error) { * Render an HTTP request to HTML. * * @private - * @param {import('express').Request} request + * @param {ExpressRequest} request * The request information to render. * @returns {string} * Returns the rendered request. @@ -198,7 +203,7 @@ function renderRequest(request) { * Render an HTTP response to HTML. * * @private - * @param {import('express').Response} response + * @param {ExpressResponse} response * The responses information to render. * @returns {string} * Returns the rendered response. diff --git a/packages/middleware-render-error-info/lib/render-layout.js b/packages/middleware-render-error-info/lib/render-layout.js index 26a152da..d1d90dc0 100644 --- a/packages/middleware-render-error-info/lib/render-layout.js +++ b/packages/middleware-render-error-info/lib/render-layout.js @@ -1,6 +1,10 @@ const appInfo = require('@dotcom-reliability-kit/app-info'); const fs = require('node:fs'); +/** + * @import { Request as ExpressRequest } from 'express' + */ + const buildServiceBaseUrl = 'https://www.ft.com/__origami/service/build/v3'; const buildServiceComponents = [ 'o-autoinit@^3.1.3', @@ -21,7 +25,7 @@ const styles = fs.readFileSync(`${__dirname}/render-error-page.css`, 'utf-8'); * @typedef {object} LayoutRenderingOptions * @property {string} body * The main body of the page. - * @property {import('express').Request} request + * @property {ExpressRequest} request * An Express request object. * @property {string} title * The page title. diff --git a/packages/opentelemetry/lib/config/instrumentations.js b/packages/opentelemetry/lib/config/instrumentations.js index e33c4237..1840bf7a 100644 --- a/packages/opentelemetry/lib/config/instrumentations.js +++ b/packages/opentelemetry/lib/config/instrumentations.js @@ -7,13 +7,18 @@ const { const { logRecoverableError } = require('@dotcom-reliability-kit/log-error'); const { UserInputError } = require('@dotcom-reliability-kit/errors'); +/** + * @import { NodeSDKConfiguration } from '@opentelemetry/sdk-node' + * @import { IgnoreIncomingRequestFunction } from '@opentelemetry/instrumentation-http' + */ + // Request paths that we ignore when instrumenting HTTP requests const IGNORED_REQUEST_PATHS = ['/__gtg', '/__health', '/favicon.ico']; /** * Create an instrumentations array for configuring OpenTelemetry. * - * @returns {import('@opentelemetry/sdk-node').NodeSDKConfiguration['instrumentations']} + * @returns {NodeSDKConfiguration['instrumentations']} */ exports.createInstrumentationConfig = function createInstrumentationConfig() { return [ @@ -34,7 +39,7 @@ exports.createInstrumentationConfig = function createInstrumentationConfig() { * if the hook returns `true` then the request WILL be ignored. * * @see https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-http/README.md#http-instrumentation-options - * @type {import('@opentelemetry/instrumentation-http').IgnoreIncomingRequestFunction} + * @type {IgnoreIncomingRequestFunction} */ function ignoreIncomingRequestHook(request) { if (request.url) { diff --git a/packages/opentelemetry/lib/config/metrics.js b/packages/opentelemetry/lib/config/metrics.js index 28463134..2fc59793 100644 --- a/packages/opentelemetry/lib/config/metrics.js +++ b/packages/opentelemetry/lib/config/metrics.js @@ -8,14 +8,19 @@ const { PeriodicExportingMetricReader } = const logger = require('@dotcom-reliability-kit/logger'); const { METRICS_USER_AGENT } = require('./user-agents'); +/** + * @import { NodeSDKConfiguration } from '@opentelemetry/sdk-node' + * @import { MetricsOptions } from '@dotcom-reliability-kit/opentelemetry' + */ + /** * Create an OpenTelemetry metrics configuration. * - * @param {import('@dotcom-reliability-kit/opentelemetry').MetricsOptions} options - * @returns {Partial} + * @param {MetricsOptions} options + * @returns {Partial} */ exports.createMetricsConfig = function createMetricsConfig(options) { - /** @type {Partial} */ + /** @type {Partial} */ const config = {}; // If we have an OpenTelemetry metrics endpoint then set it up diff --git a/packages/opentelemetry/lib/config/resource.js b/packages/opentelemetry/lib/config/resource.js index e6305b6f..2d1aeeff 100644 --- a/packages/opentelemetry/lib/config/resource.js +++ b/packages/opentelemetry/lib/config/resource.js @@ -12,7 +12,7 @@ const { /** * Create a Resource object using gathered app info. * - * @returns {import('@opentelemetry/sdk-node').resources.Resource} + * @returns {Resource} */ exports.createResourceConfig = function createResourceConfig() { // We set OpenTelemetry resource attributes based on app data diff --git a/packages/opentelemetry/lib/config/tracing.js b/packages/opentelemetry/lib/config/tracing.js index 71ed553c..edd3978e 100644 --- a/packages/opentelemetry/lib/config/tracing.js +++ b/packages/opentelemetry/lib/config/tracing.js @@ -7,16 +7,21 @@ const { NoopSpanProcessor, TraceIdRatioBasedSampler } = const logger = require('@dotcom-reliability-kit/logger'); const { TRACING_USER_AGENT } = require('./user-agents'); +/** + * @import { NodeSDKConfiguration } from '@opentelemetry/sdk-node' + * @import { TracingOptions } from '@dotcom-reliability-kit/opentelemetry' + */ + const DEFAULT_SAMPLE_PERCENTAGE = 5; /** * Create an OpenTelemetry tracing configuration. * - * @param {import('@dotcom-reliability-kit/opentelemetry').TracingOptions} options - * @returns {Partial} + * @param {TracingOptions} options + * @returns {Partial} */ exports.createTracingConfig = function createTracingConfig(options) { - /** @type {Partial} */ + /** @type {Partial} */ const config = {}; // If we have an OpenTelemetry tracing endpoint then set it up, diff --git a/packages/opentelemetry/lib/index.js b/packages/opentelemetry/lib/index.js index 07d4dc62..f4c81dbc 100644 --- a/packages/opentelemetry/lib/index.js +++ b/packages/opentelemetry/lib/index.js @@ -7,11 +7,7 @@ const opentelemetry = require('@opentelemetry/sdk-node'); const logger = require('@dotcom-reliability-kit/logger'); /** - * @typedef {import('@dotcom-reliability-kit/opentelemetry').Options} Options - */ - -/** - * @typedef {import('@dotcom-reliability-kit/opentelemetry').Instances} Instances + * @import { Instances, Options } from '@dotcom-reliability-kit/opentelemetry' */ /** diff --git a/packages/serialize-error/lib/index.js b/packages/serialize-error/lib/index.js index 2d09cb20..87a4f63c 100644 --- a/packages/serialize-error/lib/index.js +++ b/packages/serialize-error/lib/index.js @@ -1,10 +1,14 @@ const crypto = require('node:crypto'); +/** + * @import { ErrorLike, SerializedError } from '@dotcom-reliability-kit/serialize-error' + */ + /** * Serialize an error object so that it can be consistently logged or output as JSON. * - * @param {import('@dotcom-reliability-kit/serialize-error').ErrorLike} error - * @returns {import('@dotcom-reliability-kit/serialize-error').SerializedError} + * @param {ErrorLike} error + * @returns {SerializedError} */ function serializeError(error) { if (typeof error !== 'object' || Array.isArray(error) || error === null) { @@ -84,7 +88,7 @@ function serializeError(error) { * Create a new serialized error object. * * @param {Record} properties - * @returns {import('@dotcom-reliability-kit/serialize-error').SerializedError} + * @returns {SerializedError} */ function createSerializedError(properties) { return Object.assign( diff --git a/packages/serialize-request/lib/index.js b/packages/serialize-request/lib/index.js index e5db4c59..41618be1 100644 --- a/packages/serialize-request/lib/index.js +++ b/packages/serialize-request/lib/index.js @@ -1,3 +1,13 @@ +/** + * @import { + * Request, + * RequestHeaders, + * SerializedRequest, + * SerializedRequestHeaders, + * SerializeRequestOptions + * } from '@dotcom-reliability-kit/serialize-request' + */ + const DEFAULT_INCLUDED_HEADERS = [ 'accept', 'accept-encoding', @@ -15,9 +25,9 @@ const URL_TRUNCATION_LENGTH = 200; /** * Serialize a request object so that it can be consistently logged or output as JSON. * - * @param {import('@dotcom-reliability-kit/serialize-request').Request} request - * @param {import('@dotcom-reliability-kit/serialize-request').SerializeRequestOptions} options - * @returns {import('@dotcom-reliability-kit/serialize-request').SerializedRequest} + * @param {Request} request + * @param {SerializeRequestOptions} options + * @returns {SerializedRequest} */ function serializeRequest(request, options = {}) { // If the request is not an object, assume it's the request @@ -95,9 +105,9 @@ function serializeRequest(request, options = {}) { /** * Serialize request headers. * - * @param {import('@dotcom-reliability-kit/serialize-request').RequestHeaders} headers + * @param {RequestHeaders} headers * @param {string[]} includeHeaders - * @returns {import('@dotcom-reliability-kit/serialize-request').SerializedRequestHeaders} + * @returns {SerializedRequestHeaders} */ function serializeHeaders(headers, includeHeaders) { const headersObject = {}; @@ -123,7 +133,7 @@ function serializeHeaders(headers, includeHeaders) { * Create a new serialized request object. * * @param {{[key: string]: any}} properties - * @returns {import('@dotcom-reliability-kit/serialize-request').SerializedRequest} + * @returns {SerializedRequest} */ function createSerializedRequest(properties) { return Object.assign( diff --git a/resources/logos/scripts/build.js b/resources/logos/scripts/build.js index 1198a5ee..8651bc54 100755 --- a/resources/logos/scripts/build.js +++ b/resources/logos/scripts/build.js @@ -31,7 +31,6 @@ const sharp = require('sharp'); async function buildLogo(name, pngSizes) { // Load and optimize the SVG const filePath = path.join(src, `${name}.svg`); - // @ts-ignore const svgString = optimizeSvg(await readFile(filePath, 'utf-8')).data || ''; // Save the optimized SVG diff --git a/scripts/create-package.js b/scripts/create-package.js index 96df29e0..1fe9bb83 100755 --- a/scripts/create-package.js +++ b/scripts/create-package.js @@ -93,7 +93,6 @@ This module is part of [FT.com Reliability Kit](https://github.com/Financial-Tim // Add package to Release Please config console.log('🚢 adding package to Release Please config'); - // @ts-ignore releasePleaseConfig.packages[`packages/${name}`] = {}; await fs.writeFile( path.resolve(__dirname, '..', 'release-please-config.json'), @@ -101,7 +100,6 @@ This module is part of [FT.com Reliability Kit](https://github.com/Financial-Tim ); console.log('🚢 adding package to Release Please manifest'); - // @ts-ignore releasePleaseManifest[`packages/${name}`] = '0.0.0'; await fs.writeFile( path.resolve(__dirname, '..', '.release-please-manifest.json'),