skuba 12.0.0-enforce-file-extensions-20250618112549 → 12.0.0-subpath-imports-20250710043319

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.
Files changed (101) hide show
  1. package/config/tsconfig.json +4 -3
  2. package/jest/transform.js +1 -15
  3. package/jest-preset.js +4 -7
  4. package/lib/cli/buildPackage/index.js +2 -2
  5. package/lib/cli/buildPackage/index.js.map +1 -1
  6. package/lib/cli/configure/ensureTemplateCompletion.js +1 -1
  7. package/lib/cli/configure/ensureTemplateCompletion.js.map +2 -2
  8. package/lib/cli/configure/processing/prettier.d.ts +1 -1
  9. package/lib/cli/configure/processing/prettier.js +8 -6
  10. package/lib/cli/configure/processing/prettier.js.map +3 -3
  11. package/lib/cli/init/getConfig.d.ts +1 -1
  12. package/lib/cli/init/getConfig.js +7 -5
  13. package/lib/cli/init/getConfig.js.map +3 -3
  14. package/lib/cli/init/prompts.d.ts +5 -5
  15. package/lib/cli/init/prompts.js +5 -4
  16. package/lib/cli/init/prompts.js.map +3 -3
  17. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/index.d.ts +2 -0
  18. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/index.js +35 -0
  19. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/index.js.map +7 -0
  20. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/rewriteSrcImports.d.ts +6 -0
  21. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/rewriteSrcImports.js +104 -0
  22. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/rewriteSrcImports.js.map +7 -0
  23. package/lib/cli/migrate/nodeVersion/index.js +18 -18
  24. package/lib/cli/migrate/nodeVersion/index.js.map +2 -2
  25. package/package.json +32 -25
  26. package/template/base/_.prettierrc.js +1 -1
  27. package/template/base/_eslint.config.js +1 -1
  28. package/template/base/_pnpm-workspace.yaml +1 -0
  29. package/template/base/jest.config.ts +17 -3
  30. package/template/base/tsconfig.json +3 -3
  31. package/template/express-rest-api/.buildkite/pipeline.yml +1 -1
  32. package/template/express-rest-api/Dockerfile.dev-deps +1 -1
  33. package/template/express-rest-api/package.json +8 -1
  34. package/template/express-rest-api/src/app.ts +0 -2
  35. package/template/express-rest-api/src/framework/logging.ts +1 -1
  36. package/template/express-rest-api/src/framework/metrics.ts +2 -2
  37. package/template/express-rest-api/src/listen.ts +0 -2
  38. package/template/greeter/.buildkite/pipeline.yml +1 -1
  39. package/template/greeter/Dockerfile +1 -1
  40. package/template/greeter/package.json +9 -2
  41. package/template/greeter/src/app.ts +2 -2
  42. package/template/koa-rest-api/.buildkite/pipeline.yml +1 -1
  43. package/template/koa-rest-api/Dockerfile.dev-deps +1 -1
  44. package/template/koa-rest-api/package.json +14 -7
  45. package/template/koa-rest-api/src/api/healthCheck.ts +1 -1
  46. package/template/koa-rest-api/src/api/jobs/getJobs.test.ts +2 -2
  47. package/template/koa-rest-api/src/api/jobs/getJobs.ts +4 -4
  48. package/template/koa-rest-api/src/api/jobs/index.ts +2 -2
  49. package/template/koa-rest-api/src/api/jobs/postJob.test.ts +4 -4
  50. package/template/koa-rest-api/src/api/jobs/postJob.ts +6 -6
  51. package/template/koa-rest-api/src/api/smokeTest.ts +2 -2
  52. package/template/koa-rest-api/src/app.test.ts +2 -2
  53. package/template/koa-rest-api/src/app.ts +0 -2
  54. package/template/koa-rest-api/src/config.ts +1 -1
  55. package/template/koa-rest-api/src/framework/logging.ts +22 -13
  56. package/template/koa-rest-api/src/framework/metrics.ts +2 -2
  57. package/template/koa-rest-api/src/framework/server.test.ts +95 -64
  58. package/template/koa-rest-api/src/framework/server.ts +3 -3
  59. package/template/koa-rest-api/src/framework/validation.test.ts +36 -36
  60. package/template/koa-rest-api/src/framework/validation.ts +15 -22
  61. package/template/koa-rest-api/src/listen.ts +0 -2
  62. package/template/koa-rest-api/src/storage/jobs.ts +1 -1
  63. package/template/koa-rest-api/src/testing/metrics.ts +1 -1
  64. package/template/koa-rest-api/src/testing/server.ts +1 -1
  65. package/template/koa-rest-api/src/testing/types.ts +2 -2
  66. package/template/koa-rest-api/src/types/jobs.ts +1 -1
  67. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -2
  68. package/template/lambda-sqs-worker-cdk/Dockerfile +1 -1
  69. package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +6 -0
  70. package/template/lambda-sqs-worker-cdk/infra/appStack.test.ts +1 -1
  71. package/template/lambda-sqs-worker-cdk/package.json +12 -5
  72. package/template/lambda-sqs-worker-cdk/src/app.test.ts +81 -22
  73. package/template/lambda-sqs-worker-cdk/src/app.ts +7 -9
  74. package/template/lambda-sqs-worker-cdk/src/config.ts +1 -1
  75. package/template/lambda-sqs-worker-cdk/src/framework/handler.test.ts +38 -18
  76. package/template/lambda-sqs-worker-cdk/src/framework/handler.ts +2 -2
  77. package/template/lambda-sqs-worker-cdk/src/framework/logging.ts +23 -12
  78. package/template/lambda-sqs-worker-cdk/src/framework/metrics.ts +1 -1
  79. package/template/lambda-sqs-worker-cdk/src/framework/validation.test.ts +9 -12
  80. package/template/lambda-sqs-worker-cdk/src/framework/validation.ts +3 -7
  81. package/template/lambda-sqs-worker-cdk/src/services/jobScorer.test.ts +3 -3
  82. package/template/lambda-sqs-worker-cdk/src/services/jobScorer.ts +7 -6
  83. package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.test.ts +3 -3
  84. package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.ts +2 -2
  85. package/template/lambda-sqs-worker-cdk/src/testing/services.ts +2 -2
  86. package/template/lambda-sqs-worker-cdk/src/testing/types.ts +1 -1
  87. package/template/lambda-sqs-worker-cdk/src/types/jobScorer.ts +1 -1
  88. package/template/lambda-sqs-worker-cdk/src/types/pipelineEvents.ts +1 -1
  89. package/template/lambda-sqs-worker-cdk/tsconfig.json +3 -3
  90. package/template/oss-npm-package/_package.json +8 -0
  91. package/template/oss-npm-package/skuba.template.js +1 -1
  92. package/template/oss-npm-package/tsconfig.json +3 -0
  93. package/template/private-npm-package/_package.json +7 -0
  94. package/lib/cli/test/reporters/prettier/index.d.ts +0 -4
  95. package/lib/cli/test/reporters/prettier/index.js +0 -67
  96. package/lib/cli/test/reporters/prettier/index.js.map +0 -7
  97. package/template/express-rest-api/src/register.ts +0 -1
  98. package/template/koa-rest-api/src/register.ts +0 -1
  99. package/template/koa-rest-api/src/testing/logging.ts +0 -16
  100. package/template/koa-rest-api/tsconfig.json +0 -18
  101. package/template/lambda-sqs-worker-cdk/src/testing/logging.ts +0 -19
