skuba 12.0.0-subpath-imports-20250710043319 → 12.0.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.
Files changed (109) hide show
  1. package/config/tsconfig.json +3 -4
  2. package/lib/api/git/getChangedFiles.js +19 -2
  3. package/lib/api/git/getChangedFiles.js.map +3 -3
  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 +5 -3
  7. package/lib/cli/configure/ensureTemplateCompletion.js.map +2 -2
  8. package/lib/cli/init/getConfig.d.ts +7 -8
  9. package/lib/cli/init/getConfig.js +5 -7
  10. package/lib/cli/init/getConfig.js.map +3 -3
  11. package/lib/cli/init/prompts.d.ts +5 -5
  12. package/lib/cli/init/prompts.js +4 -5
  13. package/lib/cli/init/prompts.js.map +3 -3
  14. package/lib/cli/init/types.d.ts +13 -109
  15. package/lib/cli/init/types.js +30 -20
  16. package/lib/cli/init/types.js.map +2 -2
  17. package/lib/cli/lint/internalLints/patchRenovateConfig.js +3 -3
  18. package/lib/cli/lint/internalLints/patchRenovateConfig.js.map +2 -2
  19. package/lib/cli/migrate/nodeVersion/checks.d.ts +3 -3
  20. package/lib/cli/migrate/nodeVersion/checks.js +11 -11
  21. package/lib/cli/migrate/nodeVersion/checks.js.map +2 -2
  22. package/lib/utils/error.d.ts +3 -23
  23. package/lib/utils/error.js +18 -8
  24. package/lib/utils/error.js.map +2 -2
  25. package/lib/utils/manifest.d.ts +2 -2
  26. package/lib/utils/manifest.js +4 -4
  27. package/lib/utils/manifest.js.map +2 -2
  28. package/lib/utils/packageManager.d.ts +5 -2
  29. package/lib/utils/packageManager.js +2 -2
  30. package/lib/utils/packageManager.js.map +2 -2
  31. package/lib/utils/template.d.ts +9 -38
  32. package/lib/utils/template.js +22 -10
  33. package/lib/utils/template.js.map +2 -2
  34. package/lib/utils/version.d.ts +2 -10
  35. package/lib/utils/version.js +9 -9
  36. package/lib/utils/version.js.map +2 -2
  37. package/package.json +6 -13
  38. package/template/base/_.prettierrc.js +1 -1
  39. package/template/base/_eslint.config.js +1 -1
  40. package/template/base/_pnpm-workspace.yaml +0 -1
  41. package/template/base/jest.config.ts +3 -17
  42. package/template/base/tsconfig.json +3 -3
  43. package/template/express-rest-api/.buildkite/pipeline.yml +2 -1
  44. package/template/express-rest-api/docker-compose.yml +0 -2
  45. package/template/express-rest-api/package.json +0 -7
  46. package/template/express-rest-api/src/app.ts +2 -0
  47. package/template/express-rest-api/src/framework/logging.ts +1 -1
  48. package/template/express-rest-api/src/framework/metrics.ts +2 -2
  49. package/template/express-rest-api/src/listen.ts +2 -0
  50. package/template/express-rest-api/src/register.ts +1 -0
  51. package/template/greeter/.buildkite/pipeline.yml +2 -1
  52. package/template/greeter/docker-compose.yml +0 -2
  53. package/template/greeter/package.json +1 -8
  54. package/template/greeter/src/app.ts +2 -2
  55. package/template/koa-rest-api/.buildkite/pipeline.yml +2 -1
  56. package/template/koa-rest-api/docker-compose.yml +0 -2
  57. package/template/koa-rest-api/package.json +4 -11
  58. package/template/koa-rest-api/src/api/healthCheck.ts +1 -1
  59. package/template/koa-rest-api/src/api/jobs/getJobs.test.ts +2 -2
  60. package/template/koa-rest-api/src/api/jobs/getJobs.ts +4 -4
  61. package/template/koa-rest-api/src/api/jobs/index.ts +2 -2
  62. package/template/koa-rest-api/src/api/jobs/postJob.test.ts +3 -3
  63. package/template/koa-rest-api/src/api/jobs/postJob.ts +6 -6
  64. package/template/koa-rest-api/src/api/smokeTest.ts +2 -2
  65. package/template/koa-rest-api/src/app.test.ts +2 -2
  66. package/template/koa-rest-api/src/app.ts +2 -0
  67. package/template/koa-rest-api/src/framework/logging.ts +1 -1
  68. package/template/koa-rest-api/src/framework/metrics.ts +2 -2
  69. package/template/koa-rest-api/src/framework/server.test.ts +5 -5
  70. package/template/koa-rest-api/src/framework/server.ts +3 -3
  71. package/template/koa-rest-api/src/framework/validation.test.ts +5 -5
  72. package/template/koa-rest-api/src/framework/validation.ts +10 -9
  73. package/template/koa-rest-api/src/listen.ts +2 -0
  74. package/template/koa-rest-api/src/register.ts +1 -0
  75. package/template/koa-rest-api/src/storage/jobs.ts +1 -1
  76. package/template/koa-rest-api/src/testing/metrics.ts +1 -1
  77. package/template/koa-rest-api/src/testing/server.ts +1 -1
  78. package/template/koa-rest-api/src/testing/types.ts +2 -2
  79. package/template/koa-rest-api/src/types/jobs.ts +1 -1
  80. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -1
  81. package/template/lambda-sqs-worker-cdk/docker-compose.yml +0 -2
  82. package/template/lambda-sqs-worker-cdk/package.json +1 -8
  83. package/template/lambda-sqs-worker-cdk/src/app.test.ts +5 -5
  84. package/template/lambda-sqs-worker-cdk/src/app.ts +9 -7
  85. package/template/lambda-sqs-worker-cdk/src/framework/handler.test.ts +3 -3
  86. package/template/lambda-sqs-worker-cdk/src/framework/handler.ts +2 -2
  87. package/template/lambda-sqs-worker-cdk/src/framework/logging.ts +1 -1
  88. package/template/lambda-sqs-worker-cdk/src/framework/metrics.ts +1 -1
  89. package/template/lambda-sqs-worker-cdk/src/framework/validation.test.ts +3 -3
  90. package/template/lambda-sqs-worker-cdk/src/framework/validation.ts +4 -4
  91. package/template/lambda-sqs-worker-cdk/src/services/jobScorer.test.ts +3 -3
  92. package/template/lambda-sqs-worker-cdk/src/services/jobScorer.ts +6 -7
  93. package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.test.ts +3 -3
  94. package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.ts +2 -2
  95. package/template/lambda-sqs-worker-cdk/src/testing/services.ts +2 -2
  96. package/template/lambda-sqs-worker-cdk/src/testing/types.ts +1 -1
  97. package/template/lambda-sqs-worker-cdk/src/types/jobScorer.ts +1 -1
  98. package/template/lambda-sqs-worker-cdk/src/types/pipelineEvents.ts +1 -1
  99. package/template/lambda-sqs-worker-cdk/tsconfig.json +3 -3
  100. package/template/oss-npm-package/_package.json +0 -8
  101. package/template/oss-npm-package/skuba.template.js +1 -1
  102. package/template/oss-npm-package/tsconfig.json +0 -3
  103. package/template/private-npm-package/_package.json +0 -7
  104. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/index.d.ts +0 -2
  105. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/index.js +0 -35
  106. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/index.js.map +0 -7
  107. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/rewriteSrcImports.d.ts +0 -6
  108. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/rewriteSrcImports.js +0 -104
  109. package/lib/cli/lint/internalLints/upgrade/patches/11.1.0/rewriteSrcImports.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/template.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport fs from 'fs-extra';\nimport { z } from 'zod';\n\nimport { projectTypeSchema } from './manifest.js';\nimport { packageManagerSchema } from './packageManager.js';\n\nexport const TEMPLATE_NAMES = [\n 'express-rest-api',\n 'greeter',\n 'koa-rest-api',\n 'lambda-sqs-worker-cdk',\n 'oss-npm-package',\n 'private-npm-package',\n] as const;\n\nexport type TemplateName = (typeof TEMPLATE_NAMES)[number];\n\nexport const TEMPLATE_NAMES_WITH_BYO = [...TEMPLATE_NAMES, 'github \u2192'] as const;\n\ninterface TemplateDocumentationConfig {\n /**\n * The semantic version in which the template was first added.\n *\n * This is used to filter out historical changelogs.\n */\n added: string;\n\n /**\n * The Markdown file for the template in our `/docs`.\n *\n * This is used to compile per-template changelogs for our documentation site.\n */\n filename: string;\n}\n\nexport const TEMPLATE_DOCUMENTATION_CONFIG: Record<\n TemplateName,\n TemplateDocumentationConfig\n> = {\n 'express-rest-api': {\n added: '3.8.0',\n filename: 'api.md',\n },\n greeter: {\n added: '3.4.1',\n filename: 'barebones.md',\n },\n 'koa-rest-api': {\n added: '3.4.1',\n filename: 'api.md',\n },\n 'lambda-sqs-worker-cdk': {\n added: '3.13.0',\n filename: 'worker.md',\n },\n 'oss-npm-package': {\n added: '3.7.0',\n filename: 'package.md',\n },\n 'private-npm-package': {\n added: '3.6.0',\n filename: 'package.md',\n },\n};\n\nexport type TemplateConfig = z.infer<typeof templateConfigSchema>;\n\nexport const templateConfigSchema = z.object({\n fields: z.array(\n z.object({\n name: z.string(),\n message: z.string(),\n initial: z.string(),\n validate: z\n .function()\n .args(z.string())\n .returns(z.union([z.boolean(), z.string()]))\n .optional(),\n }),\n ),\n entryPoint: z.string().optional(),\n noSkip: z.boolean().optional(),\n packageManager: packageManagerSchema,\n type: projectTypeSchema.optional(),\n});\n\nexport const TEMPLATE_CONFIG_FILENAME = 'skuba.template.js';\n\nexport const TEMPLATE_DIR = path.join(__dirname, '..', '..', 'template');\n\nexport const BASE_TEMPLATE_DIR = path.join(TEMPLATE_DIR, 'base');\n\nexport const ensureTemplateConfigDeletion = (dir: string): Promise<void> =>\n fs.promises.rm(path.join(dir, TEMPLATE_CONFIG_FILENAME));\n\nexport const readBaseTemplateFile = (src: string): Promise<string> =>\n fs.promises.readFile(path.join(BASE_TEMPLATE_DIR, src), 'utf8');\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,sBAAe;AACf,iBAAkB;AAElB,sBAAkC;AAClC,4BAAqC;AAE9B,MAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,0BAA0B,CAAC,GAAG,gBAAgB,eAAU;AAkB9D,MAAM,gCAGT;AAAA,EACF,oBAAoB;AAAA,IAClB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,yBAAyB;AAAA,IACvB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,mBAAmB;AAAA,IACjB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,uBAAuB;AAAA,IACrB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AACF;AAIO,MAAM,uBAAuB,aAAE,OAAO;AAAA,EAC3C,QAAQ,aAAE;AAAA,IACR,aAAE,OAAO;AAAA,MACP,MAAM,aAAE,OAAO;AAAA,MACf,SAAS,aAAE,OAAO;AAAA,MAClB,SAAS,aAAE,OAAO;AAAA,MAClB,UAAU,aACP,SAAS,EACT,KAAK,aAAE,OAAO,CAAC,EACf,QAAQ,aAAE,MAAM,CAAC,aAAE,QAAQ,GAAG,aAAE,OAAO,CAAC,CAAC,CAAC,EAC1C,SAAS;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EACA,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQ,aAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,gBAAgB;AAAA,EAChB,MAAM,kCAAkB,SAAS;AACnC,CAAC;AAEM,MAAM,2BAA2B;AAEjC,MAAM,eAAe,YAAAA,QAAK,KAAK,WAAW,MAAM,MAAM,UAAU;AAEhE,MAAM,oBAAoB,YAAAA,QAAK,KAAK,cAAc,MAAM;AAExD,MAAM,+BAA+B,CAAC,QAC3C,gBAAAC,QAAG,SAAS,GAAG,YAAAD,QAAK,KAAK,KAAK,wBAAwB,CAAC;AAElD,MAAM,uBAAuB,CAAC,QACnC,gBAAAC,QAAG,SAAS,SAAS,YAAAD,QAAK,KAAK,mBAAmB,GAAG,GAAG,MAAM;",
