skuba 11.1.0-jest30-20250620003740 → 11.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli/migrate/nodeVersion/index.js +18 -18
- package/lib/cli/migrate/nodeVersion/index.js.map +2 -2
- package/package.json +15 -15
- package/template/express-rest-api/.buildkite/pipeline.yml +1 -1
- package/template/express-rest-api/Dockerfile.dev-deps +1 -1
- package/template/express-rest-api/package.json +1 -1
- package/template/greeter/.buildkite/pipeline.yml +1 -1
- package/template/greeter/Dockerfile +1 -1
- package/template/greeter/package.json +2 -2
- package/template/koa-rest-api/.buildkite/pipeline.yml +1 -1
- package/template/koa-rest-api/Dockerfile.dev-deps +1 -1
- package/template/koa-rest-api/package.json +7 -7
- package/template/koa-rest-api/src/api/jobs/postJob.test.ts +1 -1
- package/template/koa-rest-api/src/config.ts +1 -1
- package/template/koa-rest-api/src/framework/logging.ts +21 -12
- package/template/koa-rest-api/src/framework/server.test.ts +91 -60
- package/template/koa-rest-api/src/framework/validation.test.ts +31 -31
- package/template/koa-rest-api/src/framework/validation.ts +14 -21
- package/template/koa-rest-api/src/testing/types.ts +1 -1
- package/template/koa-rest-api/src/types/jobs.ts +1 -1
- package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -2
- package/template/lambda-sqs-worker-cdk/Dockerfile +1 -1
- package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +6 -0
- package/template/lambda-sqs-worker-cdk/package.json +5 -5
- package/template/lambda-sqs-worker-cdk/src/app.test.ts +76 -17
- package/template/lambda-sqs-worker-cdk/src/config.ts +1 -1
- package/template/lambda-sqs-worker-cdk/src/framework/handler.test.ts +35 -15
- package/template/lambda-sqs-worker-cdk/src/framework/logging.ts +22 -11
- package/template/lambda-sqs-worker-cdk/src/framework/validation.test.ts +6 -9
- package/template/lambda-sqs-worker-cdk/src/framework/validation.ts +3 -7
- package/template/lambda-sqs-worker-cdk/src/testing/types.ts +1 -1
- package/template/lambda-sqs-worker-cdk/src/types/jobScorer.ts +1 -1
- package/template/lambda-sqs-worker-cdk/src/types/pipelineEvents.ts +1 -1
- package/template/koa-rest-api/src/testing/logging.ts +0 -16
- package/template/lambda-sqs-worker-cdk/src/testing/logging.ts +0 -19
|
@@ -45,83 +45,83 @@ const subPatches = ({
|
|
|
45
45
|
` },
|
|
46
46
|
{
|
|
47
47
|
files: "**/Dockerfile*",
|
|
48
|
-
regex: /^FROM(.*) (public.ecr.aws\/docker\/library\/)?node:([0-9]+(?:\.[0-9]+(?:\.[0-9]+)?)?)(-[a-z0-9]+)?(@sha256:[a-f0-9]{64})?( .*)?$/gm,
|
|
48
|
+
regex: () => /^FROM(.*) (public.ecr.aws\/docker\/library\/)?node:([0-9]+(?:\.[0-9]+(?:\.[0-9]+)?)?)(-[a-z0-9]+)?(@sha256:[a-f0-9]{64})?( .*)?$/gm,
|
|
49
49
|
replace: `FROM$1 $2node:${nodeVersion}$4$6`
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
files: "**/Dockerfile*",
|
|
53
|
-
regex: /^FROM(.*) gcr.io\/distroless\/nodejs\d+-debian(\d+)(@sha256:[a-f0-9]{64})?(\.[^- \n]+)?(-[^ \n]+)?( .+|)$/gm,
|
|
53
|
+
regex: () => /^FROM(.*) gcr.io\/distroless\/nodejs\d+-debian(\d+)(@sha256:[a-f0-9]{64})?(\.[^- \n]+)?(-[^ \n]+)?( .+|)$/gm,
|
|
54
54
|
replace: `FROM$1 gcr.io/distroless/nodejs${nodeVersion}-debian$2$4$5$6`
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
files: "**/serverless*.y*ml",
|
|
58
|
-
regex: /\bnodejs\d+.x\b/gm,
|
|
58
|
+
regex: () => /\bnodejs\d+.x\b/gm,
|
|
59
59
|
tests: [import_checks.isPatchableServerlessVersion],
|
|
60
60
|
replace: `nodejs${nodeVersion}.x`
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
files: "**/serverless*.y*ml",
|
|
64
|
-
regex: /\bnode\d+\b/gm,
|
|
64
|
+
regex: () => /\bnode\d+\b/gm,
|
|
65
65
|
tests: [import_checks.isPatchableServerlessVersion],
|
|
66
66
|
replace: `node${nodeVersion}`
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
69
|
files: "**/infra/**/*.ts",
|
|
70
|
-
regex: /NODEJS_\d+_X/g,
|
|
70
|
+
regex: () => /NODEJS_\d+_X/g,
|
|
71
71
|
replace: `NODEJS_${nodeVersion}_X`
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
74
|
files: "**/infra/**/*.ts",
|
|
75
|
-
regex: /(target:\s*'node)(\d+)(.+)$/gm,
|
|
75
|
+
regex: () => /(target:\s*'node)(\d+)(.+)$/gm,
|
|
76
76
|
replace: `$1${nodeVersion}$3`
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
files: "**/.buildkite/*",
|
|
80
|
-
regex: /(image: )(public.ecr.aws\/docker\/library\/)?(node:)[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
|
|
80
|
+
regex: () => /(image: )(public.ecr.aws\/docker\/library\/)?(node:)[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
|
|
81
81
|
replace: `$1$2$3${nodeVersion}$5`
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
files: ".node-version*",
|
|
85
|
-
regex: /(\d+(?:\.\d+)*)/g,
|
|
85
|
+
regex: () => /(\d+(?:\.\d+)*)/g,
|
|
86
86
|
replace: `${nodeVersion}`
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
files: "**/package.json",
|
|
90
|
-
regex: /(["']engines["']:\s*{[\s\S]*?["']node["']:\s*["']>=)(\d+(?:\.\d+)*)(['"]\s*})/gm,
|
|
90
|
+
regex: () => /(["']engines["']:\s*{[\s\S]*?["']node["']:\s*["']>=)(\d+(?:\.\d+)*)(['"]\s*})/gm,
|
|
91
91
|
tests: [import_checks.isPatchableServerlessVersion, import_checks.isPatchableSkubaType],
|
|
92
92
|
replace: `$1${nodeVersion}$3`
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
95
|
files: "**/tsconfig*.json",
|
|
96
|
-
regex: /("target":\s*")(ES\d+)"/gim,
|
|
96
|
+
regex: () => /("target":\s*")(ES\d+)"/gim,
|
|
97
97
|
tests: [import_checks.isPatchableServerlessVersion, import_checks.isPatchableSkubaType],
|
|
98
98
|
replace: `$1${ECMAScriptVersion}"`
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
101
|
files: "**/tsconfig*.json",
|
|
102
|
-
regex: /("lib":\s*\[)([\S\s]*?)(ES\d+)([\S\s]*?)(\])/gim,
|
|
102
|
+
regex: () => /("lib":\s*\[)([\S\s]*?)(ES\d+)([\S\s]*?)(\])/gim,
|
|
103
103
|
tests: [import_checks.isPatchableServerlessVersion, import_checks.isPatchableSkubaType],
|
|
104
104
|
replace: `$1$2${ECMAScriptVersion}$4$5`
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
files: "**/docker-compose*.y*ml",
|
|
108
|
-
regex: /(image: )(public.ecr.aws\/docker\/library\/)?(node:)[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
|
|
108
|
+
regex: () => /(image: )(public.ecr.aws\/docker\/library\/)?(node:)[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
|
|
109
109
|
replace: `$1$2$3${nodeVersion}$5`
|
|
110
110
|
}
|
|
111
111
|
];
|
|
112
112
|
const runSubPatch = async (dir, patch) => {
|
|
113
113
|
const readFile = (0, import_project.createDestinationFileReader)(dir);
|
|
114
|
-
const paths = patch.file ? [patch.file] : await (0, import_fast_glob.glob)(patch.files ?? [], {
|
|
114
|
+
const paths = patch.file ? [patch.file] : await (0, import_fast_glob.glob)(patch.files ?? [], {
|
|
115
|
+
cwd: dir,
|
|
116
|
+
ignore: ["**/node_modules/**"]
|
|
117
|
+
});
|
|
115
118
|
await Promise.all(
|
|
116
119
|
paths.map(async (path) => {
|
|
117
|
-
if (path.includes("node_modules")) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
120
|
const contents = await readFile(path);
|
|
121
121
|
if (!contents) {
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
|
-
if (patch.regex && !patch.regex.test(contents)) {
|
|
124
|
+
if (patch.regex && !patch.regex().test(contents)) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
if (patch.tests) {
|
|
@@ -148,7 +148,7 @@ const writePatchedContents = async ({
|
|
|
148
148
|
regex
|
|
149
149
|
}) => await import_fs_extra.default.promises.writeFile(
|
|
150
150
|
path,
|
|
151
|
-
regex ? contents.replaceAll(regex, templated) : templated
|
|
151
|
+
regex ? contents.replaceAll(regex(), templated) : templated
|
|
152
152
|
);
|
|
153
153
|
const upgrade = async (versions, dir) => {
|
|
154
154
|
for (const subPatch of subPatches(versions)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/migrate/nodeVersion/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { inspect } from 'util';\n\nimport { glob } from 'fast-glob';\nimport fs from 'fs-extra';\n\nimport { log } from '../../../utils/logging';\nimport { createDestinationFileReader } from '../../configure/analysis/project';\n\nimport {\n isPatchableNodeVersion,\n isPatchableServerlessVersion,\n isPatchableSkubaType,\n} from './checks';\n\ntype FileSelector =\n | { files: string; file?: never }\n | { file: string; files?: never };\n\ntype SubPatch = FileSelector & {\n tests?: Array<(path: string) => Promise<boolean>>;\n regex?: RegExp;\n replace: string;\n};\n\nconst subPatches = ({\n nodeVersion,\n ECMAScriptVersion,\n}: Versions): SubPatch[] => [\n { file: '.nvmrc', replace: `${nodeVersion}\\n` },\n {\n files: '**/Dockerfile*',\n\n regex
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAqB;AACrB,sBAAe;AAEf,qBAAoB;AACpB,qBAA4C;AAE5C,oBAIO;AAYP,MAAM,aAAa,CAAC;AAAA,EAClB;AAAA,EACA;AACF,MAA4B;AAAA,EAC1B,EAAE,MAAM,UAAU,SAAS,GAAG,WAAW;AAAA,EAAK;AAAA,EAC9C;AAAA,IACE,OAAO;AAAA,IAEP,
|
|
4
|
+
"sourcesContent": ["import { inspect } from 'util';\n\nimport { glob } from 'fast-glob';\nimport fs from 'fs-extra';\n\nimport { log } from '../../../utils/logging';\nimport { createDestinationFileReader } from '../../configure/analysis/project';\n\nimport {\n isPatchableNodeVersion,\n isPatchableServerlessVersion,\n isPatchableSkubaType,\n} from './checks';\n\ntype FileSelector =\n | { files: string; file?: never }\n | { file: string; files?: never };\n\ntype SubPatch = FileSelector & {\n tests?: Array<(path: string) => Promise<boolean>>;\n regex?: () => RegExp;\n replace: string;\n};\n\nconst subPatches = ({\n nodeVersion,\n ECMAScriptVersion,\n}: Versions): SubPatch[] => [\n { file: '.nvmrc', replace: `${nodeVersion}\\n` },\n {\n files: '**/Dockerfile*',\n\n regex: () =>\n /^FROM(.*) (public.ecr.aws\\/docker\\/library\\/)?node:([0-9]+(?:\\.[0-9]+(?:\\.[0-9]+)?)?)(-[a-z0-9]+)?(@sha256:[a-f0-9]{64})?( .*)?$/gm,\n replace: `FROM$1 $2node:${nodeVersion}$4$6`,\n },\n {\n files: '**/Dockerfile*',\n regex: () =>\n /^FROM(.*) gcr.io\\/distroless\\/nodejs\\d+-debian(\\d+)(@sha256:[a-f0-9]{64})?(\\.[^- \\n]+)?(-[^ \\n]+)?( .+|)$/gm,\n replace: `FROM$1 gcr.io/distroless/nodejs${nodeVersion}-debian$2$4$5$6`,\n },\n\n {\n files: '**/serverless*.y*ml',\n regex: () => /\\bnodejs\\d+.x\\b/gm,\n tests: [isPatchableServerlessVersion],\n replace: `nodejs${nodeVersion}.x`,\n },\n {\n files: '**/serverless*.y*ml',\n regex: () => /\\bnode\\d+\\b/gm,\n tests: [isPatchableServerlessVersion],\n replace: `node${nodeVersion}`,\n },\n\n {\n files: '**/infra/**/*.ts',\n regex: () => /NODEJS_\\d+_X/g,\n replace: `NODEJS_${nodeVersion}_X`,\n },\n {\n files: '**/infra/**/*.ts',\n regex: () => /(target:\\s*'node)(\\d+)(.+)$/gm,\n replace: `$1${nodeVersion}$3`,\n },\n\n {\n files: '**/.buildkite/*',\n regex: () =>\n /(image: )(public.ecr.aws\\/docker\\/library\\/)?(node:)[0-9.]+(\\.[^- \\n]+)?(-[^ \\n]+)?$/gm,\n replace: `$1$2$3${nodeVersion}$5`,\n },\n {\n files: '.node-version*',\n regex: () => /(\\d+(?:\\.\\d+)*)/g,\n replace: `${nodeVersion}`,\n },\n\n {\n files: '**/package.json',\n regex: () =>\n /([\"']engines[\"']:\\s*{[\\s\\S]*?[\"']node[\"']:\\s*[\"']>=)(\\d+(?:\\.\\d+)*)(['\"]\\s*})/gm,\n tests: [isPatchableServerlessVersion, isPatchableSkubaType],\n replace: `$1${nodeVersion}$3`,\n },\n\n {\n files: '**/tsconfig*.json',\n regex: () => /(\"target\":\\s*\")(ES\\d+)\"/gim,\n tests: [isPatchableServerlessVersion, isPatchableSkubaType],\n replace: `$1${ECMAScriptVersion}\"`,\n },\n {\n files: '**/tsconfig*.json',\n regex: () => /(\"lib\":\\s*\\[)([\\S\\s]*?)(ES\\d+)([\\S\\s]*?)(\\])/gim,\n tests: [isPatchableServerlessVersion, isPatchableSkubaType],\n replace: `$1$2${ECMAScriptVersion}$4$5`,\n },\n\n {\n files: '**/docker-compose*.y*ml',\n regex: () =>\n /(image: )(public.ecr.aws\\/docker\\/library\\/)?(node:)[0-9.]+(\\.[^- \\n]+)?(-[^ \\n]+)?$/gm,\n\n replace: `$1$2$3${nodeVersion}$5`,\n },\n];\n\ntype Versions = {\n nodeVersion: number;\n ECMAScriptVersion: string;\n};\n\nconst runSubPatch = async (dir: string, patch: SubPatch) => {\n const readFile = createDestinationFileReader(dir);\n const paths = patch.file\n ? [patch.file]\n : await glob(patch.files ?? [], {\n cwd: dir,\n ignore: ['**/node_modules/**'],\n });\n\n await Promise.all(\n paths.map(async (path) => {\n const contents = await readFile(path);\n if (!contents) {\n return;\n }\n\n if (patch.regex && !patch.regex().test(contents)) {\n return;\n }\n\n if (patch.tests) {\n const results = await Promise.all(\n patch.tests.map((test) => test(path)),\n );\n if (!results.every(Boolean)) {\n return;\n }\n }\n\n await writePatchedContents({\n path,\n contents,\n templated: patch.replace,\n regex: patch.regex,\n });\n }),\n );\n};\n\nconst writePatchedContents = async ({\n path,\n contents,\n templated,\n regex,\n}: {\n path: string;\n contents: string;\n templated: string;\n regex?: () => RegExp;\n}) =>\n await fs.promises.writeFile(\n path,\n regex ? contents.replaceAll(regex(), templated) : templated,\n );\n\nconst upgrade = async (versions: Versions, dir: string) => {\n for (const subPatch of subPatches(versions)) {\n await runSubPatch(dir, subPatch);\n }\n};\n\nexport const nodeVersionMigration = async (\n {\n nodeVersion,\n ECMAScriptVersion,\n }: {\n nodeVersion: number;\n ECMAScriptVersion: string;\n },\n dir = process.cwd(),\n) => {\n log.ok(`Upgrading to Node.js ${nodeVersion}`);\n try {\n if (!(await isPatchableNodeVersion(nodeVersion, dir))) {\n throw new Error('Node.js version is not patchable');\n }\n\n await upgrade({ nodeVersion, ECMAScriptVersion }, dir);\n\n log.ok('Upgraded to Node.js', nodeVersion);\n } catch (error) {\n log.err('Failed to upgrade');\n log.subtle(inspect(error));\n process.exitCode = 1;\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fs"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skuba",
|
|
3
|
-
"version": "11.1.0
|
|
3
|
+
"version": "11.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "SEEK development toolkit for backend applications and packages",
|
|
6
6
|
"homepage": "https://github.com/seek-oss/skuba#readme",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@jest/types": "^30.0.0",
|
|
56
56
|
"@octokit/graphql": "^9.0.0",
|
|
57
57
|
"@octokit/graphql-schema": "^15.3.0",
|
|
58
|
-
"@octokit/rest": "^
|
|
58
|
+
"@octokit/rest": "^22.0.0",
|
|
59
59
|
"@octokit/types": "^14.0.0",
|
|
60
60
|
"@types/jest": "^30.0.0",
|
|
61
61
|
"@types/node": "^22.0.0",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"npm-run-path": "^4.0.1",
|
|
86
86
|
"npm-which": "^3.0.1",
|
|
87
87
|
"picomatch": "^4.0.0",
|
|
88
|
-
"prettier": "~3.
|
|
88
|
+
"prettier": "~3.6.0",
|
|
89
89
|
"prettier-plugin-packagejson": "^2.4.10",
|
|
90
90
|
"read-pkg-up": "^7.0.1",
|
|
91
91
|
"semantic-release": "^24.2.3",
|
|
@@ -97,37 +97,37 @@
|
|
|
97
97
|
"tsconfig-seek": "2.0.0",
|
|
98
98
|
"tsx": "^4.16.2",
|
|
99
99
|
"typescript": "~5.8.0",
|
|
100
|
-
"zod": "^3.
|
|
101
|
-
"eslint-config-skuba": "6.1.
|
|
100
|
+
"zod": "^3.25.67",
|
|
101
|
+
"eslint-config-skuba": "6.1.1"
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
|
-
"@changesets/cli": "2.29.
|
|
104
|
+
"@changesets/cli": "2.29.5",
|
|
105
105
|
"@changesets/get-github-info": "0.6.0",
|
|
106
106
|
"@jest/reporters": "30.0.2",
|
|
107
107
|
"@jest/test-result": "30.0.2",
|
|
108
108
|
"@types/ejs": "3.1.5",
|
|
109
|
-
"@types/express": "5.0.
|
|
109
|
+
"@types/express": "5.0.3",
|
|
110
110
|
"@types/fs-extra": "11.0.4",
|
|
111
111
|
"@types/koa": "2.15.0",
|
|
112
112
|
"@types/lodash.mergewith": "4.6.9",
|
|
113
113
|
"@types/minimist": "1.2.5",
|
|
114
114
|
"@types/module-alias": "2.0.4",
|
|
115
|
-
"@types/npm-registry-fetch": "8.0.
|
|
116
|
-
"@types/npm-which": "3.0.
|
|
115
|
+
"@types/npm-registry-fetch": "8.0.8",
|
|
116
|
+
"@types/npm-which": "3.0.4",
|
|
117
117
|
"@types/picomatch": "4.0.0",
|
|
118
118
|
"@types/semver": "7.7.0",
|
|
119
119
|
"@types/supertest": "6.0.3",
|
|
120
|
-
"enhanced-resolve": "5.18.
|
|
120
|
+
"enhanced-resolve": "5.18.2",
|
|
121
121
|
"express": "5.1.0",
|
|
122
|
-
"fastify": "5.
|
|
123
|
-
"jest-diff": "30.0.
|
|
122
|
+
"fastify": "5.4.0",
|
|
123
|
+
"jest-diff": "30.0.3",
|
|
124
124
|
"jsonfile": "6.1.0",
|
|
125
125
|
"koa": "3.0.0",
|
|
126
|
-
"memfs": "4.17.
|
|
126
|
+
"memfs": "4.17.2",
|
|
127
127
|
"remark-cli": "12.0.1",
|
|
128
128
|
"remark-preset-lint-recommended": "7.0.1",
|
|
129
|
-
"semver": "7.7.
|
|
130
|
-
"supertest": "7.1.
|
|
129
|
+
"semver": "7.7.2",
|
|
130
|
+
"supertest": "7.1.1",
|
|
131
131
|
"type-fest": "2.19.0"
|
|
132
132
|
},
|
|
133
133
|
"peerDependencies": {
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
"test:watch": "skuba test --watch"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@koa/bodyparser": "^
|
|
16
|
+
"@koa/bodyparser": "^6.0.0",
|
|
17
17
|
"@koa/router": "^13.0.0",
|
|
18
18
|
"@opentelemetry/api": "^1.9.0",
|
|
19
19
|
"@opentelemetry/core": "^2.0.0",
|
|
20
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "^0.
|
|
21
|
-
"@opentelemetry/instrumentation-aws-sdk": "^0.
|
|
22
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
20
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "^0.202.0",
|
|
21
|
+
"@opentelemetry/instrumentation-aws-sdk": "^0.54.0",
|
|
22
|
+
"@opentelemetry/instrumentation-http": "^0.202.0",
|
|
23
23
|
"@opentelemetry/propagator-b3": "^2.0.0",
|
|
24
|
-
"@opentelemetry/sdk-node": "^0.
|
|
24
|
+
"@opentelemetry/sdk-node": "^0.202.0",
|
|
25
25
|
"@seek/logger": "^10.0.0",
|
|
26
26
|
"hot-shots": "^10.0.0",
|
|
27
27
|
"koa": "^2.16.1",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"seek-datadog-custom-metrics": "^4.6.3",
|
|
30
30
|
"seek-koala": "^7.0.0",
|
|
31
31
|
"skuba-dive": "^2.0.0",
|
|
32
|
-
"zod": "^3.
|
|
32
|
+
"zod": "^3.25.67"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/chance": "^1.1.3",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"skuba": "*",
|
|
45
45
|
"supertest": "^7.0.0"
|
|
46
46
|
},
|
|
47
|
-
"packageManager": "pnpm@10.12.
|
|
47
|
+
"packageManager": "pnpm@10.12.4",
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=22"
|
|
50
50
|
}
|
|
@@ -27,7 +27,7 @@ describe('postJobHandler', () => {
|
|
|
27
27
|
.expect(422)
|
|
28
28
|
.expect(({ text }) =>
|
|
29
29
|
expect(text).toMatchInlineSnapshot(
|
|
30
|
-
`"{"message":"Input validation failed","invalidFields":{"/hirer":"
|
|
30
|
+
`"{"message":"Input validation failed","invalidFields":{"/hirer":"Invalid input: expected object, received undefined"}}"`,
|
|
31
31
|
),
|
|
32
32
|
);
|
|
33
33
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import createLogger from '@seek/logger';
|
|
1
|
+
import createLogger, { createDestination } from '@seek/logger';
|
|
2
2
|
import { RequestLogging } from 'seek-koala';
|
|
3
3
|
|
|
4
4
|
import { config } from 'src/config';
|
|
@@ -8,18 +8,27 @@ const { createContextMiddleware, mixin } =
|
|
|
8
8
|
|
|
9
9
|
export const contextMiddleware = createContextMiddleware();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
version: config.version,
|
|
15
|
-
},
|
|
11
|
+
const { destination, stdoutMock } = createDestination({
|
|
12
|
+
mock: config.environment === 'test',
|
|
13
|
+
});
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
export { stdoutMock };
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
export const logger = createLogger(
|
|
18
|
+
{
|
|
19
|
+
base: {
|
|
20
|
+
environment: config.environment,
|
|
21
|
+
version: config.version,
|
|
22
|
+
},
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
mixin,
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
level: config.logLevel,
|
|
27
|
+
|
|
28
|
+
name: config.name,
|
|
29
|
+
|
|
30
|
+
transport:
|
|
31
|
+
config.environment === 'local' ? { target: 'pino-pretty' } : undefined,
|
|
32
|
+
},
|
|
33
|
+
destination,
|
|
34
|
+
);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import Router from '@koa/router';
|
|
2
2
|
|
|
3
|
-
import { logger } from 'src/testing/logging';
|
|
4
3
|
import { metricsClient } from 'src/testing/metrics';
|
|
5
4
|
import { agentFromRouter } from 'src/testing/server';
|
|
6
5
|
import { chance } from 'src/testing/types';
|
|
7
6
|
import type { Middleware } from 'src/types/koa';
|
|
8
7
|
|
|
8
|
+
import { stdoutMock } from './logging';
|
|
9
|
+
|
|
9
10
|
const middleware = jest.fn<void, Parameters<Middleware>>();
|
|
10
11
|
|
|
11
12
|
const router = new Router()
|
|
@@ -15,10 +16,10 @@ const router = new Router()
|
|
|
15
16
|
const agent = agentFromRouter(router);
|
|
16
17
|
|
|
17
18
|
describe('createApp', () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
metricsClient.clear();
|
|
21
|
+
stdoutMock.clear();
|
|
22
|
+
});
|
|
22
23
|
|
|
23
24
|
it('handles root route', async () => {
|
|
24
25
|
middleware.mockImplementation((ctx) => (ctx.body = ''));
|
|
@@ -29,9 +30,7 @@ describe('createApp', () => {
|
|
|
29
30
|
.expect('server', /.+/)
|
|
30
31
|
.expect('x-api-version', /.+/);
|
|
31
32
|
|
|
32
|
-
expect(
|
|
33
|
-
|
|
34
|
-
expect(logger.info).not.toHaveBeenCalled();
|
|
33
|
+
expect(stdoutMock.calls).toHaveLength(0);
|
|
35
34
|
|
|
36
35
|
metricsClient.expectTagSubset(['env:test', 'version:test']);
|
|
37
36
|
metricsClient.expectTagSubset([
|
|
@@ -51,9 +50,7 @@ describe('createApp', () => {
|
|
|
51
50
|
.expect('server', /.+/)
|
|
52
51
|
.expect('x-api-version', /.+/);
|
|
53
52
|
|
|
54
|
-
expect(
|
|
55
|
-
|
|
56
|
-
expect(logger.info).not.toHaveBeenCalled();
|
|
53
|
+
expect(stdoutMock.calls).toHaveLength(0);
|
|
57
54
|
|
|
58
55
|
metricsClient.expectTagSubset([
|
|
59
56
|
'http_method:put',
|
|
@@ -72,13 +69,15 @@ describe('createApp', () => {
|
|
|
72
69
|
.expect('server', /.+/)
|
|
73
70
|
.expect('x-api-version', /.+/);
|
|
74
71
|
|
|
75
|
-
expect(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
72
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
73
|
+
{
|
|
74
|
+
level: 30,
|
|
75
|
+
method: 'GET',
|
|
76
|
+
msg: 'Client error',
|
|
77
|
+
status: 404,
|
|
78
|
+
url: '/unknown',
|
|
79
|
+
},
|
|
80
|
+
]);
|
|
82
81
|
|
|
83
82
|
metricsClient.expectTagSubset([
|
|
84
83
|
'http_method:get',
|
|
@@ -102,13 +101,16 @@ describe('createApp', () => {
|
|
|
102
101
|
.expect('server', /.+/)
|
|
103
102
|
.expect('x-api-version', /.+/);
|
|
104
103
|
|
|
105
|
-
expect(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
105
|
+
{
|
|
106
|
+
level: 30,
|
|
107
|
+
method: 'GET',
|
|
108
|
+
msg: 'Client error',
|
|
109
|
+
route: '/',
|
|
110
|
+
status: 400,
|
|
111
|
+
url: '/',
|
|
112
|
+
},
|
|
113
|
+
]);
|
|
112
114
|
|
|
113
115
|
metricsClient.expectTagSubset([
|
|
114
116
|
'http_method:get',
|
|
@@ -129,13 +131,20 @@ describe('createApp', () => {
|
|
|
129
131
|
.expect('server', /.+/)
|
|
130
132
|
.expect('x-api-version', /.+/);
|
|
131
133
|
|
|
132
|
-
expect(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
135
|
+
{
|
|
136
|
+
err: {
|
|
137
|
+
statusCode: 400,
|
|
138
|
+
type: 'BadRequestError',
|
|
139
|
+
},
|
|
140
|
+
level: 30,
|
|
141
|
+
method: 'GET',
|
|
142
|
+
msg: 'Client error',
|
|
143
|
+
route: '/',
|
|
144
|
+
status: 400,
|
|
145
|
+
url: '/',
|
|
146
|
+
},
|
|
147
|
+
]);
|
|
139
148
|
|
|
140
149
|
metricsClient.expectTagSubset([
|
|
141
150
|
'http_method:get',
|
|
@@ -156,13 +165,20 @@ describe('createApp', () => {
|
|
|
156
165
|
.expect('server', /.+/)
|
|
157
166
|
.expect('x-api-version', /.+/);
|
|
158
167
|
|
|
159
|
-
expect(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
169
|
+
{
|
|
170
|
+
err: {
|
|
171
|
+
statusCode: 500,
|
|
172
|
+
type: 'InternalServerError',
|
|
173
|
+
},
|
|
174
|
+
level: 50,
|
|
175
|
+
method: 'GET',
|
|
176
|
+
msg: 'Server error',
|
|
177
|
+
route: '/',
|
|
178
|
+
status: 500,
|
|
179
|
+
url: '/',
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
166
182
|
|
|
167
183
|
metricsClient.expectTagSubset([
|
|
168
184
|
'http_method:get',
|
|
@@ -185,13 +201,20 @@ describe('createApp', () => {
|
|
|
185
201
|
.expect('server', /.+/)
|
|
186
202
|
.expect('x-api-version', /.+/);
|
|
187
203
|
|
|
188
|
-
expect(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
205
|
+
{
|
|
206
|
+
err: {
|
|
207
|
+
message: err.message,
|
|
208
|
+
type: 'Error',
|
|
209
|
+
},
|
|
210
|
+
level: 50,
|
|
211
|
+
method: 'GET',
|
|
212
|
+
msg: 'Server error',
|
|
213
|
+
route: '/',
|
|
214
|
+
status: 500,
|
|
215
|
+
url: '/',
|
|
216
|
+
},
|
|
217
|
+
]);
|
|
195
218
|
|
|
196
219
|
metricsClient.expectTagSubset([
|
|
197
220
|
'http_method:get',
|
|
@@ -212,13 +235,17 @@ describe('createApp', () => {
|
|
|
212
235
|
.expect('server', /.+/)
|
|
213
236
|
.expect('x-api-version', /.+/);
|
|
214
237
|
|
|
215
|
-
expect(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
238
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
239
|
+
{
|
|
240
|
+
err: null,
|
|
241
|
+
level: 50,
|
|
242
|
+
method: 'GET',
|
|
243
|
+
msg: 'Server error',
|
|
244
|
+
route: '/',
|
|
245
|
+
status: 500,
|
|
246
|
+
url: '/',
|
|
247
|
+
},
|
|
248
|
+
]);
|
|
222
249
|
|
|
223
250
|
metricsClient.expectTagSubset([
|
|
224
251
|
'http_method:get',
|
|
@@ -241,13 +268,17 @@ describe('createApp', () => {
|
|
|
241
268
|
.expect('server', /.+/)
|
|
242
269
|
.expect('x-api-version', /.+/);
|
|
243
270
|
|
|
244
|
-
expect(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
271
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
272
|
+
{
|
|
273
|
+
err,
|
|
274
|
+
level: 50,
|
|
275
|
+
method: 'GET',
|
|
276
|
+
msg: 'Server error',
|
|
277
|
+
route: '/',
|
|
278
|
+
status: 500,
|
|
279
|
+
url: '/',
|
|
280
|
+
},
|
|
281
|
+
]);
|
|
251
282
|
|
|
252
283
|
metricsClient.expectTagSubset([
|
|
253
284
|
'http_method:get',
|