@@ -2,6 +2,13 @@
2
2
  "name": "@seek/<%- serviceName %>",
3
3
  "private": true,
4
4
  "license": "UNLICENSED",
5
+ "imports": {
6
+ "#src/*": {
7
+ "types": "./src/*",
8
+ "import": "./lib/*",
9
+ "require": "./lib/*"
10
+ }
11
+ },
5
12
  "scripts": {
6
13
  "deploy": "cdk deploy appStack --require-approval never",
7
14
  "deploy:hotswap": "pnpm --silent run deploy --hotswap",
@@ -17,15 +24,15 @@
17
24
  "@aws-sdk/client-codedeploy": "^3.363.0",
18
25
  "@aws-sdk/client-lambda": "^3.363.0",
19
26
  "@aws-sdk/client-sns": "^3.363.0",
20
- "@seek/aws-codedeploy-hooks": "^1.2.0",
27
+ "@seek/aws-codedeploy-hooks": "^2.0.0",
21
28
  "@seek/logger": "^10.0.0",
22
29
  "datadog-lambda-js": "^10.0.0",
23
30
  "dd-trace": "^5.0.0",
24
31
  "skuba-dive": "^2.0.0",
25
- "zod": "^3.19.1"
32
+ "zod": "^3.25.67"
26
33
  },
