From 77d645b8383ecfa4b84b1af46fe9e874bd912d36 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:25:15 +0000 Subject: [PATCH 01/13] Resolve lint related package issues and remove nextjs config --- eslint.config.mjs | 14 - package-lock.json | 777 +++++++++++++++++++++++++++++++++------------- package.json | 8 +- 3 files changed, 564 insertions(+), 235 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index b086976..bdd9bc5 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -169,20 +169,6 @@ export default defineConfig([ plugins: { html }, }, - // Next.js - ...compat.config({ - extends: ['next', 'next/core-web-vitals', 'next/typescript'], - settings: { - next: { - rootDir: 'frontend', - }, - }, - rules: { - // needed because next lint rules look for a pages directory - '@next/next/no-html-link-for-pages': 0, - }, - }), - // json { files: ['**/*.json'], diff --git a/package-lock.json b/package-lock.json index 6cd3e2e..486a6a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,13 @@ "lambdas/client-transform-filter-lambda" ], "devDependencies": { + "@stylistic/eslint-plugin": "^3.1.0", "@tsconfig/node22": "^22.0.2", "@types/jest": "^29.5.14", - "@typescript-eslint/eslint-plugin": "^8.27.0", "@typescript-eslint/parser": "^8.27.0", "esbuild": "^0.25.0", "eslint": "^9.27.0", "eslint-config-airbnb-extended": "^1.0.11", - "eslint-config-next": "^15.3.2", "eslint-config-prettier": "^10.1.5", "eslint-import-resolver-typescript": "^4.4.2", "eslint-plugin-html": "^8.1.3", @@ -38,7 +37,8 @@ "lcov-result-merger": "^5.0.1", "ts-jest": "^29.3.0", "ts-node": "^10.9.2", - "tsx": "^4.19.3" + "tsx": "^4.19.3", + "typescript-eslint": "^8.54.0" } }, "lambdas/client-transform-filter-lambda": { @@ -546,6 +546,40 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", @@ -922,7 +956,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1600,12 +1636,27 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@next/eslint-plugin-next": { "version": "15.3.4", "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.3.4.tgz", "integrity": "sha512-lBxYdj7TI8phbJcLSAqDt57nIcobEign5NYIKCiy0hXQhrUbTqLqOaSDi568U6vFg4hJfBdZYsG4iP/uKhCqgg==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-glob": "3.3.1" } @@ -1616,6 +1667,8 @@ "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1633,6 +1686,8 @@ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1672,16 +1727,6 @@ "node": ">= 8" } }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, "node_modules/@pkgr/core": { "version": "0.2.7", "dev": true, @@ -1696,14 +1741,9 @@ "node_modules/@rtsao/scc": { "version": "1.1.0", "dev": true, - "license": "MIT" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", - "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", - "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -1726,76 +1766,50 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@swc/core": { - "version": "1.12.6", + "node_modules/@stylistic/eslint-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-3.1.0.tgz", + "integrity": "sha512-pA6VOrOqk0+S8toJYhQGv2MWpQQR0QpeUo9AhNkC49Y26nxBQ/nH1rta9bUU1rPw2fJ1zZEMV5oCX5AazT7J2g==", "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.23" + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.12.6", - "@swc/core-darwin-x64": "1.12.6", - "@swc/core-linux-arm-gnueabihf": "1.12.6", - "@swc/core-linux-arm64-gnu": "1.12.6", - "@swc/core-linux-arm64-musl": "1.12.6", - "@swc/core-linux-x64-gnu": "1.12.6", - "@swc/core-linux-x64-musl": "1.12.6", - "@swc/core-win32-arm64-msvc": "1.12.6", - "@swc/core-win32-ia32-msvc": "1.12.6", - "@swc/core-win32-x64-msvc": "1.12.6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } + "eslint": ">=8.40.0" } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.12.6", - "cpu": [ - "arm64" - ], + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, + "license": "Apache-2.0", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true - }, - "node_modules/@swc/types": { - "version": "0.1.23", + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@swc/counter": "^0.1.3" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@tootallnate/once": { @@ -1833,6 +1847,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/aws-lambda": { "version": "8.10.150", "dev": true, @@ -1940,7 +1965,9 @@ "node_modules/@types/json5": { "version": "0.0.29", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/node": { "version": "24.0.3", @@ -1974,19 +2001,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", + "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.35.0", - "@typescript-eslint/type-utils": "8.35.0", - "@typescript-eslint/utils": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/type-utils": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1996,21 +2024,33 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.35.0", + "@typescript-eslint/parser": "^8.54.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", + "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.35.0", - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/typescript-estree": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2021,17 +2061,19 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", + "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.35.0", - "@typescript-eslint/types": "^8.35.0", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.54.0", + "@typescript-eslint/types": "^8.54.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2041,16 +2083,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", + "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2061,7 +2105,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", + "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", "dev": true, "license": "MIT", "engines": { @@ -2072,18 +2118,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", + "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.35.0", - "@typescript-eslint/utils": "8.35.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2094,11 +2143,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", + "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", "dev": true, "license": "MIT", "engines": { @@ -2110,20 +2161,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", + "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.35.0", - "@typescript-eslint/tsconfig-utils": "8.35.0", - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/visitor-keys": "8.35.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/project-service": "8.54.0", + "@typescript-eslint/tsconfig-utils": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2133,18 +2185,33 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", + "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.35.0", - "@typescript-eslint/types": "8.35.0", - "@typescript-eslint/typescript-estree": "8.35.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2155,15 +2222,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.35.0", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", + "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.35.0", + "@typescript-eslint/types": "8.54.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2176,6 +2245,8 @@ }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2185,6 +2256,34 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.9.2.tgz", + "integrity": "sha512-tS+lqTU3N0kkthU+rYp0spAYq15DU8ld9kXkaKg9sbQqJNF+WPMuNHZQGCgdxrUOEO0j22RKMwRVhF1HTl+X8A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.9.2.tgz", + "integrity": "sha512-MffGiZULa/KmkNjHeuuflLVqfhqLv1vZLm8lWIyeADvlElJ/GLSOkoUX+5jf4/EGtfwrNFcEaB8BRas03KT0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@unrs/resolver-binding-darwin-arm64": { "version": "1.9.2", "cpu": [ @@ -2197,6 +2296,233 @@ "darwin" ] }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.9.2.tgz", + "integrity": "sha512-gaIMWK+CWtXcg9gUyznkdV54LzQ90S3X3dn8zlh+QR5Xy7Y+Efqw4Rs4im61K1juy4YNb67vmJsCDAGOnIeffQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.9.2.tgz", + "integrity": "sha512-S7QpkMbVoVJb0xwHFwujnwCAEDe/596xqY603rpi/ioTn9VDgBHnCCxh+UFrr5yxuMH+dliHfjwCZJXOPJGPnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.9.2.tgz", + "integrity": "sha512-+XPUMCuCCI80I46nCDFbGum0ZODP5NWGiwS3Pj8fOgsG5/ctz+/zzuBlq/WmGa+EjWZdue6CF0aWWNv84sE1uw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.9.2.tgz", + "integrity": "sha512-sqvUyAd1JUpwbz33Ce2tuTLJKM+ucSsYpPGl2vuFwZnEIg0CmdxiZ01MHQ3j6ExuRqEDUCy8yvkDKvjYFPb8Zg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.9.2.tgz", + "integrity": "sha512-UYA0MA8ajkEDCFRQdng/FVx3F6szBvk3EPnkTTQuuO9lV1kPGuTB+V9TmbDxy5ikaEgyWKxa4CI3ySjklZ9lFA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.9.2.tgz", + "integrity": "sha512-P/CO3ODU9YJIHFqAkHbquKtFst0COxdphc8TKGL5yCX75GOiVpGqd1d15ahpqu8xXVsqP4MGFP2C3LRZnnL5MA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.9.2.tgz", + "integrity": "sha512-uKStFlOELBxBum2s1hODPtgJhY4NxYJE9pAeyBgNEzHgTqTiVBPjfTlPFJkfxyTjQEuxZbbJlJnMCrRgD7ubzw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.9.2.tgz", + "integrity": "sha512-LkbNnZlhINfY9gK30AHs26IIVEZ9PEl9qOScYdmY2o81imJYI4IMnJiW0vJVtXaDHvBvxeAgEy5CflwJFIl3tQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.9.2.tgz", + "integrity": "sha512-vI+e6FzLyZHSLFNomPi+nT+qUWN4YSj8pFtQZSFTtmgFoxqB6NyjxSjAxEC1m93qn6hUXhIsh8WMp+fGgxCoRg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.9.2.tgz", + "integrity": "sha512-sSO4AlAYhSM2RAzBsRpahcJB1msc6uYLAtP6pesPbZtptF8OU/CbCPhSRW6cnYOGuVmEmWVW5xVboAqCnWTeHQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.9.2.tgz", + "integrity": "sha512-jkSkwch0uPFva20Mdu8orbQjv2A3G88NExTN2oPTI1AJ+7mZfYW3cDCTyoH6OnctBKbBVeJCEqh0U02lTkqD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.9.2.tgz", + "integrity": "sha512-Uk64NoiTpQbkpl+bXsbeyOPRpUoMdcUqa+hDC1KhMW7aN1lfW8PBlBH4mJ3n3Y47dYE8qi0XTxy1mBACruYBaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.9.2.tgz", + "integrity": "sha512-EpBGwkcjDicjR/ybC0g8wO5adPNdVuMrNalVgYcWi+gYtC1XYNuxe3rufcO7dA76OHGeVabcO6cSkPJKVcbCXQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.9.2.tgz", + "integrity": "sha512-EdFbGn7o1SxGmN6aZw9wAkehZJetFPao0VGZ9OMBwKx6TkvDuj6cNeLimF/Psi6ts9lMOe+Dt6z19fZQ9Ye2fw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.9.2.tgz", + "integrity": "sha512-JY9hi1p7AG+5c/dMU8o2kWemM8I6VZxfGwn1GCtf3c5i+IKcMo2NQ8OjZ4Z3/itvY/Si3K10jOBQn7qsD/whUA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.9.2.tgz", + "integrity": "sha512-ryoo+EB19lMxAd80ln9BVf8pdOAxLb97amrQ3SFN9OCRn/5M5wvwDgAe4i8ZjhpbiHoDeP8yavcTEnpKBo7lZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/abab": { "version": "2.0.6", "dev": true, @@ -2413,6 +2739,8 @@ "version": "1.2.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", @@ -3142,7 +3470,9 @@ } }, "node_modules/debug": { - "version": "4.4.1", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -3778,69 +4108,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-config-next": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.3.4.tgz", - "integrity": "sha512-WqeumCq57QcTP2lYlV6BRUySfGiBYEXlQ1L0mQ+u4N4X4ZhUVSSQ52WtjqHv60pJ6dD7jn+YZc0d1/ZSsxccvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@next/eslint-plugin-next": "15.3.4", - "@rushstack/eslint-patch": "^1.10.3", - "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsx-a11y": "^6.10.0", - "eslint-plugin-react": "^7.37.0", - "eslint-plugin-react-hooks": "^5.0.0" - }, - "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", - "typescript": ">=3.3.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-next/node_modules/eslint-import-resolver-typescript": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", - "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.4.0", - "get-tsconfig": "^4.10.0", - "is-bun-module": "^2.0.0", - "stable-hash": "^0.0.5", - "tinyglobby": "^0.2.13", - "unrs-resolver": "^1.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, "node_modules/eslint-config-prettier": { "version": "10.1.5", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz", @@ -3886,6 +4153,8 @@ "version": "0.3.9", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -3896,6 +4165,8 @@ "version": "3.2.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -3939,6 +4210,8 @@ "version": "2.12.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^3.2.7" }, @@ -3955,6 +4228,8 @@ "version": "3.2.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -3974,6 +4249,8 @@ "version": "2.32.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -4043,6 +4320,8 @@ "version": "1.1.12", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4052,6 +4331,8 @@ "version": "3.2.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -4060,6 +4341,8 @@ "version": "3.1.2", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4071,6 +4354,8 @@ "version": "6.3.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "bin": { "semver": "bin/semver.js" } @@ -4249,6 +4534,8 @@ "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -4824,6 +5111,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "dev": true, @@ -5055,11 +5357,6 @@ "dev": true, "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, "node_modules/has-bigints": { "version": "1.1.0", "dev": true, @@ -6880,6 +7177,8 @@ "version": "1.2.8", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7049,6 +7348,8 @@ "version": "1.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7958,13 +8259,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/stable-hash": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", - "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", - "dev": true, - "license": "MIT" - }, "node_modules/stable-hash-x": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", @@ -8267,12 +8561,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.14", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -8282,9 +8578,14 @@ } }, "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "picomatch": "^3 || ^4" }, @@ -8295,7 +8596,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -8347,7 +8650,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, "license": "MIT", "engines": { @@ -8482,6 +8787,8 @@ "version": "3.15.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -8493,6 +8800,8 @@ "version": "1.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "minimist": "^1.2.0" }, @@ -8504,10 +8813,20 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=4" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/tsx": { "version": "4.20.3", "dev": true, @@ -9065,6 +9384,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.54.0.tgz", + "integrity": "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.54.0", + "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "dev": true, diff --git a/package.json b/package.json index 3c6afdf..64a600f 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,13 @@ { "//": "PLEASE UPDATE THE NAME AND WORKSPACES APPROPRIATELY.", "devDependencies": { + "@stylistic/eslint-plugin": "^3.1.0", "@tsconfig/node22": "^22.0.2", "@types/jest": "^29.5.14", - "@typescript-eslint/eslint-plugin": "^8.27.0", "@typescript-eslint/parser": "^8.27.0", "esbuild": "^0.25.0", "eslint": "^9.27.0", "eslint-config-airbnb-extended": "^1.0.11", - "eslint-config-next": "^15.3.2", "eslint-config-prettier": "^10.1.5", "eslint-import-resolver-typescript": "^4.4.2", "eslint-plugin-html": "^8.1.3", @@ -30,7 +29,8 @@ "lcov-result-merger": "^5.0.1", "ts-jest": "^29.3.0", "ts-node": "^10.9.2", - "tsx": "^4.19.3" + "tsx": "^4.19.3", + "typescript-eslint": "^8.54.0" }, "name": "nhs-notify-repository-template", "overrides": { @@ -50,4 +50,4 @@ "workspaces": [ "lambdas/client-transform-filter-lambda" ] -} +} \ No newline at end of file From 46c06696f1f80ff6a9a5b21f03fcac87d98ea364 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:25:41 +0000 Subject: [PATCH 02/13] Remove deprecated .eslintignore --- lambdas/client-transform-filter-lambda/.eslintignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 lambdas/client-transform-filter-lambda/.eslintignore diff --git a/lambdas/client-transform-filter-lambda/.eslintignore b/lambdas/client-transform-filter-lambda/.eslintignore deleted file mode 100644 index 1521c8b..0000000 --- a/lambdas/client-transform-filter-lambda/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist From 406ed3783e62e4b7795d5fd689d8993d20e28693 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:45:06 +0000 Subject: [PATCH 03/13] lint: ignore lambdas from single export should be default rule --- eslint.config.mjs | 150 +++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index bdd9bc5..957b983 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,28 +1,28 @@ -import jest from 'eslint-plugin-jest'; -import jsxA11y from 'eslint-plugin-jsx-a11y'; -import prettierRecommended from 'eslint-plugin-prettier/recommended'; -import { importX } from 'eslint-plugin-import-x'; -import * as eslintImportResolverTypescript from 'eslint-import-resolver-typescript'; -import noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths'; -import react from 'eslint-plugin-react'; -import security from 'eslint-plugin-security'; -import sonarjs from 'eslint-plugin-sonarjs'; -import json from 'eslint-plugin-json'; -import unicorn from 'eslint-plugin-unicorn'; -import { defineConfig, globalIgnores } from 'eslint/config'; -import js from '@eslint/js'; -import html from 'eslint-plugin-html'; -import tseslint from 'typescript-eslint'; -import sortDestructureKeys from 'eslint-plugin-sort-destructure-keys'; +import jest from "eslint-plugin-jest"; +import jsxA11y from "eslint-plugin-jsx-a11y"; +import prettierRecommended from "eslint-plugin-prettier/recommended"; +import { importX } from "eslint-plugin-import-x"; +import * as eslintImportResolverTypescript from "eslint-import-resolver-typescript"; +import noRelativeImportPaths from "eslint-plugin-no-relative-import-paths"; +import react from "eslint-plugin-react"; +import security from "eslint-plugin-security"; +import sonarjs from "eslint-plugin-sonarjs"; +import json from "eslint-plugin-json"; +import unicorn from "eslint-plugin-unicorn"; +import { defineConfig, globalIgnores } from "eslint/config"; +import js from "@eslint/js"; +import html from "eslint-plugin-html"; +import tseslint from "typescript-eslint"; +import sortDestructureKeys from "eslint-plugin-sort-destructure-keys"; import { configs as airbnbConfigs, plugins as airbnbPlugins, -} from 'eslint-config-airbnb-extended'; -import { rules as prettierConfigRules } from 'eslint-config-prettier'; +} from "eslint-config-airbnb-extended"; +import { rules as prettierConfigRules } from "eslint-config-prettier"; -import { dirname } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { FlatCompat } from '@eslint/eslintrc'; +import { dirname } from "node:path"; +import { fileURLToPath } from "node:url"; +import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -33,13 +33,13 @@ const compat = new FlatCompat({ export default defineConfig([ globalIgnores([ - '**/*/coverage/*', - '**/.build', - '**/node_modules', - '**/dist', - '**/test-results', - '**/playwright-report*', - 'eslint.config.mjs', + "**/*/coverage/*", + "**/.build", + "**/node_modules", + "**/dist", + "**/test-results", + "**/playwright-report*", + "eslint.config.mjs", ]), //imports @@ -58,7 +58,7 @@ export default defineConfig([ airbnbPlugins.typescriptEslint, { - ignores: ['**/*.json'], + ignores: ["**/*.json"], languageOptions: { parserOptions: { projectService: true, @@ -68,19 +68,19 @@ export default defineConfig([ }, { - files: ['**/*.json'], + files: ["**/*.json"], extends: [tseslint.configs.disableTypeChecked], }, { settings: { - 'import-x/resolver-next': [ + "import-x/resolver-next": [ eslintImportResolverTypescript.createTypeScriptImportResolver({ project: [ - 'frontend/tsconfig.json', - 'lambdas/*/tsconfig.json', - 'tests/test-team/tsconfig.json', - 'utils/*/tsconfig.json', + "frontend/tsconfig.json", + "lambdas/*/tsconfig.json", + "tests/test-team/tsconfig.json", + "utils/*/tsconfig.json", ], }), ], @@ -89,32 +89,32 @@ export default defineConfig([ { rules: { - '@typescript-eslint/no-unused-vars': [ + "@typescript-eslint/no-unused-vars": [ 2, { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", }, ], - '@typescript-eslint/consistent-type-definitions': 0, + "@typescript-eslint/consistent-type-definitions": 0, }, }, // unicorn - unicorn.configs['recommended'], + unicorn.configs["recommended"], { rules: { - 'unicorn/prevent-abbreviations': 0, - 'unicorn/filename-case': [ + "unicorn/prevent-abbreviations": 0, + "unicorn/filename-case": [ 2, { - case: 'kebabCase', - ignore: ['.tsx'], + case: "kebabCase", + ignore: [".tsx"], }, ], - 'unicorn/no-null': 0, - 'unicorn/prefer-module': 0, - 'unicorn/import-style': [ + "unicorn/no-null": 0, + "unicorn/prefer-module": 0, + "unicorn/import-style": [ 2, { styles: { @@ -136,17 +136,17 @@ export default defineConfig([ airbnbPlugins.reactA11y, // jest - jest.configs['flat/recommended'], + jest.configs["flat/recommended"], // prettier prettierRecommended, - { rules: { ...prettierConfigRules, 'prettier/prettier': 2 } }, + { rules: { ...prettierConfigRules, "prettier/prettier": 2 } }, // jsxA11y { - files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], + files: ["**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}"], plugins: { - 'jsx-a11y': jsxA11y, + "jsx-a11y": jsxA11y, }, languageOptions: { parserOptions: { @@ -165,49 +165,49 @@ export default defineConfig([ // html { - files: ['**/*.html'], + files: ["**/*.html"], plugins: { html }, }, // json { - files: ['**/*.json'], - ...json.configs['recommended'], + files: ["**/*.json"], + ...json.configs["recommended"], }, // destructure sorting { - name: 'eslint-plugin-sort-destructure-keys', + name: "eslint-plugin-sort-destructure-keys", plugins: { - 'sort-destructure-keys': sortDestructureKeys, + "sort-destructure-keys": sortDestructureKeys, }, rules: { - 'sort-destructure-keys/sort-destructure-keys': 2, + "sort-destructure-keys/sort-destructure-keys": 2, }, }, // imports { rules: { - 'sort-imports': [ + "sort-imports": [ 2, { ignoreDeclarationSort: true, }, ], - 'import-x/extensions': 0, + "import-x/extensions": 0, }, }, { - files: ['**/*.ts', '**/*.tsx'], + files: ["**/*.ts", "**/*.tsx"], rules: { - 'import-x/no-unresolved': 0, // trust the typescript compiler to catch unresolved imports + "import-x/no-unresolved": 0, // trust the typescript compiler to catch unresolved imports }, }, { - files: ['tests/test-team/**'], + files: ["tests/test-team/**"], rules: { - 'import-x/no-extraneous-dependencies': [ + "import-x/no-extraneous-dependencies": [ 2, { devDependencies: true, @@ -216,24 +216,24 @@ export default defineConfig([ }, }, { - files: ['**/utils/**', 'tests/test-team/**'], + files: ["**/utils/**", "tests/test-team/**", "lambdas/**/src/**"], rules: { - 'import-x/prefer-default-export': 0, + "import-x/prefer-default-export": 0, }, }, { plugins: { - 'no-relative-import-paths': noRelativeImportPaths, + "no-relative-import-paths": noRelativeImportPaths, }, rules: { - 'no-relative-import-paths/no-relative-import-paths': 2, + "no-relative-import-paths/no-relative-import-paths": 2, }, }, { - files: ['scripts/**'], + files: ["scripts/**"], rules: { - 'import-x/no-extraneous-dependencies': [ - 'error', + "import-x/no-extraneous-dependencies": [ + "error", { devDependencies: true }, ], }, @@ -242,11 +242,11 @@ export default defineConfig([ // misc rule overrides { rules: { - 'no-restricted-syntax': 0, - 'no-underscore-dangle': 0, - 'no-await-in-loop': 0, - 'no-plusplus': [2, { allowForLoopAfterthoughts: true }], - 'unicorn/prefer-top-level-await': 0, // top level await is not available in commonjs + "no-restricted-syntax": 0, + "no-underscore-dangle": 0, + "no-await-in-loop": 0, + "no-plusplus": [2, { allowForLoopAfterthoughts: true }], + "unicorn/prefer-top-level-await": 0, // top level await is not available in commonjs }, }, ]); From 504f3af57ce9873080a5d6f4c8197bfeecafc3cd Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:45:28 +0000 Subject: [PATCH 04/13] lint: single quotes --- .../jest.config.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lambdas/client-transform-filter-lambda/jest.config.ts b/lambdas/client-transform-filter-lambda/jest.config.ts index d30f4cd..f88e727 100644 --- a/lambdas/client-transform-filter-lambda/jest.config.ts +++ b/lambdas/client-transform-filter-lambda/jest.config.ts @@ -1,7 +1,7 @@ -import type { Config } from 'jest'; +import type { Config } from "jest"; export const baseJestConfig: Config = { - preset: 'ts-jest', + preset: "ts-jest", // Automatically clear mock calls, instances, contexts and results before every test clearMocks: true, @@ -10,10 +10,10 @@ export const baseJestConfig: Config = { collectCoverage: true, // The directory where Jest should output its coverage files - coverageDirectory: './.reports/unit/coverage', + coverageDirectory: "./.reports/unit/coverage", // Indicates which provider should be used to instrument code for coverage - coverageProvider: 'babel', + coverageProvider: "babel", coverageThreshold: { global: { @@ -24,36 +24,36 @@ export const baseJestConfig: Config = { }, }, - coveragePathIgnorePatterns: ['/__tests__/'], - transform: { '^.+\\.ts$': 'ts-jest' }, - testPathIgnorePatterns: ['.build'], - testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + coveragePathIgnorePatterns: ["/__tests__/"], + transform: { "^.+\\.ts$": "ts-jest" }, + testPathIgnorePatterns: [".build"], + testMatch: ["**/?(*.)+(spec|test).[jt]s?(x)"], // Use this configuration option to add custom reporters to Jest reporters: [ - 'default', + "default", [ - 'jest-html-reporter', + "jest-html-reporter", { - pageTitle: 'Test Report', - outputPath: './.reports/unit/test-report.html', + pageTitle: "Test Report", + outputPath: "./.reports/unit/test-report.html", includeFailureMsg: true, }, ], ], // The test environment that will be used for testing - testEnvironment: 'jsdom', + testEnvironment: "jsdom", }; const utilsJestConfig = { ...baseJestConfig, - testEnvironment: 'node', + testEnvironment: "node", coveragePathIgnorePatterns: [ ...(baseJestConfig.coveragePathIgnorePatterns ?? []), - 'zod-validators.ts', + "zod-validators.ts", ], }; From 859047500ee106a1b65f4222a9af492a6217bbc4 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:48:00 +0000 Subject: [PATCH 05/13] lint: fix issues in temp lambda --- .../src/index.ts | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lambdas/client-transform-filter-lambda/src/index.ts b/lambdas/client-transform-filter-lambda/src/index.ts index 119bd36..91bfa94 100644 --- a/lambdas/client-transform-filter-lambda/src/index.ts +++ b/lambdas/client-transform-filter-lambda/src/index.ts @@ -1,11 +1,13 @@ export const handler = async (event: any) => { + // eslint-disable-next-line no-console console.log("RAW EVENT:", JSON.stringify(event, null, 2)); let parsedEvent: any; try { parsedEvent = typeof event === "string" ? JSON.parse(event) : event; - } catch (err) { - console.error("Could not parse event string:", err); + } catch (error) { + // eslint-disable-next-line no-console + console.error("Could not parse event string:", error); return { body: {} }; } @@ -14,16 +16,20 @@ export const handler = async (event: any) => { function findFields(obj: any) { if (!obj || typeof obj !== "object") return; - if (!dataschemaversion && "dataschemaversion" in obj) dataschemaversion = obj.dataschemaversion; + if (!dataschemaversion && "dataschemaversion" in obj) + dataschemaversion = obj.dataschemaversion; if (!type && "type" in obj) type = obj.type; for (const key of Object.keys(obj)) { + // eslint-disable-next-line security/detect-object-injection const val = obj[key]; if (typeof val === "string") { try { const nested = JSON.parse(val); findFields(nested); - } catch {} + } catch { + /* empty */ + } } else if (typeof val === "object") { findFields(val); } @@ -31,12 +37,13 @@ export const handler = async (event: any) => { } if (Array.isArray(parsedEvent)) { - parsedEvent.forEach(item => findFields(item)); + for (const item of parsedEvent) findFields(item); } else { findFields(parsedEvent); } if (!dataschemaversion || !type) { + // eslint-disable-next-line no-console console.error("Failed to extract payload from event!"); return { body: {} }; } @@ -44,7 +51,7 @@ export const handler = async (event: any) => { return { body: { dataschemaversion, - type - } + type, + }, }; }; From 9b662cb4612073aba3a902ea153aada562feddde Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:48:53 +0000 Subject: [PATCH 06/13] lint: fix issues in temp lambda test --- .../src/__tests__/index.test.ts | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/lambdas/client-transform-filter-lambda/src/__tests__/index.test.ts b/lambdas/client-transform-filter-lambda/src/__tests__/index.test.ts index 2c2996c..b00cc1c 100644 --- a/lambdas/client-transform-filter-lambda/src/__tests__/index.test.ts +++ b/lambdas/client-transform-filter-lambda/src/__tests__/index.test.ts @@ -1,21 +1,20 @@ -import { handler } from "../index"; +import { handler } from ".."; describe("Lambda handler", () => { - it("extracts from a stringified event", async () => { const eventStr = JSON.stringify({ body: { dataschemaversion: "1.0", - type: "uk.nhs.notify.client-callbacks.test-sid" - } + type: "uk.nhs.notify.client-callbacks.test-sid", + }, }); const result = await handler(eventStr); expect(result).toEqual({ body: { dataschemaversion: "1.0", - type: "uk.nhs.notify.client-callbacks.test-sid" - } + type: "uk.nhs.notify.client-callbacks.test-sid", + }, }); }); @@ -26,18 +25,18 @@ describe("Lambda handler", () => { body: JSON.stringify({ body: { dataschemaversion: "1.0", - type: "uk.nhs.notify.client-callbacks.test-sid" - } - }) - } + type: "uk.nhs.notify.client-callbacks.test-sid", + }, + }), + }, ]; const result = await handler(eventArray); expect(result).toEqual({ body: { dataschemaversion: "1.0", - type: "uk.nhs.notify.client-callbacks.test-sid" - } + type: "uk.nhs.notify.client-callbacks.test-sid", + }, }); }); @@ -54,19 +53,19 @@ describe("Lambda handler", () => { body: JSON.stringify({ body: { dataschemaversion: "2.0", - type: "nested-type" - } - }) - } - } + type: "nested-type", + }, + }), + }, + }, }; const result = await handler(event); expect(result).toEqual({ body: { dataschemaversion: "2.0", - type: "nested-type" - } + type: "nested-type", + }, }); }); @@ -75,5 +74,4 @@ describe("Lambda handler", () => { const result = await handler(eventStr); expect(result).toEqual({ body: {} }); }); - }); From 1f2443b0daf78f6756a8047f83c64502c304ee3b Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 2 Feb 2026 14:57:00 +0000 Subject: [PATCH 07/13] Set node name --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 64a600f..a449a6e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,4 @@ { - "//": "PLEASE UPDATE THE NAME AND WORKSPACES APPROPRIATELY.", "devDependencies": { "@stylistic/eslint-plugin": "^3.1.0", "@tsconfig/node22": "^22.0.2", @@ -32,7 +31,7 @@ "tsx": "^4.19.3", "typescript-eslint": "^8.54.0" }, - "name": "nhs-notify-repository-template", + "name": "nhs-notify-client-callbacks", "overrides": { "pretty-format": { "react-is": "19.0.0" From 043330dbb3ae11e020585a7ad5f2b1495d681707 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Thu, 5 Feb 2026 11:31:36 +0000 Subject: [PATCH 08/13] Add vale exceptions --- .../config/vale/styles/config/vocabularies/words/accept.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/config/vale/styles/config/vocabularies/words/accept.txt b/scripts/config/vale/styles/config/vocabularies/words/accept.txt index 3aa82c3..b3cb4bc 100644 --- a/scripts/config/vale/styles/config/vocabularies/words/accept.txt +++ b/scripts/config/vale/styles/config/vocabularies/words/accept.txt @@ -1,9 +1,12 @@ [A-Z]+s +ajv Bitwarden bot Cognito +[Cc]onfig Cyber Dependabot +dev draw.io drawio endcapture @@ -20,6 +23,7 @@ onboarding Podman Python rawContent +[Rr]unbook sed Syft Terraform From 1e635a761c1315e6d2ed2524b5ca208448bfdf17 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Fri, 6 Feb 2026 14:24:33 +0000 Subject: [PATCH 09/13] Use base tsconfig --- .../tsconfig.json | 2 +- tsconfig.base.json | 22 +++++++++++++++++++ tsconfig.json | 13 +++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tsconfig.base.json create mode 100644 tsconfig.json diff --git a/lambdas/client-transform-filter-lambda/tsconfig.json b/lambdas/client-transform-filter-lambda/tsconfig.json index ea37d69..9e05f63 100644 --- a/lambdas/client-transform-filter-lambda/tsconfig.json +++ b/lambdas/client-transform-filter-lambda/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@tsconfig/node22/tsconfig.json", + "extends": "../../tsconfig.base.json", "include": [ "src/**/*", "jest.config.ts" diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..bc388dc --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2022"], + "esModuleInterop": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "noEmit": true + }, + "exclude": [ + "node_modules", + "dist", + "build", + "coverage" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ccb61df --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "./tsconfig.base.json", + "compilerOptions": { + "noEmit": true + }, + "include": [ + "lambdas/*/src/**/*", + "scripts/*/src/**/*", + "src/**/*", + "tests/**/*" + ] +} From c291f11699d1f9d445e6e8763c50391f0cc7a168 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 9 Feb 2026 10:05:23 +0000 Subject: [PATCH 10/13] Wheel dependency update to fix trivy scan --- .../docker/examples/python/assets/hello_world/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/examples/python/assets/hello_world/requirements.txt b/scripts/docker/examples/python/assets/hello_world/requirements.txt index 5331aff..6ac36a3 100644 --- a/scripts/docker/examples/python/assets/hello_world/requirements.txt +++ b/scripts/docker/examples/python/assets/hello_world/requirements.txt @@ -8,5 +8,5 @@ MarkupSafe==2.1.3 pip==23.3 setuptools==78.1.1 Werkzeug==3.0.6 -wheel==0.41.1 +wheel==0.46.2 WTForms==3.0.1 From 317c74cacc6983b0bf3ce5b81eceee7f77251f98 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 9 Feb 2026 10:10:41 +0000 Subject: [PATCH 11/13] Fix line endings --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a449a6e..2013466 100644 --- a/package.json +++ b/package.json @@ -49,4 +49,4 @@ "workspaces": [ "lambdas/client-transform-filter-lambda" ] -} \ No newline at end of file +} From 43a0c40afc862f8aaf2a580b6fcacf5e8fee30ae Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 9 Feb 2026 14:13:48 +0000 Subject: [PATCH 12/13] Fix makefile scripts --- Makefile | 13 +++++++++---- package-lock.json | 4 ++-- scripts/tests/lint.sh | 9 +++++++++ scripts/tests/typecheck.sh | 9 +++++++++ tsconfig.base.json | 20 +------------------- 5 files changed, 30 insertions(+), 25 deletions(-) create mode 100755 scripts/tests/lint.sh create mode 100755 scripts/tests/typecheck.sh diff --git a/Makefile b/Makefile index ea70e95..666201c 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ include scripts/init.mk # ============================================================================== -# Example CI/CD targets are: dependencies, build, publish, deploy, clean, etc. +# Example CI/CD targets are: dependencies, build, clean, etc. dependencies: # Install dependencies needed to build and test the project @Pipeline - # TODO: Implement installation of your project dependencies + npm ci build: # Build the project artefact @Pipeline (cd docs && make build) @@ -20,8 +20,13 @@ deploy: # Deploy the project artefact to the target environment @Pipeline # TODO: Implement the artefact deployment step clean:: # Clean-up project resources (main) @Operations - rm -f .version - # TODO: Implement project resources clean-up step + rm -f .version version.json + rm -rf node_modules + rm -rf lambdas/*/dist + rm -rf lambdas/*/node_modules + rm -rf coverage + rm -rf lambdas/*/coverage + (cd docs && make clean 2>/dev/null || true) config:: _install-dependencies version # Configure development environment (main) @Configuration (cd docs && make install) diff --git a/package-lock.json b/package-lock.json index 486a6a1..aa3caa0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,10 @@ { - "name": "nhs-notify-repository-template", + "name": "nhs-notify-client-callbacks", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "nhs-notify-repository-template", + "name": "nhs-notify-client-callbacks", "workspaces": [ "lambdas/client-transform-filter-lambda" ], diff --git a/scripts/tests/lint.sh b/scripts/tests/lint.sh new file mode 100755 index 0000000..23e4bfd --- /dev/null +++ b/scripts/tests/lint.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +cd "$(git rev-parse --show-toplevel)" + +# Run linting across all workspaces +npm ci +npm run lint diff --git a/scripts/tests/typecheck.sh b/scripts/tests/typecheck.sh new file mode 100755 index 0000000..a6f096b --- /dev/null +++ b/scripts/tests/typecheck.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +cd "$(git rev-parse --show-toplevel)" + +# Run TypeScript type checking across all workspaces +npm ci +npm run typecheck diff --git a/tsconfig.base.json b/tsconfig.base.json index bc388dc..fcbb3d0 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,22 +1,4 @@ { "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@tsconfig/node22/tsconfig.json", - "compilerOptions": { - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "Bundler", - "lib": ["ES2022"], - "esModuleInterop": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "noEmit": true - }, - "exclude": [ - "node_modules", - "dist", - "build", - "coverage" - ] + "extends": "@tsconfig/node22/tsconfig.json" } From 30a2eec29ef65bef0607652728d148128ce7ab92 Mon Sep 17 00:00:00 2001 From: Mike Wild Date: Mon, 9 Feb 2026 16:57:55 +0000 Subject: [PATCH 13/13] Update README, license, tool versions (add ruby for jekyll) --- .tool-versions | 1 + LICENCE.md | 2 +- README.md | 151 ++++++++++-------- .../config/vocabularies/words/accept.txt | 4 +- 4 files changed, 90 insertions(+), 68 deletions(-) diff --git a/.tool-versions b/.tool-versions index 389f264..61d8d75 100644 --- a/.tool-versions +++ b/.tool-versions @@ -3,6 +3,7 @@ gitleaks 8.24.0 jq 1.6 nodejs 22.11.0 pre-commit 3.6.0 +ruby 3.3.6 terraform 1.10.1 terraform-docs 0.19.0 trivy 0.61.0 diff --git a/LICENCE.md b/LICENCE.md index 02174c4..3b8ee5f 100644 --- a/LICENCE.md +++ b/LICENCE.md @@ -1,6 +1,6 @@ # MIT Licence -Copyright (c) 2025 Crown Copyright NHS England. +Copyright (c) 2026 Crown Copyright NHS England. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 2945dea..58e6607 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,79 @@ -# NHS Notify Repository Template +# NHS Notify Client Callbacks -[![CI/CD Pull Request](https://github.com/nhs-england-tools/repository-template/actions/workflows/cicd-1-pull-request.yaml/badge.svg)](https://github.com/nhs-england-tools/repository-template/actions/workflows/cicd-1-pull-request.yaml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=repository-template&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=repository-template) +Event-driven infrastructure for delivering NHS Notify callback notifications to client webhook endpoints. This repository implements the Callbacks domain as part of the NHS Notify distributed architecture, receiving events from the Shared Event Bus and orchestrating webhook delivery via EventBridge API Destinations. -Start with an overview or a brief description of what the project is about and what it does. For example - +## Overview -Welcome to our repository template designed to streamline your project setup! This robust template provides a reliable starting point for your new projects, covering an essential tech stack and encouraging best practices in documenting. +The Client Callbacks infrastructure processes message and channel status events, applies client-specific subscription filters, and delivers callbacks to configured webhook endpoints. Events flow from the Shared Event Bus through an SQS queue, are transformed and filtered by a Lambda function, then routed to clients via per-client API Destination Target Rules. -This repository template aims to foster a user-friendly development environment by ensuring that every included file is concise and adequately self-documented. By adhering to this standard, we can promote increased clarity and maintainability throughout your project's lifecycle. Bundled within this template are resources that pave the way for seamless repository creation. Currently supported technologies are: +### Key Features -- Terraform -- Docker - -Make use of this repository template to expedite your project setup and enhance your productivity right from the get-go. Enjoy the advantage of having a well-structured, self-documented project that reduces overhead and increases focus on what truly matters - coding! - -Any code files or example documentation that is not used in the new repository should be removed to prevent the proliferation of duplicate copies of redundant code that if not maintained could introduce vulnerabilities (e.g. via un-patched Dependabot issues). +- **Event-Driven Architecture**: Consumes CloudEvents from the Shared Event Bus (`uk.nhs.notify.client-callbacks.*` namespace) +- **Client Subscription Filtering**: Applies per-client rules for message status and channel status event types +- **Webhook Delivery**: EventBridge API Destinations with per-client configuration and retry policies +- **Failure Handling**: Per-client Dead Letter Queues +- **Backward Compatibility**: Maintains callback payload format compatibility with legacy Core domain implementation ## Table of Contents -- [NHS Notify Repository Template](#nhs-notify-repository-template) +- [NHS Notify Client Callbacks](#nhs-notify-client-callbacks) + - [Overview](#overview) + - [Key Features](#key-features) - [Table of Contents](#table-of-contents) - - [Documentation](#documentation) + - [Architecture](#architecture) + - [Components](#components) + - [Event Flow](#event-flow) - [Setup](#setup) - [Prerequisites](#prerequisites) - [Configuration](#configuration) - [Usage](#usage) - [Testing](#testing) - - [Design](#design) - - [Diagrams](#diagrams) - - [Modularity](#modularity) + - [Infrastructure](#infrastructure) - [Contributing](#contributing) - [Contacts](#contacts) - [Licence](#licence) -## Documentation +## Architecture -- [Built](/) -- [Source](/docs/README.md) +### Components -## Setup +- **Shared Event Bus**: Cross-domain EventBridge bus receiving events from Core, Routing, and other NHS Notify domains +- **Callback Event Queue**: SQS queue subscribed to `uk.nhs.notify.client-callbacks.*` events via EventBridge Target Rule +- **Transform & Filter Lambda**: Processes events, loads client configurations, applies subscription filters, and routes to Callbacks Event Bus +- **Callbacks Event Bus**: Domain-specific EventBridge bus for webhook orchestration +- **API Destination Target Rules**: Per-client rules invoking HTTPS endpoints with client-specific authentication +- **Client Config Storage**: S3 bucket storing client subscription configurations (status filters, webhook endpoints) +- **Per-Client DLQs**: SQS Dead Letter Queues for failed webhook deliveries (one per client) + +### Event Flow -By including preferably a one-liner or if necessary a set of clear CLI instructions we improve user experience. This should be a frictionless installation process that works on various operating systems (macOS, Linux, Windows WSL) and handles all the dependencies. +1. Status change events published to Shared Event Bus in `uk.nhs.notify.client-callbacks.*` namespace +2. SQS Target Rule routes events to Callback Event Queue +3. EventBridge Pipe invokes Transform & Filter Lambda with event batches +4. Lambda loads client subscription configs from S3 +5. Lambda applies client-specific filters (message status, channel status) +6. Matching events published to Callbacks Event Bus +7. API Destination Target Rules deliver callbacks to client webhook endpoints +8. Failed deliveries moved to per-client DLQs after retry exhaustion -Clone the repository +## Setup + +Clone the repository: ```shell -git clone https://github.com/nhs-england-tools/repository-template.git -cd nhs-england-tools/repository-template +git clone https://github.com/NHSDigital/nhs-notify-client-callbacks.git +cd nhs-notify-client-callbacks ``` ### Prerequisites The following software packages, or their equivalents, are expected to be installed and configured: -- [Docker](https://www.docker.com/) container runtime or a compatible tool, e.g. [Podman](https://podman.io/), -- [asdf](https://asdf-vm.com/) version manager, -- [GNU make](https://www.gnu.org/software/make/) 3.82 or later, +- [Node.js](https://nodejs.org/) 20.x or later (for Lambda development) +- [Terraform](https://www.terraform.io/) 1.5.x or later +- [AWS CLI](https://aws.amazon.com/cli/) configured with appropriate credentials +- [asdf](https://asdf-vm.com/) version manager +- [GNU make](https://www.gnu.org/software/make/) 3.82 or later > [!NOTE]
> The version of GNU make available by default on macOS is earlier than 3.82. You will need to upgrade it or certain `make` tasks will fail. On macOS, you will need [Homebrew](https://brew.sh/) installed, then to install `make`, like so: @@ -64,20 +82,15 @@ The following software packages, or their equivalents, are expected to be instal > brew install make > ``` > -> You will then see instructions to fix your [`$PATH`](https://github.com/nhs-england-tools/dotfiles/blob/main/dot_path.tmpl) variable to make the newly installed version available. If you are using [dotfiles](https://github.com/nhs-england-tools/dotfiles), this is all done for you. - -- [GNU sed](https://www.gnu.org/software/sed/) and [GNU grep](https://www.gnu.org/software/grep/) are required for the scripted command-line output processing, -- [GNU coreutils](https://www.gnu.org/software/coreutils/) and [GNU binutils](https://www.gnu.org/software/binutils/) may be required to build dependencies like Python, which may need to be compiled during installation, - -> [!NOTE]
-> For macOS users, installation of the GNU toolchain has been scripted and automated as part of the `dotfiles` project. Please see this [script](https://github.com/nhs-england-tools/dotfiles/blob/main/assets/20-install-base-packages.macos.sh) for details. +> You will then see instructions to fix your [`$PATH`](https://github.com/nhs-england-tools/dotfiles/blob/main/dot_path.tmpl) variable to make the newly installed version available. -- [Python](https://www.python.org/) required to run Git hooks, -- [`jq`](https://jqlang.github.io/jq/) a lightweight and flexible command-line JSON processor. +- [GNU sed](https://www.gnu.org/software/sed/) and [GNU grep](https://www.gnu.org/software/grep/) are required for scripted command-line output processing +- [Python](https://www.python.org/) required to run Git hooks +- [`jq`](https://jqlang.github.io/jq/) a lightweight and flexible command-line JSON processor ### Configuration -Installation and configuration of the toolchain dependencies +Install and configure toolchain dependencies: ```shell make config @@ -85,54 +98,62 @@ make config ## Usage -After a successful installation, provide an informative example of how this project can be used. Additional code snippets, screenshots and demos work well in this space. You may also link to the other documentation resources, e.g. the [User Guide](./docs/user-guide.md) to demonstrate more use cases and to show more features. - ### Testing -There are `make` tasks for you to configure to run your tests. Run `make test` to see how they work. You should be able to use the same entry points for local development as in your CI pipeline. +Run unit tests for Lambda functions: -## Design +```shell +npm test +``` -### Diagrams +## Infrastructure -The [C4 model](https://c4model.com/) is a simple and intuitive way to create software architecture diagrams that are clear, consistent, scalable and most importantly collaborative. This should result in documenting all the system interfaces, external dependencies and integration points. +Infrastructure is managed with Terraform under `infrastructure/terraform/`: -![Repository Template](./docs/diagrams/Repository_Template_GitHub_Generic.png) +- `components/`: Terraform components for different environments/accounts +- `modules/`: Reusable Terraform modules for callback infrastructure -The source for diagrams should be in Git for change control and review purposes. Recommendations are [draw.io](https://app.diagrams.net/) (example above in [docs](.docs/diagrams/) folder) and [Mermaids](https://github.com/mermaid-js/mermaid). Here is an example Mermaids sequence diagram: +**Deploy infrastructure**: -```mermaid -sequenceDiagram - User->>+Service: GET /users?params=... - Service->>Service: auth request - Service->>Database: get all users - Database-->>Service: list of users - Service->>Service: filter users - Service-->>-User: list[User] +```shell +cd infrastructure/terraform/components/ +terraform init +terraform plan +terraform apply ``` -### Modularity +Key infrastructure modules: -Most of the projects are built with customisability and extendability in mind. At a minimum, this can be achieved by implementing service level configuration options and settings. The intention of this section is to show how this can be used. If the system processes data, you could mention here for example how the input is prepared for testing - anonymised, synthetic or live data. +- **callback-event-queue**: SQS queue and EventBridge Target Rule for Shared Event Bus subscription +- **transform-filter-lambda**: Lambda function with EventBridge Pipe trigger +- **callbacks-event-bus**: Domain-specific EventBridge bus +- **api-destinations**: Per-client API Destination Target Rules +- **client-config-storage**: S3 bucket for subscription configurations ## Contributing -Describe or link templates on how to raise an issue, feature request or make a contribution to the codebase. Reference the other documentation files, like +Contributions should follow the NHS Notify development standards: + +- See [AGENTS.md](./AGENTS.md) for AI-assisted development guidelines +- Follow existing patterns for Lambda functions and Terraform modules +- Include tests for new functionality +- Update documentation for infrastructure or configuration changes -- Environment setup for contribution, i.e. `CONTRIBUTING.md` -- Coding standards, branching, linting, practices for development and testing -- Release process, versioning, changelog -- Backlog, board, roadmap, ways of working -- High-level requirements, guiding principles, decision records, etc. +Key development practices: + +- **Branching**: Feature branches from `main` with descriptive names (e.g., `feature/CCM-XXXXX-description`) +- **Testing**: Unit tests required for Lambda functions; integration tests for event flow +- **Logging**: Use structured JSON logging with correlation IDs +- **Infrastructure**: All infrastructure changes via Terraform with peer review +- **Event Schema**: Follow NHS Notify CloudEvents specification from `nhs-notify-standards` repository ## Contacts -Provide a way to contact the owners of this project. It can be a team, an individual or information on the means of getting in touch via active communication channels, e.g. opening a GitHub discussion, raising an issue, etc. +- [Tim Marston](https://github.com/cgitim) - Lead Developer +- [Mike Wild](https://github.com/mjewildnhs) - Developer ## Licence -> The [LICENCE.md](./LICENCE.md) file will need to be updated with the correct year and owner - Unless stated otherwise, the codebase is released under the MIT License. This covers both the codebase and any sample code in the documentation. Any HTML or Markdown documentation is [© Crown Copyright](https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/) and available under the terms of the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). diff --git a/scripts/config/vale/styles/config/vocabularies/words/accept.txt b/scripts/config/vale/styles/config/vocabularies/words/accept.txt index b3cb4bc..e8c5758 100644 --- a/scripts/config/vale/styles/config/vocabularies/words/accept.txt +++ b/scripts/config/vale/styles/config/vocabularies/words/accept.txt @@ -1,9 +1,9 @@ -[A-Z]+s ajv +[A-Z]+s Bitwarden bot -Cognito [Cc]onfig +Cognito Cyber Dependabot dev