4
+ "sourcesContent": ["import path from 'path';\n\nimport fs from 'fs-extra';\nimport * as z from 'zod/v4';\n\nimport { projectTypeSchema } from './manifest.js';\nimport { packageManagerSchema } from './packageManager.js';\n\nexport const TEMPLATE_NAMES = [\n 'express-rest-api',\n 'greeter',\n 'koa-rest-api',\n 'lambda-sqs-worker-cdk',\n 'oss-npm-package',\n 'private-npm-package',\n] as const;\n\nexport type TemplateName = (typeof TEMPLATE_NAMES)[number];\n\nexport const TEMPLATE_NAMES_WITH_BYO = [...TEMPLATE_NAMES, 'github \u2192'] as const;\n\ninterface TemplateDocumentationConfig {\n /**\n * The semantic version in which the template was first added.\n *\n * This is used to filter out historical changelogs.\n */\n added: string;\n\n /**\n * The Markdown file for the template in our `/docs`.\n *\n * This is used to compile per-template changelogs for our documentation site.\n */\n filename: string;\n}\n\nexport const TEMPLATE_DOCUMENTATION_CONFIG: Record<\n TemplateName,\n TemplateDocumentationConfig\n> = {\n 'express-rest-api': {\n added: '3.8.0',\n filename: 'api.md',\n },\n greeter: {\n added: '3.4.1',\n filename: 'barebones.md',\n },\n 'koa-rest-api': {\n added: '3.4.1',\n filename: 'api.md',\n },\n 'lambda-sqs-worker-cdk': {\n added: '3.13.0',\n filename: 'worker.md',\n },\n 'oss-npm-package': {\n added: '3.7.0',\n filename: 'package.md',\n },\n 'private-npm-package': {\n added: '3.6.0',\n filename: 'package.md',\n },\n};\n\nexport type TemplateConfig = z.infer<typeof templateConfigSchema>;\n\n// https://github.com/colinhacks/zod/issues/4143#issuecomment-2845134912\n// https://github.com/colinhacks/zod/issues/4143#issuecomment-2931729793\nconst functionSchema = <T extends z.core.$ZodFunction>(schema: T) =>\n z.custom<Parameters<T['implement']>[0]>().transform((arg, ctx) => {\n if (typeof arg !== 'function') {\n ctx.addIssue('Must be function');\n return z.NEVER;\n }\n return schema.implement(arg);\n });\n\nexport const templateConfigSchema = z.object({\n fields: z.array(\n z.object({\n name: z.string(),\n message: z.string(),\n initial: z.string(),\n validate: functionSchema(\n z.function({\n input: [z.string()],\n output: z.union([z.boolean(), z.string()]),\n }),\n ).optional(),\n }),\n ),\n entryPoint: z.string().optional(),\n noSkip: z.boolean().optional(),\n packageManager: packageManagerSchema,\n type: projectTypeSchema.optional(),\n});\n\nexport const TEMPLATE_CONFIG_FILENAME = 'skuba.template.js';\n\nexport const TEMPLATE_DIR = path.join(__dirname, '..', '..', 'template');\n\nexport const BASE_TEMPLATE_DIR = path.join(TEMPLATE_DIR, 'base');\n\nexport const ensureTemplateConfigDeletion = (dir: string): Promise<void> =>\n fs.promises.rm(path.join(dir, TEMPLATE_CONFIG_FILENAME));\n\nexport const readBaseTemplateFile = (src: string): Promise<string> =>\n fs.promises.readFile(path.join(BASE_TEMPLATE_DIR, src), 'utf8');\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,sBAAe;AACf,QAAmB;AAEnB,sBAAkC;AAClC,4BAAqC;AAE9B,MAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,0BAA0B,CAAC,GAAG,gBAAgB,eAAU;AAkB9D,MAAM,gCAGT;AAAA,EACF,oBAAoB;AAAA,IAClB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,yBAAyB;AAAA,IACvB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,mBAAmB;AAAA,IACjB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,uBAAuB;AAAA,IACrB,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AACF;AAMA,MAAM,iBAAiB,CAAgC,WACrD,EAAE,OAAsC,EAAE,UAAU,CAAC,KAAK,QAAQ;AAChE,MAAI,OAAO,QAAQ,YAAY;AAC7B,QAAI,SAAS,kBAAkB;AAC/B,WAAO,EAAE;AAAA,EACX;AACA,SAAO,OAAO,UAAU,GAAG;AAC7B,CAAC;AAEI,MAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,QAAQ,EAAE;AAAA,IACR,EAAE,OAAO;AAAA,MACP,MAAM,EAAE,OAAO;AAAA,MACf,SAAS,EAAE,OAAO;AAAA,MAClB,SAAS,EAAE,OAAO;AAAA,MAClB,UAAU;AAAA,QACR,EAAE,SAAS;AAAA,UACT,OAAO,CAAC,EAAE,OAAO,CAAC;AAAA,UAClB,QAAQ,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,QAC3C,CAAC;AAAA,MACH,EAAE,SAAS;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EACA,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQ,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,gBAAgB;AAAA,EAChB,MAAM,kCAAkB,SAAS;AACnC,CAAC;AAEM,MAAM,2BAA2B;AAEjC,MAAM,eAAe,YAAAA,QAAK,KAAK,WAAW,MAAM,MAAM,UAAU;AAEhE,MAAM,oBAAoB,YAAAA,QAAK,KAAK,cAAc,MAAM;AAExD,MAAM,+BAA+B,CAAC,QAC3C,gBAAAC,QAAG,SAAS,GAAG,YAAAD,QAAK,KAAK,KAAK,wBAAwB,CAAC;AAElD,MAAM,uBAAuB,CAAC,QACnC,gBAAAC,QAAG,SAAS,SAAS,YAAAD,QAAK,KAAK,mBAAmB,GAAG,GAAG,MAAM;",
6
6
  "names": ["path", "fs"]
7
7
  }