27
34
  "devDependencies": {
28
- "@seek/aws-codedeploy-infra": "^2.1.0",
35
+ "@seek/aws-codedeploy-infra": "^3.0.0",
29
36
  "@types/aws-lambda": "^8.10.82",
30
37
  "@types/chance": "^1.1.3",
31
38
  "@types/node": "^22.13.10",
@@ -37,9 +44,9 @@
37
44
  "constructs": "^10.0.17",
38
45
  "datadog-cdk-constructs-v2": "^2.0.0",
39
46
  "pino-pretty": "^13.0.0",
40
- "skuba": "12.0.0-enforce-file-extensions-20250618112549"
47
+ "skuba": "12.0.0-subpath-imports-20250710043319"
41
48
  },
42
- "packageManager": "pnpm@10.12.1",
49
+ "packageManager": "pnpm@10.12.4",
43
50
  "engines": {
44
51
  "node": ">=22"
45
52
  }
@@ -1,12 +1,12 @@
1
1
  import { PublishCommand } from '@aws-sdk/client-sns';
2
2
 
3
- import { metricsClient } from 'src/framework/metrics.js';
4
- import { createCtx, createSqsEvent } from 'src/testing/handler.js';
5
- import { logger } from 'src/testing/logging.js';
6
- import { scoringService, sns } from 'src/testing/services.js';
7
- import { chance, mockJobPublishedEvent } from 'src/testing/types.js';
8
-
9
3
  import * as app from './app.js';
4
+ import { stdoutMock } from './framework/logging.js';
5
+
6
+ import { metricsClient } from '#src/framework/metrics.js';
7
+ import { createCtx, createSqsEvent } from '#src/testing/handler.js';
8
+ import { scoringService, sns } from '#src/testing/services.js';
9
+ import { chance, mockJobPublishedEvent } from '#src/testing/types.js';
10
10
 
