skuba 9.2.0-old-lang-opts-20250115050141 → 10.0.0-main-20250312042528

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 (105) hide show
  1. package/lib/cli/configure/analyseDependencies.js +4 -1
  2. package/lib/cli/configure/analyseDependencies.js.map +2 -2
  3. package/lib/cli/init/index.js +2 -2
  4. package/lib/cli/init/index.js.map +2 -2
  5. package/lib/cli/init/prompts.d.ts +1 -1
  6. package/lib/cli/lint/internal.js +2 -1
  7. package/lib/cli/lint/internal.js.map +2 -2
  8. package/lib/cli/lint/internalLints/detectBadCodeowners.d.ts +4 -0
  9. package/lib/cli/lint/internalLints/detectBadCodeowners.js +72 -0
  10. package/lib/cli/lint/internalLints/detectBadCodeowners.js.map +7 -0
  11. package/lib/cli/lint/internalLints/upgrade/patches/9.1.0/index.d.ts +2 -0
  12. package/lib/cli/lint/internalLints/upgrade/patches/9.1.0/index.js +35 -0
  13. package/lib/cli/lint/internalLints/upgrade/patches/9.1.0/index.js.map +7 -0
  14. package/lib/cli/lint/internalLints/upgrade/patches/9.1.0/upgradeNode.d.ts +2 -0
  15. package/lib/cli/lint/internalLints/upgrade/patches/9.1.0/upgradeNode.js +59 -0
  16. package/lib/cli/lint/internalLints/upgrade/patches/9.1.0/upgradeNode.js.map +7 -0
  17. package/lib/cli/migrate/index.js +10 -1
  18. package/lib/cli/migrate/index.js.map +2 -2
  19. package/lib/cli/migrate/nodeVersion/checks.d.ts +14 -0
  20. package/lib/cli/migrate/nodeVersion/checks.js +165 -0
  21. package/lib/cli/migrate/nodeVersion/checks.js.map +7 -0
  22. package/lib/cli/migrate/nodeVersion/getNodeTypesVersion.d.ts +6 -0
  23. package/lib/cli/migrate/nodeVersion/getNodeTypesVersion.js +58 -0
  24. package/lib/cli/migrate/nodeVersion/getNodeTypesVersion.js.map +7 -0
  25. package/lib/cli/migrate/nodeVersion/index.d.ts +5 -1
  26. package/lib/cli/migrate/nodeVersion/index.js +119 -36
  27. package/lib/cli/migrate/nodeVersion/index.js.map +2 -2
  28. package/lib/index.js +3 -3
  29. package/lib/utils/copy.d.ts +1 -1
  30. package/lib/utils/copy.js +11 -3
  31. package/lib/utils/copy.js.map +2 -2
  32. package/lib/utils/template.d.ts +2 -2
  33. package/lib/utils/template.js +0 -5
  34. package/lib/utils/template.js.map +2 -2
  35. package/lib/utils/version.d.ts +17 -1
  36. package/lib/utils/version.js +48 -18
  37. package/lib/utils/version.js.map +3 -3
  38. package/package.json +17 -19
  39. package/template/base/tsconfig.json +2 -2
  40. package/template/express-rest-api/.buildkite/pipeline.yml +4 -4
  41. package/template/express-rest-api/.gantry/common.yml +1 -3
  42. package/template/express-rest-api/.nvmrc +1 -1
  43. package/template/express-rest-api/Dockerfile +1 -1
  44. package/template/express-rest-api/Dockerfile.dev-deps +2 -2
  45. package/template/express-rest-api/package.json +4 -4
  46. package/template/greeter/.buildkite/pipeline.yml +1 -1
  47. package/template/greeter/.nvmrc +1 -1
  48. package/template/greeter/Dockerfile +2 -2
  49. package/template/greeter/README.md +1 -1
  50. package/template/greeter/package.json +4 -4
  51. package/template/koa-rest-api/.buildkite/pipeline.yml +4 -4
  52. package/template/koa-rest-api/.gantry/common.yml +1 -3
  53. package/template/koa-rest-api/.nvmrc +1 -1
  54. package/template/koa-rest-api/Dockerfile +1 -1
  55. package/template/koa-rest-api/Dockerfile.dev-deps +2 -2
  56. package/template/koa-rest-api/package.json +3 -3
  57. package/template/koa-rest-api/tsconfig.json +2 -2
  58. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -2
  59. package/template/lambda-sqs-worker-cdk/.nvmrc +1 -1
  60. package/template/lambda-sqs-worker-cdk/Dockerfile +3 -3
  61. package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +2 -2
  62. package/template/lambda-sqs-worker-cdk/infra/appStack.ts +4 -4
  63. package/template/lambda-sqs-worker-cdk/infra/config.ts +1 -1
  64. package/template/lambda-sqs-worker-cdk/infra/index.ts +3 -5
  65. package/template/lambda-sqs-worker-cdk/package.json +6 -6
  66. package/template/lambda-sqs-worker-cdk/tsconfig.json +2 -2
  67. package/template/oss-npm-package/.github/workflows/release.yml +1 -1
  68. package/template/oss-npm-package/.github/workflows/validate.yml +1 -1
  69. package/template/oss-npm-package/.nvmrc +1 -1
  70. package/template/oss-npm-package/_package.json +1 -1
  71. package/template/private-npm-package/.nvmrc +1 -1
  72. package/template/private-npm-package/_package.json +2 -2
  73. package/template/lambda-sqs-worker/.buildkite/pipeline.yml +0 -108
  74. package/template/lambda-sqs-worker/.env +0 -1
  75. package/template/lambda-sqs-worker/.nvmrc +0 -1
  76. package/template/lambda-sqs-worker/Dockerfile +0 -17
  77. package/template/lambda-sqs-worker/README.md +0 -132
  78. package/template/lambda-sqs-worker/_.npmrc +0 -13
  79. package/template/lambda-sqs-worker/docker-compose.yml +0 -10
  80. package/template/lambda-sqs-worker/package.json +0 -45
  81. package/template/lambda-sqs-worker/serverless.yml +0 -213
  82. package/template/lambda-sqs-worker/skuba.template.js +0 -33
  83. package/template/lambda-sqs-worker/src/app.test.ts +0 -116
  84. package/template/lambda-sqs-worker/src/app.ts +0 -57
  85. package/template/lambda-sqs-worker/src/config.ts +0 -62
  86. package/template/lambda-sqs-worker/src/framework/handler.test.ts +0 -61
  87. package/template/lambda-sqs-worker/src/framework/handler.ts +0 -43
  88. package/template/lambda-sqs-worker/src/framework/logging.ts +0 -27
  89. package/template/lambda-sqs-worker/src/framework/metrics.ts +0 -14
  90. package/template/lambda-sqs-worker/src/framework/validation.test.ts +0 -84
  91. package/template/lambda-sqs-worker/src/framework/validation.ts +0 -10
  92. package/template/lambda-sqs-worker/src/hooks.ts +0 -95
  93. package/template/lambda-sqs-worker/src/mapping/jobScorer.ts +0 -22
  94. package/template/lambda-sqs-worker/src/services/aws.ts +0 -5
  95. package/template/lambda-sqs-worker/src/services/jobScorer.test.ts +0 -44
  96. package/template/lambda-sqs-worker/src/services/jobScorer.ts +0 -59
  97. package/template/lambda-sqs-worker/src/services/pipelineEventSender.test.ts +0 -40
  98. package/template/lambda-sqs-worker/src/services/pipelineEventSender.ts +0 -33
  99. package/template/lambda-sqs-worker/src/testing/handler.ts +0 -13
  100. package/template/lambda-sqs-worker/src/testing/logging.ts +0 -19
  101. package/template/lambda-sqs-worker/src/testing/services.ts +0 -28
  102. package/template/lambda-sqs-worker/src/testing/types.ts +0 -33
  103. package/template/lambda-sqs-worker/src/types/jobScorer.ts +0 -15
  104. package/template/lambda-sqs-worker/src/types/pipelineEvents.ts +0 -21
  105. package/template/lambda-sqs-worker/tsconfig.json +0 -13
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var getNodeTypesVersion_exports = {};
20
+ __export(getNodeTypesVersion_exports, {
21
+ getNodeTypesVersion: () => getNodeTypesVersion
22
+ });
23
+ module.exports = __toCommonJS(getNodeTypesVersion_exports);
24
+ var import_util = require("util");
25
+ var import_semver = require("semver");
26
+ var import_logging = require("../../../utils/logging");
27
+ var import_version = require("../../../utils/version");
28
+ const getNodeTypesVersion = async (major, defaultVersion) => {
29
+ try {
30
+ const versions = await (0, import_version.getNpmVersions)("@types/node");
31
+ const matchingVersions = Object.values(versions ?? {}).filter(
32
+ (v) => (0, import_semver.valid)(v.version) && (0, import_semver.satisfies)(v.version, `${major}.x.x`) && !v.deprecated
33
+ );
34
+ if (!matchingVersions.length) {
35
+ return {
36
+ version: defaultVersion,
37
+ err: `No matching @types/node versions for Node.js ${major}`
38
+ };
39
+ }
40
+ const { version } = matchingVersions.reduce(
41
+ (a, b) => (0, import_semver.gt)(a.version, b.version) ? a : b
42
+ );
43
+ return {
44
+ version
45
+ };
46
+ } catch (err) {
47
+ import_logging.log.subtle((0, import_util.inspect)(err));
48
+ return {
49
+ version: defaultVersion,
50
+ err: `Failed to fetch latest @types/node version, using fallback version ${defaultVersion}`
51
+ };
52
+ }
53
+ };
54
+ // Annotate the CommonJS export names for ESM import in node:
55
+ 0 && (module.exports = {
56
+ getNodeTypesVersion
57
+ });
58
+ //# sourceMappingURL=getNodeTypesVersion.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cli/migrate/nodeVersion/getNodeTypesVersion.ts"],
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport { gt, satisfies, valid } from 'semver';\n\nimport { log } from '../../../utils/logging';\nimport { getNpmVersions } from '../../../utils/version';\n\ntype VersionResult = {\n version: string;\n err?: string;\n};\n\nexport const getNodeTypesVersion = async (\n major: number,\n defaultVersion: string,\n): Promise<VersionResult> => {\n try {\n const versions = await getNpmVersions('@types/node');\n\n const matchingVersions = Object.values(versions ?? {}).filter(\n (v) =>\n valid(v.version) &&\n satisfies(v.version, `${major}.x.x`) &&\n !v.deprecated,\n );\n\n if (!matchingVersions.length) {\n return {\n version: defaultVersion,\n err: `No matching @types/node versions for Node.js ${major}`,\n };\n }\n\n const { version } = matchingVersions.reduce((a, b) =>\n gt(a.version, b.version) ? a : b,\n );\n\n return {\n version,\n };\n } catch (err) {\n log.subtle(inspect(err));\n return {\n version: defaultVersion,\n err: `Failed to fetch latest @types/node version, using fallback version ${defaultVersion}`,\n };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,oBAAqC;AAErC,qBAAoB;AACpB,qBAA+B;AAOxB,MAAM,sBAAsB,OACjC,OACA,mBAC2B;AAC3B,MAAI;AACF,UAAM,WAAW,UAAM,+BAAe,aAAa;AAEnD,UAAM,mBAAmB,OAAO,OAAO,YAAY,CAAC,CAAC,EAAE;AAAA,MACrD,CAAC,UACC,qBAAM,EAAE,OAAO,SACf,yBAAU,EAAE,SAAS,GAAG,KAAK,MAAM,KACnC,CAAC,EAAE;AAAA,IACP;AAEA,QAAI,CAAC,iBAAiB,QAAQ;AAC5B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK,gDAAgD,KAAK;AAAA,MAC5D;AAAA,IACF;AAEA,UAAM,EAAE,QAAQ,IAAI,iBAAiB;AAAA,MAAO,CAAC,GAAG,UAC9C,kBAAG,EAAE,SAAS,EAAE,OAAO,IAAI,IAAI;AAAA,IACjC;AAEA,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,KAAK,sEAAsE,cAAc;AAAA,IAC3F;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -1 +1,5 @@
1
- export declare const nodeVersionMigration: (version: number, dir?: string) => Promise<void>;
1
+ export declare const nodeVersionMigration: ({ nodeVersion, ECMAScriptVersion, defaultNodeTypesVersion, }: {
2
+ nodeVersion: number;
3
+ ECMAScriptVersion: string;
4
+ defaultNodeTypesVersion: string;
5
+ }, dir?: string) => Promise<void>;
@@ -36,70 +36,153 @@ var import_fast_glob = require("fast-glob");
36
36
  var import_fs_extra = __toESM(require("fs-extra"));
37
37
  var import_logging = require("../../../utils/logging");
38
38
  var import_project = require("../../configure/analysis/project");
39
- const subPatches = [
40
- { file: ".nvmrc", replace: "<%- version %>\n" },
39
+ var import_checks = require("./checks");
40
+ var import_getNodeTypesVersion = require("./getNodeTypesVersion");
41
+ const subPatches = ({
42
+ nodeVersion,
43
+ nodeTypesVersion,
44
+ ECMAScriptVersion
45
+ }) => [
46
+ { file: ".nvmrc", replace: `${nodeVersion}
47
+ ` },
41
48
  {
42
- files: "Dockerfile*",
43
- test: /^FROM(.*) node:[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?( .+|)$/gm,
44
- replace: "FROM$1 node:<%- version %>$3$4"
49
+ files: "**/Dockerfile*",
50
+ regex: /^FROM(.*) (public.ecr.aws\/docker\/library\/)?node:([0-9]+(?:\.[0-9]+(?:\.[0-9]+)?)?)(-[a-z0-9]+)?(@sha256:[a-f0-9]{64})?( .*)?$/gm,
51
+ replace: `FROM$1 $2node:${nodeVersion}$4$6`
45
52
  },
46
53
  {
47
- files: "Dockerfile*",
48
- test: /^FROM(.*) gcr.io\/distroless\/nodejs\d+-debian(.+)$/gm,
49
- replace: "FROM$1 gcr.io/distroless/nodejs<%- version %>-debian$2"
54
+ files: "**/Dockerfile*",
55
+ regex: /^FROM(.*) gcr.io\/distroless\/nodejs\d+-debian(\d+)(@sha256:[a-f0-9]{64})?(\.[^- \n]+)?(-[^ \n]+)?( .+|)$/gm,
56
+ replace: `FROM$1 gcr.io/distroless/nodejs${nodeVersion}-debian$2$4$5$6`
50
57
  },
51
58
  {
52
- files: "serverless*.y*ml",
53
- test: /nodejs\d+.x/gm,
54
- replace: "nodejs<%- version %>.x"
59
+ files: "**/serverless*.y*ml",
60
+ regex: /\bnodejs\d+.x\b/gm,
61
+ tests: [import_checks.isPatchableServerlessVersion],
62
+ replace: `nodejs${nodeVersion}.x`
55
63
  },
56
64
  {
57
- files: "infra/**/*.ts",
58
- test: /NODEJS_\d+_X/g,
59
- replace: "NODEJS_<%- version %>_X"
65
+ files: "**/serverless*.y*ml",
66
+ regex: /\bnode\d+\b/gm,
67
+ tests: [import_checks.isPatchableServerlessVersion],
68
+ replace: `node${nodeVersion}`
60
69
  },
61
70
  {
62
- files: ".buildkite/*",
63
- test: /image: node:[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
64
- replace: "image: node:<%- version %>$2"
71
+ files: "**/infra/**/*.ts",
72
+ regex: /NODEJS_\d+_X/g,
73
+ replace: `NODEJS_${nodeVersion}_X`
74
+ },
75
+ {
76
+ files: "**/infra/**/*.ts",
77
+ regex: /(target:\s*'node)(\d+)(.+)$/gm,
78
+ replace: `$1${nodeVersion}$3`
79
+ },
80
+ {
81
+ files: "**/.buildkite/*",
82
+ regex: /(image: )(public.ecr.aws\/docker\/library\/)?(node:)[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
83
+ replace: `$1$2$3${nodeVersion}$5`
84
+ },
85
+ {
86
+ files: ".node-version*",
87
+ regex: /(\d+(?:\.\d+)*)/g,
88
+ replace: `${nodeVersion}`
89
+ },
90
+ {
91
+ files: "**/package.json",
92
+ regex: /("@types\/node":\s*")(\^)?(\d+\.\d+\.\d+)(")/gm,
93
+ tests: [import_checks.isPatchableServerlessVersion],
94
+ replace: `$1$2${nodeTypesVersion}$4`
95
+ },
96
+ {
97
+ files: "**/package.json",
98
+ regex: /(["']engines["']:\s*{[\s\S]*?["']node["']:\s*["']>=)(\d+(?:\.\d+)*)(['"]\s*})/gm,
99
+ tests: [import_checks.isPatchableServerlessVersion, import_checks.isPatchableSkubaType],
100
+ replace: `$1${nodeVersion}$3`
101
+ },
102
+ {
103
+ files: "**/tsconfig*.json",
104
+ regex: /("target":\s*")(ES\d+)"/gim,
105
+ tests: [import_checks.isPatchableServerlessVersion, import_checks.isPatchableSkubaType],
106
+ replace: `$1${ECMAScriptVersion}"`
107
+ },
108
+ {
109
+ files: "**/tsconfig*.json",
110
+ regex: /("lib":\s*\[)([\S\s]*?)(ES\d+)([\S\s]*?)(\])/gim,
111
+ tests: [import_checks.isPatchableServerlessVersion, import_checks.isPatchableSkubaType],
112
+ replace: `$1$2${ECMAScriptVersion}$4$5`
113
+ },
114
+ {
115
+ files: "**/docker-compose*.y*ml",
116
+ regex: /(image: )(public.ecr.aws\/docker\/library\/)?(node:)[0-9.]+(\.[^- \n]+)?(-[^ \n]+)?$/gm,
117
+ replace: `$1$2$3${nodeVersion}$5`
65
118
  }
66
119
  ];
67
- const runSubPatch = async (version, dir, patch) => {
120
+ const runSubPatch = async (dir, patch) => {
68
121
  const readFile = (0, import_project.createDestinationFileReader)(dir);
69
122
  const paths = patch.file ? [patch.file] : await (0, import_fast_glob.glob)(patch.files ?? [], { cwd: dir });
70
123
  await Promise.all(
71
124
  paths.map(async (path) => {
125
+ if (path.includes("node_modules")) {
126
+ return;
127
+ }
72
128
  const contents = await readFile(path);
73
129
  if (!contents) {
74
130
  return;
75
131
  }
76
- if (patch.test && !patch.test.test(contents)) {
132
+ if (patch.regex && !patch.regex.test(contents)) {
77
133
  return;
78
134
  }
79
- const templated = patch.replace.replaceAll(
80
- "<%- version %>",
81
- version.toString()
82
- );
83
- await import_fs_extra.default.promises.writeFile(
135
+ if (patch.tests) {
136
+ const results = await Promise.all(patch.tests.map((test) => test()));
137
+ if (!results.every(Boolean)) {
138
+ return;
139
+ }
140
+ }
141
+ await writePatchedContents({
84
142
  path,
85
- patch.test ? contents.replaceAll(patch.test, templated) : templated
86
- );
143
+ contents,
144
+ templated: patch.replace,
145
+ regex: patch.regex
146
+ });
87
147
  })
88
148
  );
89
149
  };
90
- const upgrade = async (version, dir) => {
91
- await Promise.all(
92
- subPatches.map((subPatch) => runSubPatch(version, dir, subPatch))
93
- );
150
+ const writePatchedContents = async ({
151
+ path,
152
+ contents,
153
+ templated,
154
+ regex
155
+ }) => await import_fs_extra.default.promises.writeFile(
156
+ path,
157
+ regex ? contents.replaceAll(regex, templated) : templated
158
+ );
159
+ const upgrade = async (versions, dir) => {
160
+ for (const subPatch of subPatches(versions)) {
161
+ await runSubPatch(dir, subPatch);
162
+ }
94
163
  };
95
- const nodeVersionMigration = async (version, dir = process.cwd()) => {
96
- import_logging.log.ok(`Upgrading to Node.js ${version}`);
164
+ const nodeVersionMigration = async ({
165
+ nodeVersion,
166
+ ECMAScriptVersion,
167
+ defaultNodeTypesVersion
168
+ }, dir = process.cwd()) => {
169
+ import_logging.log.ok(`Upgrading to Node.js ${nodeVersion}`);
97
170
  try {
98
- await upgrade(version, dir);
99
- import_logging.log.ok("Upgraded to Node.js", version);
100
- } catch (err) {
171
+ if (!await (0, import_checks.isPatchableNodeVersion)(nodeVersion)) {
172
+ throw new Error("Node.js version is not patchable");
173
+ }
174
+ const { version: nodeTypesVersion, err } = await (0, import_getNodeTypesVersion.getNodeTypesVersion)(
175
+ nodeVersion,
176
+ defaultNodeTypesVersion
177
+ );
178
+ if (err) {
179
+ import_logging.log.warn(err);
180
+ }
181
+ await upgrade({ nodeVersion, nodeTypesVersion, ECMAScriptVersion }, dir);
182
+ import_logging.log.ok("Upgraded to Node.js", nodeVersion);
183
+ } catch (error) {
101
184
  import_logging.log.err("Failed to upgrade");
102
- import_logging.log.subtle((0, import_util.inspect)(err));
185
+ import_logging.log.subtle((0, import_util.inspect)(error));
103
186
  process.exitCode = 1;
104
187
  }
105
188
  };
@@ -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\ntype SubPatch = (\n | { files: string; file?: never }\n | { file: string; files?: never }\n) & {\n test?: RegExp;\n replace: string;\n};\n\nconst subPatches: SubPatch[] = [\n { file: '.nvmrc', replace: '<%- version %>\\n' },\n {\n files: 'Dockerfile*',\n test: /^FROM(.*) node:[0-9.]+(\\.[^- \\n]+)?(-[^ \\n]+)?( .+|)$/gm,\n replace: 'FROM$1 node:<%- version %>$3$4',\n },\n {\n files: 'Dockerfile*',\n test: /^FROM(.*) gcr.io\\/distroless\\/nodejs\\d+-debian(.+)$/gm,\n replace: 'FROM$1 gcr.io/distroless/nodejs<%- version %>-debian$2',\n },\n {\n files: 'serverless*.y*ml',\n test: /nodejs\\d+.x/gm,\n replace: 'nodejs<%- version %>.x',\n },\n {\n files: 'infra/**/*.ts',\n test: /NODEJS_\\d+_X/g,\n replace: 'NODEJS_<%- version %>_X',\n },\n {\n files: '.buildkite/*',\n test: /image: node:[0-9.]+(\\.[^- \\n]+)?(-[^ \\n]+)?$/gm,\n replace: 'image: node:<%- version %>$2',\n },\n];\n\nconst runSubPatch = async (version: number, dir: string, patch: SubPatch) => {\n const readFile = createDestinationFileReader(dir);\n const paths = patch.file\n ? [patch.file]\n : await glob(patch.files ?? [], { cwd: dir });\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.test && !patch.test.test(contents)) {\n return;\n }\n\n const templated = patch.replace.replaceAll(\n '<%- version %>',\n version.toString(),\n );\n\n await fs.promises.writeFile(\n path,\n patch.test ? contents.replaceAll(patch.test, templated) : templated,\n );\n }),\n );\n};\n\nconst upgrade = async (version: number, dir: string) => {\n await Promise.all(\n subPatches.map((subPatch) => runSubPatch(version, dir, subPatch)),\n );\n};\n\nexport const nodeVersionMigration = async (\n version: number,\n dir = process.cwd(),\n) => {\n log.ok(`Upgrading to Node.js ${version}`);\n try {\n await upgrade(version, dir);\n log.ok('Upgraded to Node.js', version);\n } catch (err) {\n log.err('Failed to upgrade');\n log.subtle(inspect(err));\n process.exitCode = 1;\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAqB;AACrB,sBAAe;AAEf,qBAAoB;AACpB,qBAA4C;AAU5C,MAAM,aAAyB;AAAA,EAC7B,EAAE,MAAM,UAAU,SAAS,mBAAmB;AAAA,EAC9C;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAEA,MAAM,cAAc,OAAO,SAAiB,KAAa,UAAoB;AAC3E,QAAM,eAAW,4CAA4B,GAAG;AAChD,QAAM,QAAQ,MAAM,OAChB,CAAC,MAAM,IAAI,IACX,UAAM,uBAAK,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAE9C,QAAM,QAAQ;AAAA,IACZ,MAAM,IAAI,OAAO,SAAS;AACxB,YAAM,WAAW,MAAM,SAAS,IAAI;AACpC,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AAEA,UAAI,MAAM,QAAQ,CAAC,MAAM,KAAK,KAAK,QAAQ,GAAG;AAC5C;AAAA,MACF;AAEA,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B;AAAA,QACA,QAAQ,SAAS;AAAA,MACnB;AAEA,YAAM,gBAAAA,QAAG,SAAS;AAAA,QAChB;AAAA,QACA,MAAM,OAAO,SAAS,WAAW,MAAM,MAAM,SAAS,IAAI;AAAA,MAC5D;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,MAAM,UAAU,OAAO,SAAiB,QAAgB;AACtD,QAAM,QAAQ;AAAA,IACZ,WAAW,IAAI,CAAC,aAAa,YAAY,SAAS,KAAK,QAAQ,CAAC;AAAA,EAClE;AACF;AAEO,MAAM,uBAAuB,OAClC,SACA,MAAM,QAAQ,IAAI,MACf;AACH,qBAAI,GAAG,wBAAwB,OAAO,EAAE;AACxC,MAAI;AACF,UAAM,QAAQ,SAAS,GAAG;AAC1B,uBAAI,GAAG,uBAAuB,OAAO;AAAA,EACvC,SAAS,KAAK;AACZ,uBAAI,IAAI,mBAAmB;AAC3B,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,YAAQ,WAAW;AAAA,EACrB;AACF;",
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';\nimport { getNodeTypesVersion } from './getNodeTypesVersion';\n\ntype FileSelector =\n | { files: string; file?: never }\n | { file: string; files?: never };\n\ntype SubPatch = FileSelector & {\n tests?: Array<() => Promise<boolean>>;\n regex?: RegExp;\n replace: string;\n};\n\nconst subPatches = ({\n nodeVersion,\n nodeTypesVersion,\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: /(\"@types\\/node\":\\s*\")(\\^)?(\\d+\\.\\d+\\.\\d+)(\")/gm,\n tests: [isPatchableServerlessVersion],\n replace: `$1$2${nodeTypesVersion}$4`,\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 nodeTypesVersion: string;\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 ?? [], { cwd: dir });\n\n await Promise.all(\n paths.map(async (path) => {\n if (path.includes('node_modules')) {\n return;\n }\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(patch.tests.map((test) => test()));\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 defaultNodeTypesVersion,\n }: {\n nodeVersion: number;\n ECMAScriptVersion: string;\n defaultNodeTypesVersion: string;\n },\n dir = process.cwd(),\n) => {\n log.ok(`Upgrading to Node.js ${nodeVersion}`);\n try {\n if (!(await isPatchableNodeVersion(nodeVersion))) {\n throw new Error('Node.js version is not patchable');\n }\n\n const { version: nodeTypesVersion, err } = await getNodeTypesVersion(\n nodeVersion,\n defaultNodeTypesVersion,\n );\n if (err) {\n log.warn(err);\n }\n await upgrade({ nodeVersion, nodeTypesVersion, ECMAScriptVersion }, dir);\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/lib/index.js CHANGED
@@ -26,15 +26,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var src_exports = {};
30
- __export(src_exports, {
29
+ var index_exports = {};
30
+ __export(index_exports, {
31
31
  Buildkite: () => Buildkite,
32
32
  Git: () => Git,
33
33
  GitHub: () => GitHub,
34
34
  Jest: () => Jest,
35
35
  Net: () => Net
36
36
  });
37
- module.exports = __toCommonJS(src_exports);
37
+ module.exports = __toCommonJS(index_exports);
38
38
  var Buildkite = __toESM(require("./api/buildkite"));
39
39
  var Git = __toESM(require("./api/git"));
40
40
  var GitHub = __toESM(require("./api/github"));
@@ -1,4 +1,4 @@
1
- export type TextProcessor = (contents: string) => string;
1
+ export type TextProcessor = (sourcePath: string, contents: string) => string;
2
2
  export declare const copyFile: (sourcePath: string, destinationPath: string, { overwrite, processors, }: Pick<CopyFilesOptions, "overwrite" | "processors">) => Promise<void>;
3
3
  interface CopyFilesOptions {
4
4
  sourceRoot: string;
package/lib/utils/copy.js CHANGED
@@ -45,7 +45,7 @@ const copyFile = async (sourcePath, destinationPath, {
45
45
  }) => {
46
46
  const oldContents = await import_fs_extra.default.promises.readFile(sourcePath, "utf8");
47
47
  const newContents = processors.reduce(
48
- (contents, process) => process(contents),
48
+ (contents, process) => process(sourcePath, contents),
49
49
  oldContents
50
50
  );
51
51
  if (oldContents === newContents && sourcePath === destinationPath) {
@@ -62,8 +62,16 @@ const copyFile = async (sourcePath, destinationPath, {
62
62
  throw err;
63
63
  }
64
64
  };
65
- const createEjsRenderer = (templateData) => (contents) => import_ejs.default.render(contents, templateData);
66
- const createStringReplacer = (replacements) => (contents) => replacements.reduce(
65
+ const createEjsRenderer = (templateData) => (sourcePath, contents) => {
66
+ try {
67
+ return import_ejs.default.render(contents, templateData, { strict: false });
68
+ } catch (err) {
69
+ import_logging.log.err("Failed to render", import_logging.log.bold(sourcePath));
70
+ import_logging.log.subtle(err);
71
+ return contents;
72
+ }
73
+ };
74
+ const createStringReplacer = (replacements) => (_sourcePath, contents) => replacements.reduce(
67
75
  (newContents, { input, output }) => newContents.replace(input, output),
68
76
  contents
69
77
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/copy.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport ejs from 'ejs';\nimport fs from 'fs-extra';\n\nimport { isErrorWithCode } from './error';\nimport { log } from './logging';\n\nexport type TextProcessor = (contents: string) => string;\n\nexport const copyFile = async (\n sourcePath: string,\n destinationPath: string,\n {\n overwrite = true,\n processors,\n }: Pick<CopyFilesOptions, 'overwrite' | 'processors'>,\n) => {\n const oldContents = await fs.promises.readFile(sourcePath, 'utf8');\n\n const newContents = processors.reduce(\n (contents, process) => process(contents),\n oldContents,\n );\n\n if (oldContents === newContents && sourcePath === destinationPath) {\n return;\n }\n\n try {\n await fs.promises.writeFile(destinationPath, newContents, {\n flag: overwrite ? 'w' : 'wx',\n });\n } catch (err) {\n if (isErrorWithCode(err, 'EEXIST')) {\n return;\n }\n\n throw err;\n }\n};\n\ninterface CopyFilesOptions {\n sourceRoot: string;\n destinationRoot: string;\n\n include: (pathname: string) => boolean;\n overwrite?: boolean;\n processors: TextProcessor[];\n stripUnderscorePrefix?: boolean;\n}\n\nexport const createEjsRenderer =\n (templateData: Record<string, unknown>): TextProcessor =>\n (contents) =>\n ejs.render(contents, templateData);\n\nexport const createStringReplacer =\n (\n replacements: Array<{\n input: RegExp;\n output: string;\n }>,\n ): TextProcessor =>\n (contents) =>\n replacements.reduce(\n (newContents, { input, output }) => newContents.replace(input, output),\n contents,\n );\n\nexport const copyFiles = async (\n opts: CopyFilesOptions,\n currentSourceDir: string = opts.sourceRoot,\n currentDestinationDir: string = opts.destinationRoot,\n) => {\n const filenames = await fs.promises.readdir(currentSourceDir);\n\n const toDestinationPath = (filename: string) =>\n path.join(\n currentDestinationDir,\n opts.stripUnderscorePrefix\n ? filename\n .replace(/^_\\./, '.')\n .replace(/^_package\\.json/, 'package.json')\n .replace(/^_eslint\\.config\\.js/, 'eslint.config.js')\n : filename,\n );\n\n const filteredFilenames = filenames.filter((filename) =>\n opts.include(\n path.relative(opts.destinationRoot, toDestinationPath(filename)),\n ),\n );\n\n await Promise.all(\n filteredFilenames.map(async (filename) => {\n const sourcePath = path.join(currentSourceDir, filename);\n const destinationPath = toDestinationPath(filename);\n\n try {\n await copyFile(sourcePath, destinationPath, opts);\n } catch (err) {\n if (isErrorWithCode(err, 'EISDIR')) {\n await fs.promises.mkdir(destinationPath, { recursive: true });\n return copyFiles(opts, sourcePath, destinationPath);\n }\n\n log.err('Failed to render', log.bold(sourcePath));\n\n throw err;\n }\n }),\n );\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,iBAAgB;AAChB,sBAAe;AAEf,mBAAgC;AAChC,qBAAoB;AAIb,MAAM,WAAW,OACtB,YACA,iBACA;AAAA,EACE,YAAY;AAAA,EACZ;AACF,MACG;AACH,QAAM,cAAc,MAAM,gBAAAA,QAAG,SAAS,SAAS,YAAY,MAAM;AAEjE,QAAM,cAAc,WAAW;AAAA,IAC7B,CAAC,UAAU,YAAY,QAAQ,QAAQ;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,gBAAgB,eAAe,eAAe,iBAAiB;AACjE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,gBAAAA,QAAG,SAAS,UAAU,iBAAiB,aAAa;AAAA,MACxD,MAAM,YAAY,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAI,8BAAgB,KAAK,QAAQ,GAAG;AAClC;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AACF;AAYO,MAAM,oBACX,CAAC,iBACD,CAAC,aACC,WAAAC,QAAI,OAAO,UAAU,YAAY;AAE9B,MAAM,uBACX,CACE,iBAKF,CAAC,aACC,aAAa;AAAA,EACX,CAAC,aAAa,EAAE,OAAO,OAAO,MAAM,YAAY,QAAQ,OAAO,MAAM;AAAA,EACrE;AACF;AAEG,MAAM,YAAY,OACvB,MACA,mBAA2B,KAAK,YAChC,wBAAgC,KAAK,oBAClC;AACH,QAAM,YAAY,MAAM,gBAAAD,QAAG,SAAS,QAAQ,gBAAgB;AAE5D,QAAM,oBAAoB,CAAC,aACzB,YAAAE,QAAK;AAAA,IACH;AAAA,IACA,KAAK,wBACD,SACG,QAAQ,QAAQ,GAAG,EACnB,QAAQ,mBAAmB,cAAc,EACzC,QAAQ,wBAAwB,kBAAkB,IACrD;AAAA,EACN;AAEF,QAAM,oBAAoB,UAAU;AAAA,IAAO,CAAC,aAC1C,KAAK;AAAA,MACH,YAAAA,QAAK,SAAS,KAAK,iBAAiB,kBAAkB,QAAQ,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,kBAAkB,IAAI,OAAO,aAAa;AACxC,YAAM,aAAa,YAAAA,QAAK,KAAK,kBAAkB,QAAQ;AACvD,YAAM,kBAAkB,kBAAkB,QAAQ;AAElD,UAAI;AACF,cAAM,SAAS,YAAY,iBAAiB,IAAI;AAAA,MAClD,SAAS,KAAK;AACZ,gBAAI,8BAAgB,KAAK,QAAQ,GAAG;AAClC,gBAAM,gBAAAF,QAAG,SAAS,MAAM,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAC5D,iBAAO,UAAU,MAAM,YAAY,eAAe;AAAA,QACpD;AAEA,2BAAI,IAAI,oBAAoB,mBAAI,KAAK,UAAU,CAAC;AAEhD,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
4
+ "sourcesContent": ["import path from 'path';\n\nimport ejs from 'ejs';\nimport fs from 'fs-extra';\n\nimport { isErrorWithCode } from './error';\nimport { log } from './logging';\n\nexport type TextProcessor = (sourcePath: string, contents: string) => string;\n\nexport const copyFile = async (\n sourcePath: string,\n destinationPath: string,\n {\n overwrite = true,\n processors,\n }: Pick<CopyFilesOptions, 'overwrite' | 'processors'>,\n) => {\n const oldContents = await fs.promises.readFile(sourcePath, 'utf8');\n\n const newContents = processors.reduce(\n (contents, process) => process(sourcePath, contents),\n oldContents,\n );\n\n if (oldContents === newContents && sourcePath === destinationPath) {\n return;\n }\n\n try {\n await fs.promises.writeFile(destinationPath, newContents, {\n flag: overwrite ? 'w' : 'wx',\n });\n } catch (err) {\n if (isErrorWithCode(err, 'EEXIST')) {\n return;\n }\n\n throw err;\n }\n};\n\ninterface CopyFilesOptions {\n sourceRoot: string;\n destinationRoot: string;\n\n include: (pathname: string) => boolean;\n overwrite?: boolean;\n processors: TextProcessor[];\n stripUnderscorePrefix?: boolean;\n}\n\nexport const createEjsRenderer =\n (templateData: Record<string, unknown>): TextProcessor =>\n (sourcePath: string, contents) => {\n try {\n return ejs.render(contents, templateData, { strict: false });\n } catch (err) {\n log.err('Failed to render', log.bold(sourcePath));\n log.subtle(err);\n return contents;\n }\n };\n\nexport const createStringReplacer =\n (\n replacements: Array<{\n input: RegExp;\n output: string;\n }>,\n ): TextProcessor =>\n (_sourcePath: string, contents) =>\n replacements.reduce(\n (newContents, { input, output }) => newContents.replace(input, output),\n contents,\n );\n\nexport const copyFiles = async (\n opts: CopyFilesOptions,\n currentSourceDir: string = opts.sourceRoot,\n currentDestinationDir: string = opts.destinationRoot,\n) => {\n const filenames = await fs.promises.readdir(currentSourceDir);\n\n const toDestinationPath = (filename: string) =>\n path.join(\n currentDestinationDir,\n opts.stripUnderscorePrefix\n ? filename\n .replace(/^_\\./, '.')\n .replace(/^_package\\.json/, 'package.json')\n .replace(/^_eslint\\.config\\.js/, 'eslint.config.js')\n : filename,\n );\n\n const filteredFilenames = filenames.filter((filename) =>\n opts.include(\n path.relative(opts.destinationRoot, toDestinationPath(filename)),\n ),\n );\n\n await Promise.all(\n filteredFilenames.map(async (filename) => {\n const sourcePath = path.join(currentSourceDir, filename);\n const destinationPath = toDestinationPath(filename);\n\n try {\n await copyFile(sourcePath, destinationPath, opts);\n } catch (err) {\n if (isErrorWithCode(err, 'EISDIR')) {\n await fs.promises.mkdir(destinationPath, { recursive: true });\n return copyFiles(opts, sourcePath, destinationPath);\n }\n\n log.err('Failed to render', log.bold(sourcePath));\n\n throw err;\n }\n }),\n );\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,iBAAgB;AAChB,sBAAe;AAEf,mBAAgC;AAChC,qBAAoB;AAIb,MAAM,WAAW,OACtB,YACA,iBACA;AAAA,EACE,YAAY;AAAA,EACZ;AACF,MACG;AACH,QAAM,cAAc,MAAM,gBAAAA,QAAG,SAAS,SAAS,YAAY,MAAM;AAEjE,QAAM,cAAc,WAAW;AAAA,IAC7B,CAAC,UAAU,YAAY,QAAQ,YAAY,QAAQ;AAAA,IACnD;AAAA,EACF;AAEA,MAAI,gBAAgB,eAAe,eAAe,iBAAiB;AACjE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,gBAAAA,QAAG,SAAS,UAAU,iBAAiB,aAAa;AAAA,MACxD,MAAM,YAAY,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAI,8BAAgB,KAAK,QAAQ,GAAG;AAClC;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AACF;AAYO,MAAM,oBACX,CAAC,iBACD,CAAC,YAAoB,aAAa;AAChC,MAAI;AACF,WAAO,WAAAC,QAAI,OAAO,UAAU,cAAc,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC7D,SAAS,KAAK;AACZ,uBAAI,IAAI,oBAAoB,mBAAI,KAAK,UAAU,CAAC;AAChD,uBAAI,OAAO,GAAG;AACd,WAAO;AAAA,EACT;AACF;AAEK,MAAM,uBACX,CACE,iBAKF,CAAC,aAAqB,aACpB,aAAa;AAAA,EACX,CAAC,aAAa,EAAE,OAAO,OAAO,MAAM,YAAY,QAAQ,OAAO,MAAM;AAAA,EACrE;AACF;AAEG,MAAM,YAAY,OACvB,MACA,mBAA2B,KAAK,YAChC,wBAAgC,KAAK,oBAClC;AACH,QAAM,YAAY,MAAM,gBAAAD,QAAG,SAAS,QAAQ,gBAAgB;AAE5D,QAAM,oBAAoB,CAAC,aACzB,YAAAE,QAAK;AAAA,IACH;AAAA,IACA,KAAK,wBACD,SACG,QAAQ,QAAQ,GAAG,EACnB,QAAQ,mBAAmB,cAAc,EACzC,QAAQ,wBAAwB,kBAAkB,IACrD;AAAA,EACN;AAEF,QAAM,oBAAoB,UAAU;AAAA,IAAO,CAAC,aAC1C,KAAK;AAAA,MACH,YAAAA,QAAK,SAAS,KAAK,iBAAiB,kBAAkB,QAAQ,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,kBAAkB,IAAI,OAAO,aAAa;AACxC,YAAM,aAAa,YAAAA,QAAK,KAAK,kBAAkB,QAAQ;AACvD,YAAM,kBAAkB,kBAAkB,QAAQ;AAElD,UAAI;AACF,cAAM,SAAS,YAAY,iBAAiB,IAAI;AAAA,MAClD,SAAS,KAAK;AACZ,gBAAI,8BAAgB,KAAK,QAAQ,GAAG;AAClC,gBAAM,gBAAAF,QAAG,SAAS,MAAM,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAC5D,iBAAO,UAAU,MAAM,YAAY,eAAe;AAAA,QACpD;AAEA,2BAAI,IAAI,oBAAoB,mBAAI,KAAK,UAAU,CAAC;AAEhD,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
6
6
  "names": ["fs", "ejs", "path"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
- export declare const TEMPLATE_NAMES: readonly ["express-rest-api", "greeter", "koa-rest-api", "lambda-sqs-worker", "lambda-sqs-worker-cdk", "oss-npm-package", "private-npm-package"];
2
+ export declare const TEMPLATE_NAMES: readonly ["express-rest-api", "greeter", "koa-rest-api", "lambda-sqs-worker-cdk", "oss-npm-package", "private-npm-package"];
3
3
  export type TemplateName = (typeof TEMPLATE_NAMES)[number];
4
- export declare const TEMPLATE_NAMES_WITH_BYO: readonly ["express-rest-api", "greeter", "koa-rest-api", "lambda-sqs-worker", "lambda-sqs-worker-cdk", "oss-npm-package", "private-npm-package", "github →"];
4
+ export declare const TEMPLATE_NAMES_WITH_BYO: readonly ["express-rest-api", "greeter", "koa-rest-api", "lambda-sqs-worker-cdk", "oss-npm-package", "private-npm-package", "github →"];
5
5
  interface TemplateDocumentationConfig {
6
6
  /**
7
7
  * The semantic version in which the template was first added.
@@ -48,7 +48,6 @@ const TEMPLATE_NAMES = [
48
48
  "express-rest-api",
49
49
  "greeter",
50
50
  "koa-rest-api",
51
- "lambda-sqs-worker",
52
51
  "lambda-sqs-worker-cdk",
53
52
  "oss-npm-package",
54
53
  "private-npm-package"
@@ -67,10 +66,6 @@ const TEMPLATE_DOCUMENTATION_CONFIG = {
67
66
  added: "3.4.1",
68
67
  filename: "api.md"
69
68
  },
70
- "lambda-sqs-worker": {
71
- added: "3.4.1",
72
- filename: "worker.md"
73
- },
74
69
  "lambda-sqs-worker-cdk": {
75
70
  added: "3.13.0",
76
71
  filename: "worker.md"
@@ -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';\nimport { packageManagerSchema } from './packageManager';\n\nexport const TEMPLATE_NAMES = [\n 'express-rest-api',\n 'greeter',\n 'koa-rest-api',\n 'lambda-sqs-worker',\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': {\n added: '3.4.1',\n filename: 'worker.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;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,qBAAqB;AAAA,IACnB,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 { z } from 'zod';\n\nimport { projectTypeSchema } from './manifest';\nimport { packageManagerSchema } from './packageManager';\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;",
6
6
  "names": ["path", "fs"]
7
7
  }
@@ -1,4 +1,20 @@
1
- export declare const latestNpmVersion: (packageName: string) => Promise<string>;
1
+ import { z } from 'zod';
2
+ declare const NpmVersions: z.ZodRecord<z.ZodString, z.ZodObject<{
3
+ name: z.ZodString;
4
+ version: z.ZodString;
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
+ }>>;
15
+ export type NpmVersions = z.infer<typeof NpmVersions>;
16
+ export declare const getNpmVersions: (packageName: string) => Promise<NpmVersions | null>;
17
+ export declare const getLatestNpmVersion: (packageName: string) => Promise<string | null>;
2
18
  export declare const getSkubaVersion: () => Promise<string>;
3
19
  type SkubaVersionInfo = {
4
20
  isStale: true;
@@ -28,31 +28,60 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var version_exports = {};
30
30
  __export(version_exports, {
31
+ getLatestNpmVersion: () => getLatestNpmVersion,
32
+ getNpmVersions: () => getNpmVersions,
31
33
  getSkubaVersion: () => getSkubaVersion,
32
- getSkubaVersionInfo: () => getSkubaVersionInfo,
33
- latestNpmVersion: () => latestNpmVersion
34
+ getSkubaVersionInfo: () => getSkubaVersionInfo
34
35
  });
35
36
  module.exports = __toCommonJS(version_exports);
36
- var import_libnpmsearch = __toESM(require("libnpmsearch"));
37
- var import_validate_npm_package_name = __toESM(require("validate-npm-package-name"));
37
+ var import_npm_registry_fetch = __toESM(require("npm-registry-fetch"));
38
+ var import_zod = require("zod");
38
39
  var import_manifest = require("./manifest");
39
40
  var import_wait = require("./wait");
40
- const latestNpmVersion = async (packageName) => {
41
- const { validForNewPackages } = (0, import_validate_npm_package_name.default)(packageName);
42
- if (!validForNewPackages) {
43
- throw new Error(`Package "${packageName}" does not have a valid name`);
44
- }
45
- const [result] = await (0, import_libnpmsearch.default)(packageName, { limit: 1, timeout: 5e3 });
46
- if (result?.name !== packageName) {
47
- throw new Error(
48
- `Package "${packageName}" does not exist on the npm registry`
49
- );
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()
47
+ })
48
+ );
49
+ const PackageResponse = import_zod.z.object({
50
+ "dist-tags": import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional(),
51
+ versions: NpmVersions
52
+ });
53
+ const getNpmPackage = async (packageName) => {
54
+ try {
55
+ const response = await import_npm_registry_fetch.default.json(packageName, {
56
+ headers: {
57
+ Accept: "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"
58
+ }
59
+ });
60
+ const parsedResponse = PackageResponse.safeParse(response);
61
+ if (!parsedResponse.success) {
62
+ throw new Error(
63
+ `Failed to parse package response from npm for package ${packageName}`
64
+ );
65
+ }
66
+ return parsedResponse.data;
67
+ } catch (error) {
68
+ if (error instanceof Error && "statusCode" in error && error.statusCode === 404) {
69
+ return null;
70
+ }
71
+ throw error;
50
72
  }
51
- return result.version;
73
+ };
74
+ const getNpmVersions = async (packageName) => {
75
+ const response = await getNpmPackage(packageName);
76
+ return response?.versions ?? null;
77
+ };
78
+ const getLatestNpmVersion = async (packageName) => {
79
+ const response = await getNpmPackage(packageName);
80
+ return response?.["dist-tags"]?.latest ?? null;
52
81
  };
53
82
  const latestSkubaVersion = async () => {
54
83
  try {
55
- const result = await (0, import_wait.withTimeout)(latestNpmVersion("skuba"), { s: 2 });
84
+ const result = await (0, import_wait.withTimeout)(getLatestNpmVersion("skuba"), { s: 2 });
56
85
  return result.ok ? result.value : null;
57
86
  } catch {
58
87
  return null;
@@ -82,8 +111,9 @@ const getSkubaVersionInfo = async () => {
82
111
  };
83
112
  // Annotate the CommonJS export names for ESM import in node:
84
113
  0 && (module.exports = {
114
+ getLatestNpmVersion,
115
+ getNpmVersions,
85
116
  getSkubaVersion,
86
- getSkubaVersionInfo,
87
- latestNpmVersion
117
+ getSkubaVersionInfo
88
118
  });
89
119
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/version.ts"],
4
- "sourcesContent": ["import searchNpm from 'libnpmsearch';\nimport validatePackageName from 'validate-npm-package-name';\n\nimport { getSkubaManifest } from './manifest';\nimport { withTimeout } from './wait';\n\nexport const latestNpmVersion = async (\n packageName: string,\n): Promise<string> => {\n const { validForNewPackages } = validatePackageName(packageName);\n\n if (!validForNewPackages) {\n throw new Error(`Package \"${packageName}\" does not have a valid name`);\n }\n\n const [result] = await searchNpm(packageName, { limit: 1, timeout: 5_000 });\n\n if (result?.name !== packageName) {\n throw new Error(\n `Package \"${packageName}\" does not exist on the npm registry`,\n );\n }\n\n return result.version;\n};\n\nconst latestSkubaVersion = async (): Promise<string | null> => {\n try {\n const result = await withTimeout(latestNpmVersion('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,0BAAsB;AACtB,uCAAgC;AAEhC,sBAAiC;AACjC,kBAA4B;AAErB,MAAM,mBAAmB,OAC9B,gBACoB;AACpB,QAAM,EAAE,oBAAoB,QAAI,iCAAAA,SAAoB,WAAW;AAE/D,MAAI,CAAC,qBAAqB;AACxB,UAAM,IAAI,MAAM,YAAY,WAAW,8BAA8B;AAAA,EACvE;AAEA,QAAM,CAAC,MAAM,IAAI,UAAM,oBAAAC,SAAU,aAAa,EAAE,OAAO,GAAG,SAAS,IAAM,CAAC;AAE1E,MAAI,QAAQ,SAAS,aAAa;AAChC,UAAM,IAAI;AAAA,MACR,YAAY,WAAW;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,OAAO;AAChB;AAEA,MAAM,qBAAqB,YAAoC;AAC7D,MAAI;AACF,UAAM,SAAS,UAAM,yBAAY,iBAAiB,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC;AAEpE,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
- "names": ["validatePackageName", "searchNpm"]
4
+ "sourcesContent": ["import npmFetch from 'npm-registry-fetch';\nimport { z } from 'zod';\n\nimport { getSkubaManifest } from './manifest';\nimport { withTimeout } from './wait';\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;",
6
+ "names": ["npmFetch"]
7
7
  }