skuba 9.0.0-main-20240924121500 → 9.0.0-main-20240928013837

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/api/github/issueComment.ts"],
4
- "sourcesContent": ["import type { Octokit } from '@octokit/rest';\n\nimport * as Git from '../git';\n\nimport { apiTokenFromEnvironment } from './environment';\nimport { createRestClient } from './octokit';\nimport { getPullRequestNumber } from './pullRequest';\n\nconst getUserId = async (client: Octokit): Promise<number> => {\n const { data } = await client.users.getAuthenticated();\n\n return data.id;\n};\n\n/**\n * https://docs.github.com/en/rest/reference/issues#create-an-issue-comment\n */\ninterface PutIssueCommentParameters {\n /**\n * The body of the issue comment.\n */\n body: string;\n\n /**\n * An internal identifier for the issue comment.\n *\n * This can be used to scope a given `put` to a particular comment, preventing\n * it from clobbering other comments from the same bot or user.\n *\n * The identifier is embedded as hidden content in the comment body.\n */\n internalId?: string;\n\n env?: Record<string, string | undefined>;\n\n /**\n * The number that identifies the GitHub issue.\n *\n * If this is not provided, the number will be inferred from the GitHub Repos\n * API by finding the latest pull request associated with the head commit.\n *\n * https://docs.github.com/en/rest/reference/repos#list-pull-requests-associated-with-a-commit\n */\n issueNumber?: number;\n\n /**\n * The ID of authenticated bot or user that is putting the issue comment.\n *\n * This drives our `put` behaviour, which tries to locate and edit an existing\n * comment before creating a new one. If this is not provided, the ID will be\n * inferred from the GitHub Users API.\n *\n * https://docs.github.com/en/rest/reference/users#get-the-authenticated-user\n *\n * If you're at SEEK and using BuildAgency's GitHub API integration, you may\n * use `'seek-build-agency'` as an optimisation to skip the user lookup.\n *\n * https://api.github.com/users/buildagencygitapitoken[bot]\n */\n userId?: number | 'seek-build-agency';\n}\n\ninterface IssueComment {\n id: number;\n}\n\n/**\n * Asynchronously creates or updates a GitHub issue comment.\n *\n * This emulates `put` behaviour by overwriting the first existing comment by\n * the same author on the issue, enabling use cases like a persistent bot\n * comment at the top of the pull request that reflects the current status of a\n * CI check.\n *\n * A `GITHUB_API_TOKEN` or `GITHUB_TOKEN` with write permissions must be present\n * on the environment.\n */\nexport const putIssueComment = async (\n params: PutIssueCommentParameters,\n): Promise<IssueComment> => {\n const env = params.env ?? process.env;\n\n const dir = process.cwd();\n\n const { owner, repo } = await Git.getOwnerAndRepo({ dir });\n\n const client = await createRestClient({ auth: apiTokenFromEnvironment() });\n\n const issueNumber =\n params.issueNumber ?? (await getPullRequestNumber({ client, env }));\n\n if (!issueNumber) {\n throw new Error('Failed to infer an issue number');\n }\n\n const comments = await client.issues.listComments({\n issue_number: issueNumber,\n owner,\n repo,\n });\n\n const userId: number =\n params.userId === 'seek-build-agency'\n ? // https://api.github.com/users/buildagencygitapitoken[bot]\n 87109344\n : params.userId ?? (await getUserId(client));\n\n const commentId = comments.data.find(\n (comment) =>\n comment.user?.id === userId &&\n (params.internalId\n ? comment.body?.endsWith(`\\n\\n<!-- ${params.internalId} -->`)\n : true),\n )?.id;\n\n const body = params.internalId\n ? [params.body.trim(), `<!-- ${params.internalId} -->`].join('\\n\\n')\n : params.body.trim();\n\n const response = await (commentId\n ? client.issues.updateComment({\n body,\n comment_id: commentId,\n issue_number: issueNumber,\n owner,\n repo,\n })\n : client.issues.createComment({\n body,\n issue_number: issueNumber,\n owner,\n repo,\n }));\n\n return {\n id: response.data.id,\n };\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,UAAqB;AAErB,yBAAwC;AACxC,qBAAiC;AACjC,yBAAqC;AAErC,MAAM,YAAY,OAAO,WAAqC;AAC5D,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,MAAM,iBAAiB;AAErD,SAAO,KAAK;AACd;AAiEO,MAAM,kBAAkB,OAC7B,WAC0B;AAC1B,QAAM,MAAM,OAAO,OAAO,QAAQ;AAElC,QAAM,MAAM,QAAQ,IAAI;AAExB,QAAM,EAAE,OAAO,KAAK,IAAI,MAAM,IAAI,gBAAgB,EAAE,IAAI,CAAC;AAEzD,QAAM,SAAS,UAAM,iCAAiB,EAAE,UAAM,4CAAwB,EAAE,CAAC;AAEzE,QAAM,cACJ,OAAO,eAAgB,UAAM,yCAAqB,EAAE,QAAQ,IAAI,CAAC;AAEnE,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AAEA,QAAM,WAAW,MAAM,OAAO,OAAO,aAAa;AAAA,IAChD,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,SACJ,OAAO,WAAW;AAAA;AAAA,IAEd;AAAA,MACA,OAAO,UAAW,MAAM,UAAU,MAAM;AAE9C,QAAM,YAAY,SAAS,KAAK;AAAA,IAC9B,CAAC,YACC,QAAQ,MAAM,OAAO,WACpB,OAAO,aACJ,QAAQ,MAAM,SAAS;AAAA;AAAA,OAAY,OAAO,UAAU,MAAM,IAC1D;AAAA,EACR,GAAG;AAEH,QAAM,OAAO,OAAO,aAChB,CAAC,OAAO,KAAK,KAAK,GAAG,QAAQ,OAAO,UAAU,MAAM,EAAE,KAAK,MAAM,IACjE,OAAO,KAAK,KAAK;AAErB,QAAM,WAAW,OAAO,YACpB,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC,IACD,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAEL,SAAO;AAAA,IACL,IAAI,SAAS,KAAK;AAAA,EACpB;AACF;",
4
+ "sourcesContent": ["import type { Octokit } from '@octokit/rest';\n\nimport * as Git from '../git';\n\nimport { apiTokenFromEnvironment } from './environment';\nimport { createRestClient } from './octokit';\nimport { getPullRequestNumber } from './pullRequest';\n\nconst getUserId = async (client: Octokit): Promise<number> => {\n const { data } = await client.users.getAuthenticated();\n\n return data.id;\n};\n\n/**\n * https://docs.github.com/en/rest/reference/issues#create-an-issue-comment\n */\ninterface PutIssueCommentParameters {\n /**\n * The body of the issue comment.\n */\n body: string;\n\n /**\n * An internal identifier for the issue comment.\n *\n * This can be used to scope a given `put` to a particular comment, preventing\n * it from clobbering other comments from the same bot or user.\n *\n * The identifier is embedded as hidden content in the comment body.\n */\n internalId?: string;\n\n env?: Record<string, string | undefined>;\n\n /**\n * The number that identifies the GitHub issue.\n *\n * If this is not provided, the number will be inferred from the GitHub Repos\n * API by finding the latest pull request associated with the head commit.\n *\n * https://docs.github.com/en/rest/reference/repos#list-pull-requests-associated-with-a-commit\n */\n issueNumber?: number;\n\n /**\n * The ID of authenticated bot or user that is putting the issue comment.\n *\n * This drives our `put` behaviour, which tries to locate and edit an existing\n * comment before creating a new one. If this is not provided, the ID will be\n * inferred from the GitHub Users API.\n *\n * https://docs.github.com/en/rest/reference/users#get-the-authenticated-user\n *\n * If you're at SEEK and using BuildAgency's GitHub API integration, you may\n * use `'seek-build-agency'` as an optimisation to skip the user lookup.\n *\n * https://api.github.com/users/buildagencygitapitoken[bot]\n */\n userId?: number | 'seek-build-agency';\n}\n\ninterface IssueComment {\n id: number;\n}\n\n/**\n * Asynchronously creates or updates a GitHub issue comment.\n *\n * This emulates `put` behaviour by overwriting the first existing comment by\n * the same author on the issue, enabling use cases like a persistent bot\n * comment at the top of the pull request that reflects the current status of a\n * CI check.\n *\n * A `GITHUB_API_TOKEN` or `GITHUB_TOKEN` with write permissions must be present\n * on the environment.\n */\nexport const putIssueComment = async (\n params: PutIssueCommentParameters,\n): Promise<IssueComment> => {\n const env = params.env ?? process.env;\n\n const dir = process.cwd();\n\n const { owner, repo } = await Git.getOwnerAndRepo({ dir });\n\n const client = await createRestClient({ auth: apiTokenFromEnvironment() });\n\n const issueNumber =\n params.issueNumber ?? (await getPullRequestNumber({ client, env }));\n\n if (!issueNumber) {\n throw new Error('Failed to infer an issue number');\n }\n\n const comments = await client.issues.listComments({\n issue_number: issueNumber,\n owner,\n repo,\n });\n\n const userId: number =\n params.userId === 'seek-build-agency'\n ? // https://api.github.com/users/buildagencygitapitoken[bot]\n 87109344\n : (params.userId ?? (await getUserId(client)));\n\n const commentId = comments.data.find(\n (comment) =>\n comment.user?.id === userId &&\n (params.internalId\n ? comment.body?.endsWith(`\\n\\n<!-- ${params.internalId} -->`)\n : true),\n )?.id;\n\n const body = params.internalId\n ? [params.body.trim(), `<!-- ${params.internalId} -->`].join('\\n\\n')\n : params.body.trim();\n\n const response = await (commentId\n ? client.issues.updateComment({\n body,\n comment_id: commentId,\n issue_number: issueNumber,\n owner,\n repo,\n })\n : client.issues.createComment({\n body,\n issue_number: issueNumber,\n owner,\n repo,\n }));\n\n return {\n id: response.data.id,\n };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,UAAqB;AAErB,yBAAwC;AACxC,qBAAiC;AACjC,yBAAqC;AAErC,MAAM,YAAY,OAAO,WAAqC;AAC5D,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,MAAM,iBAAiB;AAErD,SAAO,KAAK;AACd;AAiEO,MAAM,kBAAkB,OAC7B,WAC0B;AAC1B,QAAM,MAAM,OAAO,OAAO,QAAQ;AAElC,QAAM,MAAM,QAAQ,IAAI;AAExB,QAAM,EAAE,OAAO,KAAK,IAAI,MAAM,IAAI,gBAAgB,EAAE,IAAI,CAAC;AAEzD,QAAM,SAAS,UAAM,iCAAiB,EAAE,UAAM,4CAAwB,EAAE,CAAC;AAEzE,QAAM,cACJ,OAAO,eAAgB,UAAM,yCAAqB,EAAE,QAAQ,IAAI,CAAC;AAEnE,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AAEA,QAAM,WAAW,MAAM,OAAO,OAAO,aAAa;AAAA,IAChD,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,SACJ,OAAO,WAAW;AAAA;AAAA,IAEd;AAAA,MACC,OAAO,UAAW,MAAM,UAAU,MAAM;AAE/C,QAAM,YAAY,SAAS,KAAK;AAAA,IAC9B,CAAC,YACC,QAAQ,MAAM,OAAO,WACpB,OAAO,aACJ,QAAQ,MAAM,SAAS;AAAA;AAAA,OAAY,OAAO,UAAU,MAAM,IAC1D;AAAA,EACR,GAAG;AAEH,QAAM,OAAO,OAAO,aAChB,CAAC,OAAO,KAAK,KAAK,GAAG,QAAQ,OAAO,UAAU,MAAM,EAAE,KAAK,MAAM,IACjE,OAAO,KAAK,KAAK;AAErB,QAAM,WAAW,OAAO,YACpB,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC,IACD,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAEL,SAAO;AAAA,IACL,IAAI,SAAS,KAAK;AAAA,EACpB;AACF;",
6
6
  "names": []
7
7
  }
@@ -23,6 +23,7 @@ __export(__exports, {
23
23
  module.exports = __toCommonJS(__exports);
24
24
  var import_collapseDuplicateMergeKeys = require("./collapseDuplicateMergeKeys");
25
25
  var import_patchDockerCompose = require("./patchDockerCompose");
26
+ var import_patchDockerImages = require("./patchDockerImages");
26
27
  var import_upgradeESLint = require("./upgradeESLint");
27
28
  const patches = [
28
29
  {
@@ -36,6 +37,10 @@ const patches = [
36
37
  {
37
38
  apply: import_patchDockerCompose.tryPatchDockerComposeFiles,
38
39
  description: "Remove version field from docker-compose files"
40
+ },
41
+ {
42
+ apply: import_patchDockerImages.tryPatchDockerImages,
43
+ description: "Update docker image references to use public.ecr.aws and remove --platform flag"
39
44
  }
40
45
  ];
41
46
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/index.ts"],
4
- "sourcesContent": ["import type { Patches } from '../..';\n\nimport { tryCollapseDuplicateMergeKeys } from './collapseDuplicateMergeKeys';\nimport { tryPatchDockerComposeFiles } from './patchDockerCompose';\nimport { tryUpgradeESLint } from './upgradeESLint';\n\nexport const patches: Patches = [\n {\n apply: tryCollapseDuplicateMergeKeys,\n description: 'Collapse duplicate merge keys in .buildkite files',\n },\n {\n apply: tryUpgradeESLint,\n description: 'Upgrade to ESLint flat config',\n },\n {\n apply: tryPatchDockerComposeFiles,\n description: 'Remove version field from docker-compose files',\n },\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wCAA8C;AAC9C,gCAA2C;AAC3C,2BAAiC;AAE1B,MAAM,UAAmB;AAAA,EAC9B;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;",
4
+ "sourcesContent": ["import type { Patches } from '../..';\n\nimport { tryCollapseDuplicateMergeKeys } from './collapseDuplicateMergeKeys';\nimport { tryPatchDockerComposeFiles } from './patchDockerCompose';\nimport { tryPatchDockerImages } from './patchDockerImages';\nimport { tryUpgradeESLint } from './upgradeESLint';\n\nexport const patches: Patches = [\n {\n apply: tryCollapseDuplicateMergeKeys,\n description: 'Collapse duplicate merge keys in .buildkite files',\n },\n {\n apply: tryUpgradeESLint,\n description: 'Upgrade to ESLint flat config',\n },\n {\n apply: tryPatchDockerComposeFiles,\n description: 'Remove version field from docker-compose files',\n },\n {\n apply: tryPatchDockerImages,\n description:\n 'Update docker image references to use public.ecr.aws and remove --platform flag',\n },\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wCAA8C;AAC9C,gCAA2C;AAC3C,+BAAqC;AACrC,2BAAiC;AAE1B,MAAM,UAAmB;AAAA,EAC9B;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aACE;AAAA,EACJ;AACF;",
6
6
  "names": []
7
7
  }
@@ -48,9 +48,7 @@ const fetchFiles = async (files) => Promise.all(
48
48
  const patchDockerComposeFiles = async ({
49
49
  mode
50
50
  }) => {
51
- const maybeDockerComposeFiles = await Promise.resolve(
52
- (0, import_fast_glob.default)(["docker-compose*.yml"])
53
- );
51
+ const maybeDockerComposeFiles = await (0, import_fast_glob.default)(["docker-compose*.yml"]);
54
52
  if (!maybeDockerComposeFiles.length) {
55
53
  return {
56
54
  result: "skip",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerCompose.ts"],
4
- "sourcesContent": ["import { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport { readFile, writeFile } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst DOCKER_COMPOSE_VERSION_REGEX = /^version: ['\"]?\\d+(\\.\\d+)*['\"]?\\n*/m;\n\nconst fetchFiles = async (files: string[]) =>\n Promise.all(\n files.map(async (file) => {\n const contents = await readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n );\n\nconst patchDockerComposeFiles: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const maybeDockerComposeFiles = await Promise.resolve(\n fg(['docker-compose*.yml']),\n );\n\n if (!maybeDockerComposeFiles.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files found',\n };\n }\n\n const dockerComposeFiles = await fetchFiles(maybeDockerComposeFiles);\n\n const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>\n DOCKER_COMPOSE_VERSION_REGEX.exec(contents),\n );\n\n if (!dockerComposeFilesToPatch.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n await Promise.all(\n dockerComposeFilesToPatch.map(async ({ file, contents }) => {\n const patchedContents = contents.replace(\n DOCKER_COMPOSE_VERSION_REGEX,\n '',\n );\n await writeFile(file, patchedContents);\n }),\n );\n\n return { result: 'apply' };\n};\n\nexport const tryPatchDockerComposeFiles: PatchFunction = async (config) => {\n try {\n return await patchDockerComposeFiles(config);\n } catch (err) {\n log.warn('Failed to patch pnpm packageManager CI configuration.');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAe;AACf,sBAAoC;AAGpC,qBAAoB;AAEpB,MAAM,+BAA+B;AAErC,MAAM,aAAa,OAAO,UACxB,QAAQ;AAAA,EACN,MAAM,IAAI,OAAO,SAAS;AACxB,UAAM,WAAW,UAAM,0BAAS,MAAM,MAAM;AAE5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEF,MAAM,0BAAyC,OAAO;AAAA,EACpD;AACF,MAAgC;AAC9B,QAAM,0BAA0B,MAAM,QAAQ;AAAA,QAC5C,iBAAAA,SAAG,CAAC,qBAAqB,CAAC;AAAA,EAC5B;AAEA,MAAI,CAAC,wBAAwB,QAAQ;AACnC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAM,WAAW,uBAAuB;AAEnE,QAAM,4BAA4B,mBAAmB;AAAA,IAAO,CAAC,EAAE,SAAS,MACtE,6BAA6B,KAAK,QAAQ;AAAA,EAC5C;AAEA,MAAI,CAAC,0BAA0B,QAAQ;AACrC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,0BAA0B,IAAI,OAAO,EAAE,MAAM,SAAS,MAAM;AAC1D,YAAM,kBAAkB,SAAS;AAAA,QAC/B;AAAA,QACA;AAAA,MACF;AACA,gBAAM,2BAAU,MAAM,eAAe;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEO,MAAM,6BAA4C,OAAO,WAAW;AACzE,MAAI;AACF,WAAO,MAAM,wBAAwB,MAAM;AAAA,EAC7C,SAAS,KAAK;AACZ,uBAAI,KAAK,uDAAuD;AAChE,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport { readFile, writeFile } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst DOCKER_COMPOSE_VERSION_REGEX = /^version: ['\"]?\\d+(\\.\\d+)*['\"]?\\n*/m;\n\nconst fetchFiles = async (files: string[]) =>\n Promise.all(\n files.map(async (file) => {\n const contents = await readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n );\n\nconst patchDockerComposeFiles: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const maybeDockerComposeFiles = await fg(['docker-compose*.yml']);\n\n if (!maybeDockerComposeFiles.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files found',\n };\n }\n\n const dockerComposeFiles = await fetchFiles(maybeDockerComposeFiles);\n\n const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>\n DOCKER_COMPOSE_VERSION_REGEX.exec(contents),\n );\n\n if (!dockerComposeFilesToPatch.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n await Promise.all(\n dockerComposeFilesToPatch.map(async ({ file, contents }) => {\n const patchedContents = contents.replace(\n DOCKER_COMPOSE_VERSION_REGEX,\n '',\n );\n await writeFile(file, patchedContents);\n }),\n );\n\n return { result: 'apply' };\n};\n\nexport const tryPatchDockerComposeFiles: PatchFunction = async (config) => {\n try {\n return await patchDockerComposeFiles(config);\n } catch (err) {\n log.warn('Failed to patch pnpm packageManager CI configuration.');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAe;AACf,sBAAoC;AAGpC,qBAAoB;AAEpB,MAAM,+BAA+B;AAErC,MAAM,aAAa,OAAO,UACxB,QAAQ;AAAA,EACN,MAAM,IAAI,OAAO,SAAS;AACxB,UAAM,WAAW,UAAM,0BAAS,MAAM,MAAM;AAE5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEF,MAAM,0BAAyC,OAAO;AAAA,EACpD;AACF,MAAgC;AAC9B,QAAM,0BAA0B,UAAM,iBAAAA,SAAG,CAAC,qBAAqB,CAAC;AAEhE,MAAI,CAAC,wBAAwB,QAAQ;AACnC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAM,WAAW,uBAAuB;AAEnE,QAAM,4BAA4B,mBAAmB;AAAA,IAAO,CAAC,EAAE,SAAS,MACtE,6BAA6B,KAAK,QAAQ;AAAA,EAC5C;AAEA,MAAI,CAAC,0BAA0B,QAAQ;AACrC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,0BAA0B,IAAI,OAAO,EAAE,MAAM,SAAS,MAAM;AAC1D,YAAM,kBAAkB,SAAS;AAAA,QAC/B;AAAA,QACA;AAAA,MACF;AACA,gBAAM,2BAAU,MAAM,eAAe;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEO,MAAM,6BAA4C,OAAO,WAAW;AACzE,MAAI;AACF,WAAO,MAAM,wBAAwB,MAAM;AAAA,EAC7C,SAAS,KAAK;AACZ,uBAAI,KAAK,uDAAuD;AAChE,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
6
6
  "names": ["fg"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ import type { PatchFunction } from '../..';
2
+ export declare const tryPatchDockerImages: PatchFunction;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var patchDockerImages_exports = {};
30
+ __export(patchDockerImages_exports, {
31
+ tryPatchDockerImages: () => tryPatchDockerImages
32
+ });
33
+ module.exports = __toCommonJS(patchDockerImages_exports);
34
+ var import_util = require("util");
35
+ var import_fast_glob = __toESM(require("fast-glob"));
36
+ var import_fs_extra = require("fs-extra");
37
+ var import_logging = require("../../../../../../utils/logging");
38
+ const DOCKER_IMAGE_REGEX = /^(FROM\s?.*)(\s)(node|python)(:.*)/gm;
39
+ const DOCKER_IMAGE_PLATFORM_REGEX = /^(FROM\s?.*)(--platform=[^\s]+) /gm;
40
+ const DOCKER_COMPOSE_IMAGE_REGEX = /^(\s+image:\s)(node|python)(:.*)/gm;
41
+ const PUBLIC_ECR = "public.ecr.aws/docker/library/";
42
+ const fetchFiles = async (files) => Promise.all(
43
+ files.map(async (file) => {
44
+ const contents = await (0, import_fs_extra.readFile)(file, "utf8");
45
+ return {
46
+ file,
47
+ contents
48
+ };
49
+ })
50
+ );
51
+ const isInvalidPlatformFlagUsage = (contents) => {
52
+ const matches = [...contents.matchAll(DOCKER_IMAGE_PLATFORM_REGEX)];
53
+ if (!matches.length) {
54
+ return false;
55
+ }
56
+ const uniquePlatforms = [
57
+ ...new Set(matches.map(([, , platform]) => platform))
58
+ ];
59
+ if (uniquePlatforms.length > 1) {
60
+ return false;
61
+ }
62
+ if (uniquePlatforms[0]?.startsWith("--platform=$")) {
63
+ return false;
64
+ }
65
+ return true;
66
+ };
67
+ const patchDockerImages = async ({
68
+ mode
69
+ }) => {
70
+ const [maybeDockerFilesPaths, maybeDockerComposePaths] = await Promise.all([
71
+ (0, import_fast_glob.default)(["Dockerfile*"]),
72
+ (0, import_fast_glob.default)(["docker-compose*.y*ml"])
73
+ ]);
74
+ if (!maybeDockerFilesPaths.length && !maybeDockerComposePaths.length) {
75
+ return {
76
+ result: "skip",
77
+ reason: "no Dockerfile or docker-compose files found"
78
+ };
79
+ }
80
+ const [dockerFiles, dockerComposeFiles] = await Promise.all([
81
+ fetchFiles(maybeDockerFilesPaths),
82
+ fetchFiles(maybeDockerComposePaths)
83
+ ]);
84
+ const dockerFilesToPatch = dockerFiles.filter(
85
+ ({ contents }) => DOCKER_IMAGE_REGEX.exec(contents) ?? isInvalidPlatformFlagUsage(contents)
86
+ );
87
+ const dockerComposeFilesToPatch = dockerComposeFiles.filter(
88
+ ({ contents }) => DOCKER_COMPOSE_IMAGE_REGEX.exec(contents)
89
+ );
90
+ if (!dockerFilesToPatch.length && !dockerComposeFilesToPatch.length) {
91
+ return {
92
+ result: "skip",
93
+ reason: "no Dockerfile or docker-compose files to patch"
94
+ };
95
+ }
96
+ if (mode === "lint") {
97
+ return {
98
+ result: "apply"
99
+ };
100
+ }
101
+ const dockerFilePatches = dockerFilesToPatch.map(
102
+ async ({ file, contents }) => {
103
+ let patchedContents = contents.replace(
104
+ DOCKER_IMAGE_REGEX,
105
+ `$1$2${PUBLIC_ECR}$3$4`
106
+ );
107
+ if (isInvalidPlatformFlagUsage(contents)) {
108
+ patchedContents = patchedContents.replace(
109
+ DOCKER_IMAGE_PLATFORM_REGEX,
110
+ "$1"
111
+ );
112
+ }
113
+ await (0, import_fs_extra.writeFile)(file, patchedContents);
114
+ }
115
+ );
116
+ const dockerComposeFilePatches = dockerComposeFilesToPatch.map(
117
+ async ({ file, contents }) => {
118
+ const patchedContents = contents.replace(
119
+ DOCKER_COMPOSE_IMAGE_REGEX,
120
+ `$1${PUBLIC_ECR}$2$3`
121
+ );
122
+ await (0, import_fs_extra.writeFile)(file, patchedContents);
123
+ }
124
+ );
125
+ await Promise.all([...dockerFilePatches, ...dockerComposeFilePatches]);
126
+ return { result: "apply" };
127
+ };
128
+ const tryPatchDockerImages = async (config) => {
129
+ try {
130
+ return await patchDockerImages(config);
131
+ } catch (err) {
132
+ import_logging.log.warn("Failed to patch Docker images");
133
+ import_logging.log.subtle((0, import_util.inspect)(err));
134
+ return { result: "skip", reason: "due to an error" };
135
+ }
136
+ };
137
+ // Annotate the CommonJS export names for ESM import in node:
138
+ 0 && (module.exports = {
139
+ tryPatchDockerImages
140
+ });
141
+ //# sourceMappingURL=patchDockerImages.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerImages.ts"],
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport { readFile, writeFile } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst DOCKER_IMAGE_REGEX = /^(FROM\\s?.*)(\\s)(node|python)(:.*)/gm;\nconst DOCKER_IMAGE_PLATFORM_REGEX = /^(FROM\\s?.*)(--platform=[^\\s]+) /gm;\nconst DOCKER_COMPOSE_IMAGE_REGEX = /^(\\s+image:\\s)(node|python)(:.*)/gm;\nconst PUBLIC_ECR = 'public.ecr.aws/docker/library/';\n\nconst fetchFiles = async (files: string[]) =>\n Promise.all(\n files.map(async (file) => {\n const contents = await readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n );\n\nconst isInvalidPlatformFlagUsage = (contents: string) => {\n const matches = [...contents.matchAll(DOCKER_IMAGE_PLATFORM_REGEX)];\n\n if (!matches.length) {\n return false;\n }\n\n const uniquePlatforms = [\n ...new Set(matches.map(([, , platform]) => platform as string)),\n ];\n\n // Multiple --platform flags are used which may indicate a multi arch build\n if (uniquePlatforms.length > 1) {\n return false;\n }\n\n // Avoid patching as they may be using args to set the platform\n if (uniquePlatforms[0]?.startsWith('--platform=$')) {\n return false;\n }\n\n return true;\n};\n\nconst patchDockerImages: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const [maybeDockerFilesPaths, maybeDockerComposePaths] = await Promise.all([\n fg(['Dockerfile*']),\n fg(['docker-compose*.y*ml']),\n ]);\n\n if (!maybeDockerFilesPaths.length && !maybeDockerComposePaths.length) {\n return {\n result: 'skip',\n reason: 'no Dockerfile or docker-compose files found',\n };\n }\n\n const [dockerFiles, dockerComposeFiles] = await Promise.all([\n fetchFiles(maybeDockerFilesPaths),\n fetchFiles(maybeDockerComposePaths),\n ]);\n\n const dockerFilesToPatch = dockerFiles.filter(\n ({ contents }) =>\n DOCKER_IMAGE_REGEX.exec(contents) ?? isInvalidPlatformFlagUsage(contents),\n );\n\n const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>\n DOCKER_COMPOSE_IMAGE_REGEX.exec(contents),\n );\n\n if (!dockerFilesToPatch.length && !dockerComposeFilesToPatch.length) {\n return {\n result: 'skip',\n reason: 'no Dockerfile or docker-compose files to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n const dockerFilePatches = dockerFilesToPatch.map(\n async ({ file, contents }) => {\n let patchedContents = contents.replace(\n DOCKER_IMAGE_REGEX,\n `$1$2${PUBLIC_ECR}$3$4`,\n );\n\n if (isInvalidPlatformFlagUsage(contents)) {\n patchedContents = patchedContents.replace(\n DOCKER_IMAGE_PLATFORM_REGEX,\n '$1',\n );\n }\n\n await writeFile(file, patchedContents);\n },\n );\n\n const dockerComposeFilePatches = dockerComposeFilesToPatch.map(\n async ({ file, contents }) => {\n const patchedContents = contents.replace(\n DOCKER_COMPOSE_IMAGE_REGEX,\n `$1${PUBLIC_ECR}$2$3`,\n );\n await writeFile(file, patchedContents);\n },\n );\n\n await Promise.all([...dockerFilePatches, ...dockerComposeFilePatches]);\n\n return { result: 'apply' };\n};\n\nexport const tryPatchDockerImages: PatchFunction = async (config) => {\n try {\n return await patchDockerImages(config);\n } catch (err) {\n log.warn('Failed to patch Docker images');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAe;AACf,sBAAoC;AAGpC,qBAAoB;AAEpB,MAAM,qBAAqB;AAC3B,MAAM,8BAA8B;AACpC,MAAM,6BAA6B;AACnC,MAAM,aAAa;AAEnB,MAAM,aAAa,OAAO,UACxB,QAAQ;AAAA,EACN,MAAM,IAAI,OAAO,SAAS;AACxB,UAAM,WAAW,UAAM,0BAAS,MAAM,MAAM;AAE5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEF,MAAM,6BAA6B,CAAC,aAAqB;AACvD,QAAM,UAAU,CAAC,GAAG,SAAS,SAAS,2BAA2B,CAAC;AAElE,MAAI,CAAC,QAAQ,QAAQ;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB;AAAA,IACtB,GAAG,IAAI,IAAI,QAAQ,IAAI,CAAC,CAAC,EAAE,EAAE,QAAQ,MAAM,QAAkB,CAAC;AAAA,EAChE;AAGA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,WAAO;AAAA,EACT;AAGA,MAAI,gBAAgB,CAAC,GAAG,WAAW,cAAc,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,MAAM,oBAAmC,OAAO;AAAA,EAC9C;AACF,MAAgC;AAC9B,QAAM,CAAC,uBAAuB,uBAAuB,IAAI,MAAM,QAAQ,IAAI;AAAA,QACzE,iBAAAA,SAAG,CAAC,aAAa,CAAC;AAAA,QAClB,iBAAAA,SAAG,CAAC,sBAAsB,CAAC;AAAA,EAC7B,CAAC;AAED,MAAI,CAAC,sBAAsB,UAAU,CAAC,wBAAwB,QAAQ;AACpE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,CAAC,aAAa,kBAAkB,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC1D,WAAW,qBAAqB;AAAA,IAChC,WAAW,uBAAuB;AAAA,EACpC,CAAC;AAED,QAAM,qBAAqB,YAAY;AAAA,IACrC,CAAC,EAAE,SAAS,MACV,mBAAmB,KAAK,QAAQ,KAAK,2BAA2B,QAAQ;AAAA,EAC5E;AAEA,QAAM,4BAA4B,mBAAmB;AAAA,IAAO,CAAC,EAAE,SAAS,MACtE,2BAA2B,KAAK,QAAQ;AAAA,EAC1C;AAEA,MAAI,CAAC,mBAAmB,UAAU,CAAC,0BAA0B,QAAQ;AACnE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,oBAAoB,mBAAmB;AAAA,IAC3C,OAAO,EAAE,MAAM,SAAS,MAAM;AAC5B,UAAI,kBAAkB,SAAS;AAAA,QAC7B;AAAA,QACA,OAAO,UAAU;AAAA,MACnB;AAEA,UAAI,2BAA2B,QAAQ,GAAG;AACxC,0BAAkB,gBAAgB;AAAA,UAChC;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,gBAAM,2BAAU,MAAM,eAAe;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,2BAA2B,0BAA0B;AAAA,IACzD,OAAO,EAAE,MAAM,SAAS,MAAM;AAC5B,YAAM,kBAAkB,SAAS;AAAA,QAC/B;AAAA,QACA,KAAK,UAAU;AAAA,MACjB;AACA,gBAAM,2BAAU,MAAM,eAAe;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,QAAQ,IAAI,CAAC,GAAG,mBAAmB,GAAG,wBAAwB,CAAC;AAErE,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEO,MAAM,uBAAsC,OAAO,WAAW;AACnE,MAAI;AACF,WAAO,MAAM,kBAAkB,MAAM;AAAA,EACvC,SAAS,KAAK;AACZ,uBAAI,KAAK,+BAA+B;AACxC,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
6
+ "names": ["fg"]
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/wrapper/requestListener.ts"],
4
- "sourcesContent": ["import http from 'http';\n\nimport { isFunction, isIpPort, isObject } from '../utils/validation';\n\nimport { serveRequestListener, startServer } from './http';\n\n// Express compatibility\ninterface FunctionConfig extends http.RequestListener {\n port?: number;\n}\n\ninterface ObjectConfig {\n // Koa compatibility\n callback?: () => http.RequestListener;\n\n requestListener?: http.RequestListener;\n\n // Fastify compatibility\n server?: http.Server;\n\n default?: Promise<unknown>;\n port?: unknown;\n}\n\nconst isConfig = (\n data: unknown,\n): data is Promise<FunctionConfig> | Promise<ObjectConfig> =>\n isFunction(data) || isObject(data);\n\ninterface Args {\n availablePort?: number;\n entryPoint: unknown;\n}\n\n/**\n * Create an HTTP server that calls into an exported `http.RequestListener`.\n *\n * This supports Express and Koa applications out of the box.\n */\nexport const runRequestListener = async ({\n availablePort,\n entryPoint,\n}: Args): Promise<void> => {\n if (!isConfig(entryPoint)) {\n // Assume an executable script with weird exports\n return;\n }\n\n let config: FunctionConfig | ObjectConfig = await entryPoint;\n\n if (typeof config === 'object' && isConfig(config.default)) {\n // Prefer `export default` over `export =`\n config = await config.default;\n }\n\n if (Object.keys(config).length === 0) {\n // Assume an executable script with no exports\n return;\n }\n\n const port = isIpPort(config.port) ? config.port : availablePort;\n\n // http.Server support\n if (typeof config !== 'function' && config instanceof http.Server) {\n return startServer(config, port);\n }\n\n // Fastify workaround\n if (\n typeof config !== 'function' &&\n config.server &&\n config.server instanceof http.Server\n ) {\n return startServer(config.server, port);\n }\n\n const requestListener =\n typeof config === 'function'\n ? config\n : config.requestListener ?? config.callback?.();\n\n if (typeof requestListener !== 'function') {\n // Assume an executable script with non-request listener exports\n return;\n }\n\n return serveRequestListener(requestListener, port);\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,wBAA+C;AAE/C,IAAAA,eAAkD;AAoBlD,MAAM,WAAW,CACf,aAEA,8BAAW,IAAI,SAAK,4BAAS,IAAI;AAY5B,MAAM,qBAAqB,OAAO;AAAA,EACvC;AAAA,EACA;AACF,MAA2B;AACzB,MAAI,CAAC,SAAS,UAAU,GAAG;AAEzB;AAAA,EACF;AAEA,MAAI,SAAwC,MAAM;AAElD,MAAI,OAAO,WAAW,YAAY,SAAS,OAAO,OAAO,GAAG;AAE1D,aAAS,MAAM,OAAO;AAAA,EACxB;AAEA,MAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AAEpC;AAAA,EACF;AAEA,QAAM,WAAO,4BAAS,OAAO,IAAI,IAAI,OAAO,OAAO;AAGnD,MAAI,OAAO,WAAW,cAAc,kBAAkB,YAAAC,QAAK,QAAQ;AACjE,eAAO,0BAAY,QAAQ,IAAI;AAAA,EACjC;AAGA,MACE,OAAO,WAAW,cAClB,OAAO,UACP,OAAO,kBAAkB,YAAAA,QAAK,QAC9B;AACA,eAAO,0BAAY,OAAO,QAAQ,IAAI;AAAA,EACxC;AAEA,QAAM,kBACJ,OAAO,WAAW,aACd,SACA,OAAO,mBAAmB,OAAO,WAAW;AAElD,MAAI,OAAO,oBAAoB,YAAY;AAEzC;AAAA,EACF;AAEA,aAAO,mCAAqB,iBAAiB,IAAI;AACnD;",
4
+ "sourcesContent": ["import http from 'http';\n\nimport { isFunction, isIpPort, isObject } from '../utils/validation';\n\nimport { serveRequestListener, startServer } from './http';\n\n// Express compatibility\ninterface FunctionConfig extends http.RequestListener {\n port?: number;\n}\n\ninterface ObjectConfig {\n // Koa compatibility\n callback?: () => http.RequestListener;\n\n requestListener?: http.RequestListener;\n\n // Fastify compatibility\n server?: http.Server;\n\n default?: Promise<unknown>;\n port?: unknown;\n}\n\nconst isConfig = (\n data: unknown,\n): data is Promise<FunctionConfig> | Promise<ObjectConfig> =>\n isFunction(data) || isObject(data);\n\ninterface Args {\n availablePort?: number;\n entryPoint: unknown;\n}\n\n/**\n * Create an HTTP server that calls into an exported `http.RequestListener`.\n *\n * This supports Express and Koa applications out of the box.\n */\nexport const runRequestListener = async ({\n availablePort,\n entryPoint,\n}: Args): Promise<void> => {\n if (!isConfig(entryPoint)) {\n // Assume an executable script with weird exports\n return;\n }\n\n let config: FunctionConfig | ObjectConfig = await entryPoint;\n\n if (typeof config === 'object' && isConfig(config.default)) {\n // Prefer `export default` over `export =`\n config = await config.default;\n }\n\n if (Object.keys(config).length === 0) {\n // Assume an executable script with no exports\n return;\n }\n\n const port = isIpPort(config.port) ? config.port : availablePort;\n\n // http.Server support\n if (typeof config !== 'function' && config instanceof http.Server) {\n return startServer(config, port);\n }\n\n // Fastify workaround\n if (\n typeof config !== 'function' &&\n config.server &&\n config.server instanceof http.Server\n ) {\n return startServer(config.server, port);\n }\n\n const requestListener =\n typeof config === 'function'\n ? config\n : (config.requestListener ?? config.callback?.());\n\n if (typeof requestListener !== 'function') {\n // Assume an executable script with non-request listener exports\n return;\n }\n\n return serveRequestListener(requestListener, port);\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,wBAA+C;AAE/C,IAAAA,eAAkD;AAoBlD,MAAM,WAAW,CACf,aAEA,8BAAW,IAAI,SAAK,4BAAS,IAAI;AAY5B,MAAM,qBAAqB,OAAO;AAAA,EACvC;AAAA,EACA;AACF,MAA2B;AACzB,MAAI,CAAC,SAAS,UAAU,GAAG;AAEzB;AAAA,EACF;AAEA,MAAI,SAAwC,MAAM;AAElD,MAAI,OAAO,WAAW,YAAY,SAAS,OAAO,OAAO,GAAG;AAE1D,aAAS,MAAM,OAAO;AAAA,EACxB;AAEA,MAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AAEpC;AAAA,EACF;AAEA,QAAM,WAAO,4BAAS,OAAO,IAAI,IAAI,OAAO,OAAO;AAGnD,MAAI,OAAO,WAAW,cAAc,kBAAkB,YAAAC,QAAK,QAAQ;AACjE,eAAO,0BAAY,QAAQ,IAAI;AAAA,EACjC;AAGA,MACE,OAAO,WAAW,cAClB,OAAO,UACP,OAAO,kBAAkB,YAAAA,QAAK,QAC9B;AACA,eAAO,0BAAY,OAAO,QAAQ,IAAI;AAAA,EACxC;AAEA,QAAM,kBACJ,OAAO,WAAW,aACd,SACC,OAAO,mBAAmB,OAAO,WAAW;AAEnD,MAAI,OAAO,oBAAoB,YAAY;AAEzC;AAAA,EACF;AAEA,aAAO,mCAAqB,iBAAiB,IAAI;AACnD;",
6
6
  "names": ["import_http", "http"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skuba",
3
- "version": "9.0.0-main-20240924121500",
3
+ "version": "9.0.0-main-20240928013837",
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",
@@ -81,7 +81,7 @@
81
81
  "libnpmsearch": "^7.0.0",
82
82
  "lodash.mergewith": "^4.6.2",
83
83
  "minimist": "^1.2.6",
84
- "normalize-package-data": "^6.0.0",
84
+ "normalize-package-data": "^7.0.0",
85
85
  "npm-run-path": "^4.0.1",
86
86
  "npm-which": "^3.0.1",
87
87
  "picomatch": "^4.0.0",
@@ -99,9 +99,9 @@
99
99
  "tsconfig-seek": "2.0.0",
100
100
  "tsx": "^4.16.2",
101
101
  "typescript": "~5.6.0",
102
- "validate-npm-package-name": "^5.0.0",
102
+ "validate-npm-package-name": "^6.0.0",
103
103
  "zod": "^3.22.4",
104
- "eslint-config-skuba": "5.0.0-main-20240924121500"
104
+ "eslint-config-skuba": "5.0.0-main-20240928013837"
105
105
  },
106
106
  "devDependencies": {
107
107
  "@changesets/cli": "2.27.8",
@@ -12,7 +12,7 @@ RUN pnpm install --offline --prod
12
12
 
13
13
  ###
14
14
 
15
- FROM --platform=<%- platformName %> gcr.io/distroless/nodejs20-debian12 AS runtime
15
+ FROM gcr.io/distroless/nodejs20-debian12 AS runtime
16
16
 
17
17
  WORKDIR /workdir
18
18
 
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1.10
2
2
 
3
- FROM --platform=<%- platformName %> node:20-alpine AS dev-deps
3
+ FROM public.ecr.aws/docker/library/node:20-alpine AS dev-deps
4
4
 
5
5
  RUN --mount=type=bind,source=package.json,target=package.json \
6
6
  corepack enable pnpm && corepack install
@@ -13,7 +13,7 @@
13
13
  "test:watch": "skuba test --watch"
14
14
  },
15
15
  "dependencies": {
16
- "@seek/logger": "^6.0.0",
16
+ "@seek/logger": "^9.0.0",
17
17
  "express": "^4.17.1",
18
18
  "hot-shots": "^10.0.0",
19
19
  "seek-datadog-custom-metrics": "^4.6.3",
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1.10
2
2
 
3
- FROM --platform=<%- platformName %> node:20-alpine AS dev-deps
3
+ FROM public.ecr.aws/docker/library/node:20-alpine AS dev-deps
4
4
 
5
5
  RUN --mount=type=bind,source=package.json,target=package.json \
6
6
  corepack enable pnpm && corepack install
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "^20.9.0",
20
- "skuba": "9.0.0-main-20240924121500"
20
+ "skuba": "9.0.0-main-20240928013837"
21
21
  },
22
22
  "packageManager": "pnpm@9.11.0",
23
23
  "engines": {
@@ -12,7 +12,7 @@ RUN pnpm install --offline --prod
12
12
 
13
13
  ###
14
14
 
15
- FROM --platform=<%- platformName %> gcr.io/distroless/nodejs20-debian12 AS runtime
15
+ FROM gcr.io/distroless/nodejs20-debian12 AS runtime
16
16
 
17
17
  WORKDIR /workdir
18
18
 
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1.10
2
2
 
3
- FROM --platform=<%- platformName %> node:20-alpine AS dev-deps
3
+ FROM public.ecr.aws/docker/library/node:20-alpine AS dev-deps
4
4
 
5
5
  RUN --mount=type=bind,source=package.json,target=package.json \
6
6
  corepack enable pnpm && corepack install
@@ -13,7 +13,7 @@
13
13
  "test:watch": "skuba test --watch"
14
14
  },
15
15
  "dependencies": {
16
- "@koa/router": "^12.0.0",
16
+ "@koa/router": "^13.0.0",
17
17
  "@opentelemetry/api": "^1.9.0",
18
18
  "@opentelemetry/core": "^1.25.0",
19
19
  "@opentelemetry/exporter-trace-otlp-grpc": "^0.53.0",
@@ -21,7 +21,7 @@
21
21
  "@opentelemetry/instrumentation-http": "^0.53.0",
22
22
  "@opentelemetry/propagator-b3": "^1.25.0",
23
23
  "@opentelemetry/sdk-node": "^0.53.0",
24
- "@seek/logger": "^6.0.0",
24
+ "@seek/logger": "^9.0.0",
25
25
  "hot-shots": "^10.0.0",
26
26
  "koa": "^2.13.4",
27
27
  "koa-bodyparser": "^4.3.0",
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1.10
2
2
 
3
- FROM --platform=<%- platformName %> node:20-alpine AS dev-deps
3
+ FROM public.ecr.aws/docker/library/node:20-alpine AS dev-deps
4
4
 
5
5
  RUN --mount=type=bind,source=package.json,target=package.json \
6
6
  corepack enable pnpm && corepack install
@@ -18,8 +18,8 @@
18
18
  "@aws-sdk/client-codedeploy": "^3.363.0",
19
19
  "@aws-sdk/client-lambda": "^3.363.0",
20
20
  "@aws-sdk/client-sns": "^3.363.0",
21
- "@seek/logger": "^6.0.0",
22
- "datadog-lambda-js": "^8.0.0",
21
+ "@seek/logger": "^9.0.0",
22
+ "datadog-lambda-js": "^9.0.0",
23
23
  "dd-trace": "^5.0.0",
24
24
  "skuba-dive": "^2.0.0",
25
25
  "zod": "^3.19.1"
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1.10
2
2
 
3
- FROM --platform=<%- platformName %> node:20-alpine AS dev-deps
3
+ FROM public.ecr.aws/docker/library/node:20-alpine AS dev-deps
4
4
 
5
5
  # Needed for cdk
6
6
  RUN apk add --no-cache bash
@@ -16,7 +16,7 @@
16
16
  "@aws-sdk/client-codedeploy": "^3.363.0",
17
17
  "@aws-sdk/client-lambda": "^3.363.0",
18
18
  "@aws-sdk/client-sns": "^3.363.0",
19
- "@seek/logger": "^6.0.0",
19
+ "@seek/logger": "^9.0.0",
20
20
  "skuba-dive": "^2.0.0",
21
21
  "zod": "^3.19.1"
22
22
  },
@@ -28,7 +28,7 @@
28
28
  "aws-cdk-lib": "^2.109.0",
29
29
  "constructs": "^10.0.17",
30
30
  "pino-pretty": "^11.0.0",
31
- "skuba": "9.0.0-main-20240924121500"
31
+ "skuba": "9.0.0-main-20240928013837"
32
32
  },
33
33
  "packageManager": "pnpm@9.11.0",
34
34
  "engines": {