11
11
  describe('app', () => {
12
12
  it('exports a handler', () => expect(app).toHaveProperty('handler'));
@@ -23,7 +23,6 @@ describe('handler', () => {
23
23
  .spyOn(metricsClient, 'distribution')
24
24
  .mockReturnValue();
25
25
 
26
- beforeAll(logger.spy);
27
26
  beforeAll(scoringService.spy);
28
27
 
29
28
  beforeEach(() => {
@@ -32,7 +31,7 @@ describe('handler', () => {
32
31
  });
33
32
 
34
33
  afterEach(() => {
35
- logger.clear();
34
+ stdoutMock.clear();
36
35
  distribution.mockClear();
37
36
  scoringService.clear();
38
37
  sns.clear();
@@ -45,12 +44,24 @@ describe('handler', () => {
45
44
 
46
45
  expect(scoringService.request).toHaveBeenCalledTimes(1);
47
46
 
48
- expect(logger.error).not.toHaveBeenCalled();
49
-
50
- expect(logger.debug.mock.calls).toEqual([
51
- [{ count: 1 }, 'Received jobs'],
52
- [{ snsMessageId: expect.any(String) }, 'Scored job'],
53
- ['Function succeeded'],
47
+ expect(stdoutMock.calls).toMatchObject([
48
+ {
49
+ awsRequestId: '-',
50
+ count: 1,
51
+ level: 20,
52
+ msg: 'Received jobs',
53
+ },
54
+ {
55
+ awsRequestId: '-',
56
+ level: 20,
57
+ msg: 'Scored job',
58
+ snsMessageId: expect.any(String),
59
+ },
60
+ {
61
+ awsRequestId: '-',
62
+ level: 20,
63
+ msg: 'Function succeeded',
64
+ },
54
65
  ]);
55
66
 
56
67
  expect(distribution.mock.calls).toEqual([
@@ -76,7 +87,23 @@ describe('handler', () => {
76
87
 
77
88
  await expect(app.handler(event, ctx)).rejects.toThrow('Function failed');
78
89
 
79
- expect(logger.error).toHaveBeenCalledWith({ err }, 'Function failed');
90
+ expect(stdoutMock.calls).toMatchObject([
91
+ {
92
+ awsRequestId: '-',
93
+ count: 1,
94
+ level: 20,
95
+ msg: 'Received jobs',
96
+ },
97
+ {
98
+ awsRequestId: '-',
99
+ err: {
100
+ message: err.message,
101
+ type: 'Error',
102
+ },
103
+ level: 50,
104
+ msg: 'Function failed',
105
+ },
106
+ ]);
80
107
  });
81
108
 
82
109
  it('bubbles up SNS error', async () => {
@@ -88,22 +115,44 @@ describe('handler', () => {
88
115
 
89
116
  await expect(app.handler(event, ctx)).rejects.toThrow('Function failed');
90
117
 
91
- expect(logger.error).toHaveBeenCalledWith({ err }, 'Function failed');
118
+ expect(stdoutMock.calls).toMatchObject([
119
+ {
120
+ awsRequestId: '-',
121
+ count: 1,
122
+ level: 20,
123
+ msg: 'Received jobs',
124
+ },
125
+ {
126
+ awsRequestId: '-',
127
+ err: {
128
+ message: err.message,
129
+ type: 'Error',
130
+ },
131
+ level: 50,
132
+ msg: 'Function failed',
133
+ },
134
+ ]);
92
135
  });
93
136
 
94
137
  it('throws on zero records', async () => {
95
- const err = new Error('Received 0 records');
96
-
97
138
  const event = createSqsEvent([]);
98
139
 
99
140
  await expect(app.handler(event, ctx)).rejects.toThrow('Function failed');
100
141
 
101
- expect(logger.error).toHaveBeenCalledWith({ err }, 'Function failed');
142
+ expect(stdoutMock.calls).toMatchObject([
143
+ {
144
+ awsRequestId: '-',
145
+ err: {
146
+ message: 'Received 0 records',
147
+ type: 'Error',
148
+ },
149
+ level: 50,
150
+ msg: 'Function failed',
151
+ },
152
+ ]);
102
153
  });
103
154
 
104
155
  it('throws on multiple records', async () => {
105
- const err = new Error('Received 2 records');
106
-
107
156
  const event = createSqsEvent([
108
157
  JSON.stringify(jobPublished),
109
158
  JSON.stringify(jobPublished),
@@ -111,6 +160,16 @@ describe('handler', () => {
111
160
 
112
161
  await expect(app.handler(event, ctx)).rejects.toThrow('Function failed');
113
162
 
114
- expect(logger.error).toHaveBeenCalledWith({ err }, 'Function failed');
163
+ expect(stdoutMock.calls).toMatchObject([
164
+ {
165
+ awsRequestId: '-',
166
+ err: {
167
+ message: 'Received 2 records',
168
+ type: 'Error',
169
+ },
170
+ level: 50,
171
+ msg: 'Function failed',
172
+ },
173
+ ]);
115
174
  });
116
175
  });
@@ -1,18 +1,16 @@
1
- import 'skuba-dive/register';
2
-
3
1
  import { isLambdaHook } from '@seek/aws-codedeploy-hooks';
4
2
  import type { SQSEvent } from 'aws-lambda';
5
3
 
6
- import { createHandler } from 'src/framework/handler.js';
7
- import { logger } from 'src/framework/logging.js';
8
- import { metricsClient } from 'src/framework/metrics.js';
9
- import { validateJson } from 'src/framework/validation.js';
4
+ import { createHandler } from '#src/framework/handler.js';
5
+ import { logger } from '#src/framework/logging.js';
6
+ import { metricsClient } from '#src/framework/metrics.js';
7
+ import { validateJson } from '#src/framework/validation.js';
10
8
  import {
11
9
  scoreJobPublishedEvent,
12
10
  scoringService,
13
- } from 'src/services/jobScorer.js';
14
- import { sendPipelineEvent } from 'src/services/pipelineEventSender.js';
15
- import { JobPublishedEventSchema } from 'src/types/pipelineEvents.js';
11
+ } from '#src/services/jobScorer.js';
12
+ import { sendPipelineEvent } from '#src/services/pipelineEventSender.js';
13
+ import { JobPublishedEventSchema } from '#src/types/pipelineEvents.js';
16
14
 
17
15
  /**
18
16
  * Tests connectivity to ensure appropriate access and network configuration.
@@ -29,7 +29,7 @@ const configs: Record<Environment, () => Omit<Config, 'environment'>> = {
29
29
  }),
30
30
 
31
31
  test: () => ({
32
- logLevel: Env.string('LOG_LEVEL', { default: 'silent' }),
32
+ logLevel: Env.string('LOG_LEVEL', { default: 'debug' }),
33
33
  metrics: false,
34
34
  name: '<%- serviceName %>',
35
35
  version: 'test',
@@ -1,16 +1,14 @@
1
- import { createCtx } from 'src/testing/handler.js';
2
- import { logger } from 'src/testing/logging.js';
3
- import { chance } from 'src/testing/types.js';
4
-
5
1
  import { createHandler } from './handler.js';
2
+ import { logger, stdoutMock } from './logging.js';
3
+
4
+ import { createCtx } from '#src/testing/handler.js';
5
+ import { chance } from '#src/testing/types.js';
6
6
 
7
7
  describe('createHandler', () => {
8
8
  const ctx = createCtx();
9
9
  const input = chance.paragraph();
10
10
 
11
- beforeAll(logger.spy);
12
-
13
- afterEach(logger.clear);
11
+ afterEach(stdoutMock.clear);
14
12
 
15
13
  it('handles happy path', async () => {
16
14
  const output = chance.paragraph();
@@ -25,11 +23,17 @@ describe('createHandler', () => {
25
23
 
26
24
  await expect(handler(input, ctx)).resolves.toBe(output);
27
25
 
28
- expect(logger.error).not.toHaveBeenCalled();
29
-
30
- expect(logger.debug.mock.calls).toEqual([
31
- ['Handler invoked'],
32
- ['Function succeeded'],
26
+ expect(stdoutMock.calls).toMatchObject([
27
+ {
28
+ awsRequestId: '-',
29
+ level: 20,
30
+ msg: 'Handler invoked',
31
+ },
32
+ {
33
+ awsRequestId: '-',
34
+ level: 20,
35
+ msg: 'Function succeeded',
36
+ },
33
37
  ]);
34
38
  });
35
39
 
@@ -40,9 +44,17 @@ describe('createHandler', () => {
40
44
 
41
45
  await expect(handler(input, ctx)).rejects.toThrow('Function failed');
42
46
 
43
- expect(logger.error).toHaveBeenCalledWith({ err }, 'Function failed');
44
-
45
- expect(logger.debug).not.toHaveBeenCalled();
47
+ expect(stdoutMock.calls).toMatchObject([
48
+ {
49
+ awsRequestId: '-',
50
+ err: {
51
+ message: err.message,
52
+ type: 'Error',
53
+ },
54
+ level: 50,
55
+ msg: 'Function failed',
56
+ },
57
+ ]);
46
58
  });
47
59
 
48
60
  it('handles sync error', async () => {
@@ -54,8 +66,16 @@ describe('createHandler', () => {
54
66
 
55
67
  await expect(handler(input, ctx)).rejects.toThrow('Function failed');
56
68
 
57
- expect(logger.error).toHaveBeenCalledWith({ err }, 'Function failed');
58
-
59
- expect(logger.debug).not.toHaveBeenCalled();
69
+ expect(stdoutMock.calls).toMatchObject([
70
+ {
71
+ awsRequestId: '-',
72
+ err: {
73
+ message: err.message,
74
+ type: 'Error',
75
+ },
76
+ level: 50,
77
+ msg: 'Function failed',
78
+ },
79
+ ]);
60
80
  });
61
81
  });
@@ -1,8 +1,8 @@
1
1
  import type { Context as LambdaContext } from 'aws-lambda';
2
2
  import { datadog } from 'datadog-lambda-js';
3
3
 
4
- import { config } from 'src/config.js';
5
- import { logger, loggerContext } from 'src/framework/logging.js';
4
+ import { config } from '#src/config.js';
5
+ import { logger, loggerContext } from '#src/framework/logging.js';
6
6
 
7
7
  type Handler<Event, Output> = (
8
8
  event: Event,
@@ -1,8 +1,8 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
2
 
3
- import createLogger from '@seek/logger';
3
+ import createLogger, { createDestination } from '@seek/logger';
4
4
 
5
- import { config } from 'src/config.js';
5
+ import { config } from '#src/config.js';
6
6
 
7
7
  interface LoggerContext {
8
8
  awsRequestId: string;
@@ -10,18 +10,29 @@ interface LoggerContext {
10
10
 
11
11
  export const loggerContext = new AsyncLocalStorage<LoggerContext>();
12
12
 
13
- export const logger = createLogger({
14
- base: {
15
- environment: config.environment,
16
- version: config.version,
13
+ const { destination, stdoutMock } = createDestination({
14
+ mock: config.environment === 'test' && {
15
+ redact: ['awsRequestId'],
17
16
  },
17
+ });
18
18
 
19
- level: config.logLevel,
19
+ export { stdoutMock };
20
20
 
21
- mixin: () => ({ ...loggerContext.getStore() }),
21
+ export const logger = createLogger(
22
+ {
23
+ base: {
24
+ environment: config.environment,
25
+ version: config.version,
26
+ },
22
27
 
23
- name: config.name,
28
+ level: config.logLevel,
24
29
 
25
- transport:
26
- config.environment === 'local' ? { target: 'pino-pretty' } : undefined,
27
- });
30
+ mixin: () => ({ ...loggerContext.getStore() }),
31
+
32
+ name: config.name,
33
+
34
+ transport:
35
+ config.environment === 'local' ? { target: 'pino-pretty' } : undefined,
36
+ },
37
+ destination,
38
+ );
@@ -1,6 +1,6 @@
1
1
  import { sendDistributionMetric } from 'datadog-lambda-js';
2
2
 
3
- import { config } from 'src/config.js';
3
+ import { config } from '#src/config.js';
4
4
 
5
5
  const prefix = `${config.name}.`;
6
6
 
@@ -1,10 +1,10 @@
1
+ import { validateJson } from './validation.js';
2
+
1
3
  import {
2
4
  IdDescriptionSchema,
3
5
  chance,
4
6
  mockIdDescription,
5
- } from 'src/testing/types.js';
6
-
7
- import { validateJson } from './validation.js';
7
+ } from '#src/testing/types.js';
8
8
 
9
9
  describe('validateJson', () => {
10
10
  const idDescription = mockIdDescription();
@@ -32,13 +32,12 @@ describe('validateJson', () => {
32
32
  .toThrowErrorMatchingInlineSnapshot(`
33
33
  "[
34
34
  {
35
- "code": "invalid_type",
36
35
  "expected": "string",
37
- "received": "null",
36
+ "code": "invalid_type",
38
37
  "path": [
39
38
  "id"
40
39
  ],
41
- "message": "Expected string, received null"
40
+ "message": "Invalid input: expected string, received null"
42
41
  }
43
42
  ]"
44
43
  `);
@@ -51,22 +50,20 @@ describe('validateJson', () => {
51
50
  .toThrowErrorMatchingInlineSnapshot(`
52
51
  "[
53
52
  {
54
- "code": "invalid_type",
55
53
  "expected": "string",
56
- "received": "undefined",
54
+ "code": "invalid_type",
57
55
  "path": [
58
56
  "id"
59
57
  ],
60
- "message": "Required"
58
+ "message": "Invalid input: expected string, received undefined"
61
59
  },
62
60
  {
63
- "code": "invalid_type",
64
61
  "expected": "string",
65
- "received": "undefined",
62
+ "code": "invalid_type",
66
63
  "path": [
67
64
  "description"
68
65
  ],
69
- "message": "Required"
66
+ "message": "Invalid input: expected string, received undefined"
70
67
  }
71
68
  ]"
72
69
  `);
@@ -1,10 +1,6 @@
1
- import type { z } from 'zod';
1
+ import type { z } from 'zod/v4';
2
2
 
3
- export const validateJson = <
4
- Output,
5
- Def extends z.ZodTypeDef = z.ZodTypeDef,
6
- Input = Output,
7
- >(
3
+ export const validateJson = <Output, Input>(
8
4
  input: string,
9
- schema: z.ZodSchema<Output, Def, Input>,
5
+ schema: z.ZodSchema<Output, Input>,
10
6
  ): Output => schema.parse(JSON.parse(input));
@@ -1,8 +1,8 @@
1
- import { scoringService } from 'src/testing/services.js';
2
- import { chance, mockJobPublishedEvent } from 'src/testing/types.js';
3
-
4
1
  import * as jobScorer from './jobScorer.js';
5
2
 
3
+ import { scoringService } from '#src/testing/services.js';
4
+ import { chance, mockJobPublishedEvent } from '#src/testing/types.js';
5
+
6
6
  describe('scoreJobPublishedEvent', () => {
7
7
  beforeAll(scoringService.spy);
8
8
 
@@ -1,16 +1,17 @@
1
+ import type {
2
+ JobPublishedEvent,
3
+ JobScoredEvent,
4
+ } from 'src/types/pipelineEvents.js';
5
+
1
6
  import {
2
7
  jobPublishedEventToScorerInput,
3
8
  jobScorerOutputToScoredEvent,
4
- } from 'src/mapping/jobScorer.js';
9
+ } from '#src/mapping/jobScorer.js';
5
10
  import {
6
11
  type JobScorerInput,
7
12
  type JobScorerOutput,
8
13
  JobScorerOutputSchema,
9
- } from 'src/types/jobScorer.js';
10
- import type {
11
- JobPublishedEvent,
12
- JobScoredEvent,
13
- } from 'src/types/pipelineEvents.js';
14
+ } from '#src/types/jobScorer.js';
14
15
 
15
16
  /* istanbul ignore next: simulation of an external service */
16
17
  export const scoringService = {
@@ -1,10 +1,10 @@
1
1
  import { PublishCommand } from '@aws-sdk/client-sns';
2
2
 
3
- import { sns } from 'src/testing/services.js';
4
- import { chance } from 'src/testing/types.js';
5
-
6
3
  import { sendPipelineEvent } from './pipelineEventSender.js';
7
4
 
5
+ import { sns } from '#src/testing/services.js';
6
+ import { chance } from '#src/testing/types.js';
7
+
8
8
  describe('sendPipelineEvent', () => {
9
9
  afterEach(() => {
10
10
  jest.clearAllMocks();
@@ -1,9 +1,9 @@
1
1
  import { PublishCommand } from '@aws-sdk/client-sns';
2
2
 
3
- import { config } from 'src/config.js';
4
-
5
3
  import { sns } from './aws.js';
6
4
 
5
+ import { config } from '#src/config.js';
6
+
7
7
  export const sendPipelineEvent = async (
8
8
  event: unknown,
9
9
  smokeTest: boolean = false,
@@ -3,8 +3,8 @@ import 'aws-sdk-client-mock-jest';
3
3
  import { PublishCommand } from '@aws-sdk/client-sns';
4
4
  import { mockClient } from 'aws-sdk-client-mock';
5
5
 
6
- import { sns as snsClient } from 'src/services/aws.js';
7
- import * as jobScorer from 'src/services/jobScorer.js';
6
+ import { sns as snsClient } from '#src/services/aws.js';
7
+ import * as jobScorer from '#src/services/jobScorer.js';
8
8
 
9
9
  export const scoringService = {
10
10
  request: jest.fn(),
@@ -1,5 +1,5 @@
1
1
  import { Chance } from 'chance';
2
- import { z } from 'zod';
2
+ import { z } from 'zod/v4';
3
3
 
4
4
  import type { JobPublishedEvent } from 'src/types/pipelineEvents.js';
5
5
 
@@ -1,4 +1,4 @@
1
- import { z } from 'zod';
1
+ import { z } from 'zod/v4';
2
2
 
3
3
  export type JobScorerInput = z.infer<typeof JobScorerInputSchema>;
4
4
 
@@ -1,4 +1,4 @@
1
- import { z } from 'zod';
1
+ import { z } from 'zod/v4';
2
2
 
3
3
  export type JobPublishedEvent = z.infer<typeof JobPublishedEventSchema>;
4
4
 
@@ -2,10 +2,10 @@
2
2
  "compilerOptions": {
3
3
  "baseUrl": ".",
4
4
  "lib": ["ES2024"],
5
+ "moduleResolution": "node16",
6
+ "module": "node18",
5
7
  "outDir": "lib",
6
- "paths": {
7
- "src": ["src"]
8
- },
8
+ "rootDir": ".",
9
9
  "target": "ES2024"
10
10
  },
11
11
  "exclude": ["lib*/**/*"],
@@ -2,6 +2,14 @@
2
2
  "name": "<%- moduleName %>",
3
3
  "version": "0.0.0-semantically-released",
4
4
  "description": "<%- description %>",
5
+ "type": "module",
6
+ "imports": {
7
+ "#src/*": {
8
+ "types": "./src/*",
9
+ "import": "./lib/*",
10
+ "require": "./lib/*"
11
+ }
12
+ },
5
13
  "repository": {
6
14
  "type": "git",
7
15
  "url": "git+ssh://git@github.com/<%- orgName %>/<%- repoName %>.git"
@@ -2,7 +2,7 @@
2
2
  * Run `skuba configure` to finish templating and remove this file.
3
3
  */
4
4
 
5
- module.exports = {
5
+ export default {
6
6
  entryPoint: 'src/index.ts',
7
7
  fields: [
8
8
  {
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "lib": ["ES2022"],
4
+ "module": "node18",
5
+ "moduleResolution": "node16",
4
6
  "outDir": "lib",
5
7
  "removeComments": false,
8
+ "rootDir": ".",
6
9
  "target": "ES2022"
7
10
  },
8
11
  "exclude": ["lib*/**/*"],
@@ -2,6 +2,13 @@
2
2
  "name": "<%- moduleName %>",
3
3
  "version": "0.0.0-semantically-released",
4
4
  "description": "<%- description %>",
5
+ "imports": {
6
+ "#src/*": {
7
+ "types": "./src/*",
8
+ "import": "./lib/*",
9
+ "require": "./lib/*"
10
+ }
11
+ },
5
12
  "repository": {
6
13
  "type": "git",
7
14
  "url": "git+ssh://git@github.com/<%- orgName %>/<%- repoName %>.git"
@@ -1,4 +0,0 @@
1
- import type { Reporter } from '@jest/reporters';
2
- export default class SnapshotPrettifier implements Pick<Reporter, 'onTestFileResult'> {
3
- onTestFileResult(...[test, testResult]: Parameters<NonNullable<Reporter['onTestFileResult']>>): Promise<void>;
4
- }