@@ -1,17 +1,9 @@
1
- import { z } from 'zod';
1
+ import * as z from 'zod/v4';
2
2
  declare const NpmVersions: z.ZodRecord<z.ZodString, z.ZodObject<{
3
3
  name: z.ZodString;
4
4
  version: z.ZodString;
5
5
  deprecated: z.ZodOptional<z.ZodString>;
6
- }, "strip", z.ZodTypeAny, {
7
- name: string;
8
- version: string;
9
- deprecated?: string | undefined;
10
- }, {
11
- name: string;
12
- version: string;
13
- deprecated?: string | undefined;
14
- }>>;
6
+ }, z.core.$strip>>;
15
7
  export type NpmVersions = z.infer<typeof NpmVersions>;
16
8
  export declare const getNpmVersions: (packageName: string) => Promise<NpmVersions | null>;
17
9
  export declare const getLatestNpmVersion: (packageName: string) => Promise<string | null>;
@@ -35,19 +35,19 @@ __export(version_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(version_exports);
37
37
  var import_npm_registry_fetch = __toESM(require("npm-registry-fetch"));
38
- var import_zod = require("zod");
38
+ var z = __toESM(require("zod/v4"));
39
39
  var import_manifest = require("./manifest.js");
40
40
  var import_wait = require("./wait.js");
41
- const NpmVersions = import_zod.z.record(
42
- import_zod.z.string(),
43
- import_zod.z.object({
44
- name: import_zod.z.string(),
45
- version: import_zod.z.string(),
46
- deprecated: import_zod.z.string().optional()
41
+ const NpmVersions = z.record(
42
+ z.string(),
43
+ z.object({
44
+ name: z.string(),
45
+ version: z.string(),
46
+ deprecated: z.string().optional()
47
47
  })
48
48
  );
49
- const PackageResponse = import_zod.z.object({
50
- "dist-tags": import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional(),
49
+ const PackageResponse = z.object({
50
+ "dist-tags": z.record(z.string(), z.string()).optional(),
51
51
  versions: NpmVersions
52
52
  });
53
53
  const getNpmPackage = async (packageName) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/version.ts"],
4
- "sourcesContent": ["import npmFetch from 'npm-registry-fetch';\nimport { z } from 'zod';\n\nimport { getSkubaManifest } from './manifest.js';\nimport { withTimeout } from './wait.js';\n\nconst NpmVersions = z.record(\n z.string(),\n z.object({\n name: z.string(),\n version: z.string(),\n deprecated: z.string().optional(),\n }),\n);\n\nexport type NpmVersions = z.infer<typeof NpmVersions>;\n\nconst PackageResponse = z.object({\n 'dist-tags': z.record(z.string(), z.string()).optional(),\n versions: NpmVersions,\n});\n\nconst getNpmPackage = async (packageName: string) => {\n try {\n const response = await npmFetch.json(packageName, {\n headers: {\n Accept:\n 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',\n },\n });\n\n const parsedResponse = PackageResponse.safeParse(response);\n if (!parsedResponse.success) {\n throw new Error(\n `Failed to parse package response from npm for package ${packageName}`,\n );\n }\n\n return parsedResponse.data;\n } catch (error) {\n if (\n error instanceof Error &&\n 'statusCode' in error &&\n error.statusCode === 404\n ) {\n return null;\n }\n throw error;\n }\n};\n\nexport const getNpmVersions = async (\n packageName: string,\n): Promise<NpmVersions | null> => {\n const response = await getNpmPackage(packageName);\n return response?.versions ?? null;\n};\n\nexport const getLatestNpmVersion = async (\n packageName: string,\n): Promise<string | null> => {\n const response = await getNpmPackage(packageName);\n return response?.['dist-tags']?.latest ?? null;\n};\n\nconst latestSkubaVersion = async (): Promise<string | null> => {\n try {\n const result = await withTimeout(getLatestNpmVersion('skuba'), { s: 2 });\n\n return result.ok ? result.value : null;\n } catch {\n return null;\n }\n};\n\nexport const getSkubaVersion = async (): Promise<string> => {\n const { version } = await getSkubaManifest();\n\n return version;\n};\n\ntype SkubaVersionInfo =\n | {\n isStale: true;\n\n local: string;\n latest: string;\n }\n | {\n isStale: false;\n\n local: string;\n latest: string | null;\n };\n\nexport const getSkubaVersionInfo = async (): Promise<SkubaVersionInfo> => {\n const [local, latest] = await Promise.all([\n getSkubaVersion(),\n latestSkubaVersion(),\n ]);\n\n if (latest === null) {\n // Assume we're up to date if we can't reach the npm registry\n return {\n isStale: false,\n local,\n latest,\n };\n }\n\n return {\n isStale: latest !== local,\n local,\n latest,\n };\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAAqB;AACrB,iBAAkB;AAElB,sBAAiC;AACjC,kBAA4B;AAE5B,MAAM,cAAc,aAAE;AAAA,EACpB,aAAE,OAAO;AAAA,EACT,aAAE,OAAO;AAAA,IACP,MAAM,aAAE,OAAO;AAAA,IACf,SAAS,aAAE,OAAO;AAAA,IAClB,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC;AACH;AAIA,MAAM,kBAAkB,aAAE,OAAO;AAAA,EAC/B,aAAa,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvD,UAAU;AACZ,CAAC;AAED,MAAM,gBAAgB,OAAO,gBAAwB;AACnD,MAAI;AACF,UAAM,WAAW,MAAM,0BAAAA,QAAS,KAAK,aAAa;AAAA,MAChD,SAAS;AAAA,QACP,QACE;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,iBAAiB,gBAAgB,UAAU,QAAQ;AACzD,QAAI,CAAC,eAAe,SAAS;AAC3B,YAAM,IAAI;AAAA,QACR,yDAAyD,WAAW;AAAA,MACtE;AAAA,IACF;AAEA,WAAO,eAAe;AAAA,EACxB,SAAS,OAAO;AACd,QACE,iBAAiB,SACjB,gBAAgB,SAChB,MAAM,eAAe,KACrB;AACA,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEO,MAAM,iBAAiB,OAC5B,gBACgC;AAChC,QAAM,WAAW,MAAM,cAAc,WAAW;AAChD,SAAO,UAAU,YAAY;AAC/B;AAEO,MAAM,sBAAsB,OACjC,gBAC2B;AAC3B,QAAM,WAAW,MAAM,cAAc,WAAW;AAChD,SAAO,WAAW,WAAW,GAAG,UAAU;AAC5C;AAEA,MAAM,qBAAqB,YAAoC;AAC7D,MAAI;AACF,UAAM,SAAS,UAAM,yBAAY,oBAAoB,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC;AAEvE,WAAO,OAAO,KAAK,OAAO,QAAQ;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,MAAM,kBAAkB,YAA6B;AAC1D,QAAM,EAAE,QAAQ,IAAI,UAAM,kCAAiB;AAE3C,SAAO;AACT;AAgBO,MAAM,sBAAsB,YAAuC;AACxE,QAAM,CAAC,OAAO,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IACxC,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,EACrB,CAAC;AAED,MAAI,WAAW,MAAM;AAEnB,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import npmFetch from 'npm-registry-fetch';\nimport * as z from 'zod/v4';\n\nimport { getSkubaManifest } from './manifest.js';\nimport { withTimeout } from './wait.js';\n\nconst NpmVersions = z.record(\n z.string(),\n z.object({\n name: z.string(),\n version: z.string(),\n deprecated: z.string().optional(),\n }),\n);\n\nexport type NpmVersions = z.infer<typeof NpmVersions>;\n\nconst PackageResponse = z.object({\n 'dist-tags': z.record(z.string(), z.string()).optional(),\n versions: NpmVersions,\n});\n\nconst getNpmPackage = async (packageName: string) => {\n try {\n const response = await npmFetch.json(packageName, {\n headers: {\n Accept:\n 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',\n },\n });\n\n const parsedResponse = PackageResponse.safeParse(response);\n if (!parsedResponse.success) {\n throw new Error(\n `Failed to parse package response from npm for package ${packageName}`,\n );\n }\n\n return parsedResponse.data;\n } catch (error) {\n if (\n error instanceof Error &&\n 'statusCode' in error &&\n error.statusCode === 404\n ) {\n return null;\n }\n throw error;\n }\n};\n\nexport const getNpmVersions = async (\n packageName: string,\n): Promise<NpmVersions | null> => {\n const response = await getNpmPackage(packageName);\n return response?.versions ?? null;\n};\n\nexport const getLatestNpmVersion = async (\n packageName: string,\n): Promise<string | null> => {\n const response = await getNpmPackage(packageName);\n return response?.['dist-tags']?.latest ?? null;\n};\n\nconst latestSkubaVersion = async (): Promise<string | null> => {\n try {\n const result = await withTimeout(getLatestNpmVersion('skuba'), { s: 2 });\n\n return result.ok ? result.value : null;\n } catch {\n return null;\n }\n};\n\nexport const getSkubaVersion = async (): Promise<string> => {\n const { version } = await getSkubaManifest();\n\n return version;\n};\n\ntype SkubaVersionInfo =\n | {\n isStale: true;\n\n local: string;\n latest: string;\n }\n | {\n isStale: false;\n\n local: string;\n latest: string | null;\n };\n\nexport const getSkubaVersionInfo = async (): Promise<SkubaVersionInfo> => {\n const [local, latest] = await Promise.all([\n getSkubaVersion(),\n latestSkubaVersion(),\n ]);\n\n if (latest === null) {\n // Assume we're up to date if we can't reach the npm registry\n return {\n isStale: false,\n local,\n latest,\n };\n }\n\n return {\n isStale: latest !== local,\n local,\n latest,\n };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAAqB;AACrB,QAAmB;AAEnB,sBAAiC;AACjC,kBAA4B;AAE5B,MAAM,cAAc,EAAE;AAAA,EACpB,EAAE,OAAO;AAAA,EACT,EAAE,OAAO;AAAA,IACP,MAAM,EAAE,OAAO;AAAA,IACf,SAAS,EAAE,OAAO;AAAA,IAClB,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC;AACH;AAIA,MAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvD,UAAU;AACZ,CAAC;AAED,MAAM,gBAAgB,OAAO,gBAAwB;AACnD,MAAI;AACF,UAAM,WAAW,MAAM,0BAAAA,QAAS,KAAK,aAAa;AAAA,MAChD,SAAS;AAAA,QACP,QACE;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,iBAAiB,gBAAgB,UAAU,QAAQ;AACzD,QAAI,CAAC,eAAe,SAAS;AAC3B,YAAM,IAAI;AAAA,QACR,yDAAyD,WAAW;AAAA,MACtE;AAAA,IACF;AAEA,WAAO,eAAe;AAAA,EACxB,SAAS,OAAO;AACd,QACE,iBAAiB,SACjB,gBAAgB,SAChB,MAAM,eAAe,KACrB;AACA,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAEO,MAAM,iBAAiB,OAC5B,gBACgC;AAChC,QAAM,WAAW,MAAM,cAAc,WAAW;AAChD,SAAO,UAAU,YAAY;AAC/B;AAEO,MAAM,sBAAsB,OACjC,gBAC2B;AAC3B,QAAM,WAAW,MAAM,cAAc,WAAW;AAChD,SAAO,WAAW,WAAW,GAAG,UAAU;AAC5C;AAEA,MAAM,qBAAqB,YAAoC;AAC7D,MAAI;AACF,UAAM,SAAS,UAAM,yBAAY,oBAAoB,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC;AAEvE,WAAO,OAAO,KAAK,OAAO,QAAQ;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,MAAM,kBAAkB,YAA6B;AAC1D,QAAM,EAAE,QAAQ,IAAI,UAAM,kCAAiB;AAE3C,SAAO;AACT;AAgBO,MAAM,sBAAsB,YAAuC;AACxE,QAAM,CAAC,OAAO,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IACxC,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,EACrB,CAAC;AAED,MAAI,WAAW,MAAM;AAEnB,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AACF;",
6
6
  "names": ["npmFetch"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skuba",
3
- "version": "12.0.0-subpath-imports-20250710043319",
3
+ "version": "12.0.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",
@@ -13,13 +13,6 @@
13
13
  },
14
14
  "license": "MIT",
15
15
  "sideEffects": false,
16
- "imports": {
17
- "#src/*": {
18
- "types": "./src/*",
19
- "import": "./lib/*",
20
- "require": "./lib/*"
21
- }
22
- },
23
16
  "main": "lib/index.js",
24
17
  "types": "./lib/index.d.ts",
25
18
  "bin": {
@@ -105,13 +98,13 @@
105
98
  "tsx": "^4.16.2",
106
99
  "typescript": "~5.8.0",
107
100
  "zod": "^3.25.67",
108
- "eslint-config-skuba": "7.0.0-subpath-imports-20250710043319"
101
+ "eslint-config-skuba": "7.0.0"
109
102
  },
110
103
  "devDependencies": {
111
104
  "@changesets/cli": "2.29.5",
112
105
  "@changesets/get-github-info": "0.6.0",
113
- "@jest/reporters": "30.0.2",
114
- "@jest/test-result": "30.0.2",
106
+ "@jest/reporters": "30.0.4",
107
+ "@jest/test-result": "30.0.4",
115
108
  "@types/ejs": "3.1.5",
116
109
  "@types/express": "5.0.3",
117
110
  "@types/fs-extra": "11.0.4",
@@ -127,14 +120,14 @@
127
120
  "enhanced-resolve": "5.18.2",
128
121
  "express": "5.1.0",
129
122
  "fastify": "5.4.0",
130
- "jest-diff": "30.0.3",
123
+ "jest-diff": "30.0.4",
131
124
  "jsonfile": "6.1.0",
132
125
  "koa": "3.0.0",
133
126
  "memfs": "4.17.2",
134
127
  "remark-cli": "12.0.1",
135
128
  "remark-preset-lint-recommended": "7.0.1",
136
129
  "semver": "7.7.2",
137
- "supertest": "7.1.1",
130
+ "supertest": "7.1.3",
138
131
  "type-fest": "2.19.0"
139
132
  },
140
133
  "peerDependencies": {
@@ -1 +1 @@
1
- export { default } from 'skuba/config/prettier.js';
1
+ module.exports = require('skuba/config/prettier');
@@ -1 +1 @@
1
- export { default } from 'eslint-config-skuba';
1
+ module.exports = require('eslint-config-skuba');
@@ -1,5 +1,4 @@
1
1
  # managed by skuba
2
- nodeOptions: '${NODE_OPTIONS:- } --experimental-vm-modules'
3
2
  packageManagerStrictVersion: true
4
3
  publicHoistPattern:
5
4
  - '@types*'
@@ -1,15 +1,6 @@
1
- import { readFileSync } from 'fs';
1
+ import { Jest } from 'skuba';
2
2
 
3
- const packageJson = JSON.parse(readFileSync('package.json', 'utf8')) as {
4
- type?: string;
5
- };
6
- const isESM = packageJson.type === 'module';
7
-
8
- export default {
9
- preset: 'skuba',
10
- ...(isESM && {
11
- extensionsToTreatAsEsm: ['.ts'],
12
- }),
3
+ export default Jest.mergePreset({
13
4
  coveragePathIgnorePatterns: ['src/testing'],
14
5
  coverageThreshold: {
15
6
  global: {
@@ -19,11 +10,6 @@ export default {
19
10
  statements: 0,
20
11
  },
21
12
  },
22
- moduleNameMapper: {
23
- '^#src$': '<rootDir>/src',
24
- '^#src\/(.*)\\.js$': '<rootDir>/src/$1',
25
- '^#src\/(.*)$': '<rootDir>/src/$1',
26
- },
27
13
  setupFiles: ['<rootDir>/jest.setup.ts'],
28
14
  testPathIgnorePatterns: ['/test\\.ts'],
29
- };
15
+ });
@@ -2,10 +2,10 @@
2
2
  "compilerOptions": {
3
3
  "baseUrl": ".",
4
4
  "lib": ["ES2024"],
5
- "moduleResolution": "node16",
6
- "module": "node18",
7
5
  "outDir": "lib",
8
- "rootDir": ".",
6
+ "paths": {
7
+ "src": ["src"]
8
+ },
9
9
  "target": "ES2024"
10
10
  },
11
11
  "exclude": ["lib*/**/*"],
@@ -49,10 +49,11 @@ steps:
49
49
  plugins:
50
50
  - *docker-ecr-cache
51
51
  - docker-compose#v5.10.0:
52
- run: app
53
52
  environment:
54
53
  - GITHUB_API_TOKEN
54
+ mount-buildkite-agent: true
55
55
  propagate-environment: true
56
+ run: app
56
57
  timeout_in_minutes: 10
57
58
 
58
59
  - label: 📦 Build & Package
@@ -4,7 +4,5 @@ services:
4
4
  init: true
5
5
  volumes:
6
6
  - ./:/workdir
7
- # Mount agent for Buildkite annotations.
8
- - /usr/bin/buildkite-agent:/usr/bin/buildkite-agent
9
7
  # Mount cached dependencies.
10
8
  - /workdir/node_modules
@@ -2,13 +2,6 @@
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
- },
12
5
  "scripts": {
13
6
  "build": "skuba build",
14
7
  "format": "skuba format",
@@ -1,3 +1,5 @@
1
+ import './register.js';
2
+
1
3
  import express from 'express';
2
4
 
3
5
  import { healthCheckHandler } from './api/healthCheck.js';
@@ -1,6 +1,6 @@
1
1
  import createLogger from '@seek/logger';
2
2
 
3
- import { config } from '#src/config.js';
3
+ import { config } from 'src/config.js';
4
4
 
5
5
  export const logger = createLogger({
6
6
  base: {
@@ -1,9 +1,9 @@
1
1
  import { StatsD } from 'hot-shots';
2
2
  import { createStatsDClient } from 'seek-datadog-custom-metrics';
3
3
 
4
- import { logger } from './logging.js';
4
+ import { config } from 'src/config.js';
5
5
 
6
- import { config } from '#src/config.js';
6
+ import { logger } from './logging.js';
7
7
 
8
8
  /* istanbul ignore next: StatsD client is not our responsibility */
9
9
  export const metricsClient = createStatsDClient(StatsD, config, (err) =>
@@ -1,3 +1,5 @@
1
+ import './register.js';
2
+
1
3
  import app from './app.js';
2
4
  import { config } from './config.js';
3
5
  import { logger } from './framework/logging.js';
@@ -0,0 +1 @@
1
+ import 'skuba-dive/register';
@@ -30,8 +30,9 @@ steps:
30
30
  plugins:
31
31
  - *docker-ecr-cache
32
32
  - docker-compose#v5.10.0:
33
- run: app
34
33
  environment:
35
34
  - GITHUB_API_TOKEN
35
+ mount-buildkite-agent: true
36
36
  propagate-environment: true
37
+ run: app
37
38
  timeout_in_minutes: 10
@@ -4,7 +4,5 @@ services:
4
4
  init: true
5
5
  volumes:
6
6
  - ./:/workdir
7
- # Mount agent for Buildkite annotations.
8
- - /usr/bin/buildkite-agent:/usr/bin/buildkite-agent
9
7
  # Mount cached dependencies.
10
8
  - /workdir/node_modules
@@ -2,13 +2,6 @@
2
2
  "name": "@seek/greeter",
3
3
  "private": true,
4
4
  "license": "UNLICENSED",
5
- "imports": {
6
- "#src/*": {
7
- "types": "./src/*",
8
- "import": "./lib/*",
9
- "require": "./lib/*"
10
- }
11
- },
12
5
  "scripts": {
13
6
  "build": "skuba build",
14
7
  "format": "skuba format",
@@ -24,7 +17,7 @@
24
17
  },
25
18
  "devDependencies": {
26
19
  "@types/node": "^22.13.10",
27
- "skuba": "12.0.0-subpath-imports-20250710043319"
20
+ "skuba": "*"
28
21
  },
29
22
  "packageManager": "pnpm@10.12.4",
30
23
  "engines": {
@@ -1,4 +1,4 @@
1
+ import 'skuba-dive/register';
2
+
1
3
  /* eslint-disable-next-line no-console */
2
4
  console.log('Hello world');
3
-
4
- export {};
@@ -49,10 +49,11 @@ steps:
49
49
  plugins:
50
50
  - *docker-ecr-cache
51
51
  - docker-compose#v5.10.0:
52
- run: app
53
52
  environment:
54
53
  - GITHUB_API_TOKEN
54
+ mount-buildkite-agent: true
55
55
  propagate-environment: true
56
+ run: app
56
57
  timeout_in_minutes: 10
57
58
 
58
59
  - label: 📦 Build & Package
@@ -4,7 +4,5 @@ services:
4
4
  init: true
5
5
  volumes:
6
6
  - ./:/workdir
7
- # Mount agent for Buildkite annotations.
8
- - /usr/bin/buildkite-agent:/usr/bin/buildkite-agent
9
7
  # Mount cached dependencies.
10
8
  - /workdir/node_modules
@@ -2,13 +2,6 @@
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
- },
12
5
  "scripts": {
13
6
  "build": "skuba build",
14
7
  "format": "skuba format",
@@ -24,11 +17,11 @@
24
17
  "@koa/router": "^13.0.0",
25
18
  "@opentelemetry/api": "^1.9.0",
26
19
  "@opentelemetry/core": "^2.0.0",
27
- "@opentelemetry/exporter-trace-otlp-grpc": "^0.202.0",
28
- "@opentelemetry/instrumentation-aws-sdk": "^0.54.0",
29
- "@opentelemetry/instrumentation-http": "^0.202.0",
20
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.203.0",
21
+ "@opentelemetry/instrumentation-aws-sdk": "^0.56.0",
22
+ "@opentelemetry/instrumentation-http": "^0.203.0",
30
23
  "@opentelemetry/propagator-b3": "^2.0.0",
31
- "@opentelemetry/sdk-node": "^0.202.0",
24
+ "@opentelemetry/sdk-node": "^0.203.0",
32
25
  "@seek/logger": "^10.0.0",
33
26
  "hot-shots": "^10.0.0",
34
27
  "koa": "^2.16.1",
@@ -1,4 +1,4 @@
1
- import type { Middleware } from '#src/types/koa.js';
1
+ import type { Middleware } from 'src/types/koa.js';
2
2
 
3
3
  /**
4
4
  * Signifies that the API is available to serve requests.
@@ -1,6 +1,6 @@
1
- import { jobRouter } from './index.js';
1
+ import { agentFromRouter } from 'src/testing/server.js';
2
2
 
3
- import { agentFromRouter } from '#src/testing/server.js';
3
+ import { jobRouter } from './index.js';
4
4
 
5
5
  const agent = agentFromRouter(jobRouter);
6
6
 
@@ -1,7 +1,7 @@
1
- import { logger } from '#src/framework/logging.js';
2
- import { metricsClient } from '#src/framework/metrics.js';
3
- import * as storage from '#src/storage/jobs.js';
4
- import type { Middleware } from '#src/types/koa.js';
1
+ import { logger } from 'src/framework/logging.js';
2
+ import { metricsClient } from 'src/framework/metrics.js';
3
+ import * as storage from 'src/storage/jobs.js';
4
+ import type { Middleware } from 'src/types/koa.js';
5
5
 
6
6
  export const getJobsHandler: Middleware = async (ctx) => {
7
7
  const jobs = await storage.readJobs();
@@ -1,10 +1,10 @@
1
1
  import Router from '@koa/router';
2
2
 
3
+ import { jsonBodyParser } from 'src/framework/bodyParser.js';
4
+
3
5
  import { getJobsHandler } from './getJobs.js';
4
6
  import { postJobHandler } from './postJob.js';
5
7
 
6
- import { jsonBodyParser } from '#src/framework/bodyParser.js';
7
-
8
8
  export const jobRouter = new Router()
9
9
  .get('/', getJobsHandler)
10
10
  .post('/', jsonBodyParser, postJobHandler);
@@ -1,7 +1,7 @@
1
- import { jobRouter } from './index.js';
1
+ import { agentFromRouter } from 'src/testing/server.js';
2
+ import { mockJobInput } from 'src/testing/types.js';
2
3
 
3
- import { agentFromRouter } from '#src/testing/server.js';
4
- import { mockJobInput } from '#src/testing/types.js';
4
+ import { jobRouter } from './index.js';
5
5
 
6
6
  const agent = agentFromRouter(jobRouter);
7
7
 
@@ -1,9 +1,9 @@
1
- import { logger } from '#src/framework/logging.js';
2
- import { metricsClient } from '#src/framework/metrics.js';
3
- import { validateRequestBody } from '#src/framework/validation.js';
4
- import * as storage from '#src/storage/jobs.js';
5
- import { JobInputSchema } from '#src/types/jobs.js';
6
- import type { Middleware } from '#src/types/koa.js';
1
+ import { logger } from 'src/framework/logging.js';
2
+ import { metricsClient } from 'src/framework/metrics.js';
3
+ import { validateRequestBody } from 'src/framework/validation.js';
4
+ import * as storage from 'src/storage/jobs.js';
5
+ import { JobInputSchema } from 'src/types/jobs.js';
6
+ import type { Middleware } from 'src/types/koa.js';
7
7
 
8
8
  export const postJobHandler: Middleware = async (ctx) => {
9
9
  const jobInput = validateRequestBody(ctx, JobInputSchema);
@@ -1,5 +1,5 @@
1
- import { smokeTestJobStorage } from '#src/storage/jobs.js';
2
- import type { Middleware } from '#src/types/koa.js';
1
+ import { smokeTestJobStorage } from 'src/storage/jobs.js';
2
+ import type { Middleware } from 'src/types/koa.js';
3
3
 
4
4
  /**
5
5
  * Tests connectivity to ensure appropriate access and network configuration.
@@ -1,6 +1,6 @@
1
- import app from './app.js';
1
+ import { agentFromApp } from 'src/testing/server.js';
2
2
 
3
- import { agentFromApp } from '#src/testing/server.js';
3
+ import app from './app.js';
4
4
 
5
5
  const agent = agentFromApp(app);
6
6
 
@@ -1,3 +1,5 @@
1
+ import './register.js';
2
+
1
3
  import { router } from './api/index.js';
2
4
  import { createApp } from './framework/server.js';
3
5
 
@@ -1,7 +1,7 @@
1
1
  import createLogger, { createDestination } from '@seek/logger';
2
2
  import { RequestLogging } from 'seek-koala';
3
3
 
4
- import { config } from '#src/config.js';
4
+ import { config } from 'src/config.js';
5
5
 
6
6
  const { createContextMiddleware, mixin } =
7
7
  RequestLogging.createContextStorage();
@@ -1,9 +1,9 @@
1
1
  import { StatsD } from 'hot-shots';
2
2
  import { createStatsDClient } from 'seek-datadog-custom-metrics';
3
3
 
4
- import { logger } from './logging.js';
4
+ import { config } from 'src/config.js';
5
5
 
6
- import { config } from '#src/config.js';
6
+ import { logger } from './logging.js';
7
7
 
8
8
  /* istanbul ignore next: StatsD client is not our responsibility */
9
9
  export const metricsClient = createStatsDClient(StatsD, config, (err) =>
@@ -1,11 +1,11 @@
1
1
  import Router from '@koa/router';
2
2
 
3
- import { stdoutMock } from './logging.js';
3
+ import { metricsClient } from 'src/testing/metrics.js';
4
+ import { agentFromRouter } from 'src/testing/server.js';
5
+ import { chance } from 'src/testing/types.js';
6
+ import type { Middleware } from 'src/types/koa.js';
4
7
 
5
- import { metricsClient } from '#src/testing/metrics.js';
6
- import { agentFromRouter } from '#src/testing/server.js';
7
- import { chance } from '#src/testing/types.js';
8
- import type { Middleware } from '#src/types/koa.js';
8
+ import { stdoutMock } from './logging.js';
9
9
 
10
10
  const middleware = jest.fn<void, Parameters<Middleware>>();
11
11
 
@@ -8,9 +8,9 @@ import {
8
8
  VersionMiddleware,
9
9
  } from 'seek-koala';
10
10
 
11
- import { config } from '#src/config.js';
12
- import { contextMiddleware, logger } from '#src/framework/logging.js';
13
- import { metricsClient } from '#src/framework/metrics.js';
11
+ import { config } from 'src/config.js';
12
+ import { contextMiddleware, logger } from 'src/framework/logging.js';
13
+ import { metricsClient } from 'src/framework/metrics.js';
14
14
 
15
15
  const metrics = MetricsMiddleware.create(
16
16
  metricsClient,
@@ -1,12 +1,12 @@
1
- import { jsonBodyParser } from './bodyParser.js';
2
- import { validate } from './validation.js';
3
-
4
- import { agentFromMiddleware } from '#src/testing/server.js';
1
+ import { agentFromMiddleware } from 'src/testing/server.js';
5
2
  import {
6
3
  IdDescriptionSchema,
7
4
  chance,
8
5
  mockIdDescription,
9
- } from '#src/testing/types.js';
6
+ } from 'src/testing/types.js';
7
+
8
+ import { jsonBodyParser } from './bodyParser.js';
9
+ import { validate } from './validation.js';
10
10
 
11
11
  const agent = agentFromMiddleware(jsonBodyParser, (ctx) => {
12
12
  const result = validate({
@@ -1,7 +1,8 @@
1
1
  import { ErrorMiddleware } from 'seek-koala';
2
- import type { core, z } from 'zod/v4';
2
+ import type * as z from 'zod/v4';
3
+ import type * as core from 'zod/v4/core';
3
4
 
4
- import type { Context } from '#src/types/koa.js';
5
+ import type { Context } from 'src/types/koa.js';
5
6
 
6
7
  type InvalidFields = Record<string, string>;
7
8
 
@@ -59,15 +60,15 @@ const parseTuples = (
59
60
  return [[path, issue.message]] as const;
60
61
  });
61
62
 
62
- export const validate = <Output, Input = Output>({
63
+ export const validate = <T extends z.ZodType>({
63
64
  ctx,
64
65
  input,
65
66
  schema,
66
67
  }: {
67
68
  ctx: Context;
68
69
  input: unknown;
69
- schema: z.ZodSchema<Output, Input>;
70
- }): Output => {
70
+ schema: T;
71
+ }): z.infer<T> => {
71
72
  const parseResult = schema.safeParse(input);
72
73
  if (parseResult.success === false) {
73
74
  const invalidFields = parseInvalidFieldsFromError(parseResult.error);
@@ -82,11 +83,11 @@ export const validate = <Output, Input = Output>({
82
83
  return parseResult.data;
83
84
  };
84
85
 
85
- export const validateRequestBody = <Output, Input = Output>(
86
+ export const validateRequestBody = <T extends z.ZodType>(
86
87
  ctx: Context,
87
- schema: z.ZodSchema<Output, Input>,
88
- ): Output =>
89
- validate<Output, Input>({
88
+ schema: T,
89
+ ): z.infer<T> =>
90
+ validate({
90
91
  ctx,
91
92
  input: ctx.request.body as unknown,
92
93
  schema,