@aws/nx-plugin 1.0.0-rc.46 → 1.0.0-rc.48

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 (182) hide show
  1. package/LICENSE-THIRD-PARTY +3 -60
  2. package/generators.json +1 -1
  3. package/package.json +7 -6
  4. package/src/agentcore-gateway/generator.js +12 -2
  5. package/src/agentcore-gateway/generator.js.map +1 -1
  6. package/src/infra/app/__snapshots__/generator.spec.ts.snap +25 -31
  7. package/src/infra/app/generator.js +9 -6
  8. package/src/infra/app/generator.js.map +1 -1
  9. package/src/license/config.js +1 -1
  10. package/src/license/config.js.map +1 -1
  11. package/src/mcp-server/dev-server.d.ts +1 -0
  12. package/src/mcp-server/dev-server.js +18 -0
  13. package/src/mcp-server/dev-server.js.map +1 -0
  14. package/src/mcp-server/schema.d.ts +1 -1
  15. package/src/mcp-server/tools/general-guidance.js +5 -6
  16. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  17. package/src/preset/__snapshots__/generator.spec.ts.snap +42 -7
  18. package/src/preset/generator.d.ts +1 -1
  19. package/src/preset/generator.js +4 -2
  20. package/src/preset/generator.js.map +1 -1
  21. package/src/preset/schema.d.js.map +1 -1
  22. package/src/preset/schema.d.ts +1 -0
  23. package/src/preset/schema.json +5 -0
  24. package/src/py/agent/generator.js +2 -1
  25. package/src/py/agent/generator.js.map +1 -1
  26. package/src/py/mcp-server/generator.js +2 -1
  27. package/src/py/mcp-server/generator.js.map +1 -1
  28. package/src/py/project/generator.js +2 -1
  29. package/src/py/project/generator.js.map +1 -1
  30. package/src/py/rdb/generator.js +2 -1
  31. package/src/py/rdb/generator.js.map +1 -1
  32. package/src/smithy/ts/api/generator.js +5 -2
  33. package/src/smithy/ts/api/generator.js.map +1 -1
  34. package/src/terraform/project/generator.js +4 -1
  35. package/src/terraform/project/generator.js.map +1 -1
  36. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +6 -6
  37. package/src/trpc/backend/generator.js +7 -5
  38. package/src/trpc/backend/generator.js.map +1 -1
  39. package/src/trpc/react/generator.js +4 -4
  40. package/src/trpc/react/generator.js.map +1 -1
  41. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +9 -5
  42. package/src/ts/agent/a2a-connection/generator.js +3 -2
  43. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  44. package/src/ts/agent/files/deploy/Dockerfile.template +7 -3
  45. package/src/ts/agent/gateway-connection/generator.js +4 -3
  46. package/src/ts/agent/gateway-connection/generator.js.map +1 -1
  47. package/src/ts/agent/generator.js +10 -7
  48. package/src/ts/agent/generator.js.map +1 -1
  49. package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +1 -1
  50. package/src/ts/agent/mcp-connection/generator.js +4 -3
  51. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  52. package/src/ts/agent/react-connection/generator.js +10 -19
  53. package/src/ts/agent/react-connection/generator.js.map +1 -1
  54. package/src/ts/astro-docs/generator.js +12 -3
  55. package/src/ts/astro-docs/generator.js.map +1 -1
  56. package/src/ts/dcr-proxy/generator.js +5 -5
  57. package/src/ts/dcr-proxy/generator.js.map +1 -1
  58. package/src/ts/dynamodb/generator.js +5 -2
  59. package/src/ts/dynamodb/generator.js.map +1 -1
  60. package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +4 -2
  61. package/src/ts/lambda-function/files/handler/__lambdaFunctionKebabCase__.ts.template +2 -1
  62. package/src/ts/lambda-function/generator.js +3 -2
  63. package/src/ts/lambda-function/generator.js.map +1 -1
  64. package/src/ts/lib/ts-project-utils.js +17 -10
  65. package/src/ts/lib/ts-project-utils.js.map +1 -1
  66. package/src/ts/lib/vitest.js +2 -1
  67. package/src/ts/lib/vitest.js.map +1 -1
  68. package/src/ts/mcp-server/files/Dockerfile.template +7 -3
  69. package/src/ts/mcp-server/generator.js +13 -13
  70. package/src/ts/mcp-server/generator.js.map +1 -1
  71. package/src/ts/nx-generator/generator.js +5 -0
  72. package/src/ts/nx-generator/generator.js.map +1 -1
  73. package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +5 -6
  74. package/src/ts/nx-plugin/files/mcp-server/resources/GENERAL_GUIDANCE.md.template +5 -6
  75. package/src/ts/nx-plugin/utils.js +8 -10
  76. package/src/ts/nx-plugin/utils.js.map +1 -1
  77. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +11 -3
  78. package/src/ts/rdb/agent-connection/generator.js +1 -2
  79. package/src/ts/rdb/agent-connection/generator.js.map +1 -1
  80. package/src/ts/rdb/files/Dockerfile.template +5 -1
  81. package/src/ts/rdb/files/src/migration-handler.ts.template +3 -1
  82. package/src/ts/rdb/generator.js +12 -8
  83. package/src/ts/rdb/generator.js.map +1 -1
  84. package/src/ts/rdb/mcp-server-connection/generator.js +1 -2
  85. package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
  86. package/src/ts/rdb/smithy-connection/generator.js +1 -2
  87. package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
  88. package/src/ts/rdb/trpc-connection/generator.js +1 -2
  89. package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
  90. package/src/ts/react-website/agui/generator.js +5 -4
  91. package/src/ts/react-website/agui/generator.js.map +1 -1
  92. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +210 -79
  93. package/src/ts/react-website/app/generator.js +34 -14
  94. package/src/ts/react-website/app/generator.js.map +1 -1
  95. package/src/ts/react-website/cognito-auth/generator.js +3 -2
  96. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  97. package/src/ts/react-website/runtime-config/generator.js +2 -2
  98. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  99. package/src/ts/sync/generator.js +81 -3
  100. package/src/ts/sync/generator.js.map +1 -1
  101. package/src/utils/agent-connection/agent-connection.d.ts +1 -1
  102. package/src/utils/agent-connection/agent-connection.js +50 -1
  103. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  104. package/src/utils/agent-core-constructs/agent-core-constructs.js +10 -1
  105. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  106. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +19 -1
  107. package/src/utils/api-constructs/api-constructs.js +15 -1
  108. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  109. package/src/utils/bundle/bundle.js +2 -1
  110. package/src/utils/bundle/bundle.js.map +1 -1
  111. package/src/utils/commands.d.ts +5 -3
  112. package/src/utils/commands.js +24 -3
  113. package/src/utils/commands.js.map +1 -1
  114. package/src/utils/config/index.d.ts +16 -0
  115. package/src/utils/config/index.js.map +1 -1
  116. package/src/utils/config/utils.d.ts +3 -2
  117. package/src/utils/config/utils.js +4 -3
  118. package/src/utils/config/utils.js.map +1 -1
  119. package/src/utils/connection/open-api/react.js +3 -2
  120. package/src/utils/connection/open-api/react.js.map +1 -1
  121. package/src/utils/containers.js +1 -1
  122. package/src/utils/containers.js.map +1 -1
  123. package/src/utils/dependencies.d.ts +18 -0
  124. package/src/utils/dependencies.js +206 -0
  125. package/src/utils/dependencies.js.map +1 -0
  126. package/src/utils/docker.d.ts +8 -0
  127. package/src/utils/docker.js +8 -1
  128. package/src/utils/docker.js.map +1 -1
  129. package/src/utils/files/common/shadcn/readme/README.md.template +3 -3
  130. package/src/utils/files/shadcn/components.json.template +1 -1
  131. package/src/utils/format.d.ts +20 -1
  132. package/src/utils/format.js +137 -74
  133. package/src/utils/format.js.map +1 -1
  134. package/src/utils/fs.d.ts +1 -1
  135. package/src/utils/fs.js +1 -1
  136. package/src/utils/fs.js.map +1 -1
  137. package/src/utils/iac.js +1 -1
  138. package/src/utils/iac.js.map +1 -1
  139. package/src/utils/init.d.ts +7 -1
  140. package/src/utils/init.js +45 -19
  141. package/src/utils/init.js.map +1 -1
  142. package/src/utils/install.js +3 -1
  143. package/src/utils/install.js.map +1 -1
  144. package/src/utils/mcp.d.ts +9 -0
  145. package/src/utils/mcp.js +9 -1
  146. package/src/utils/mcp.js.map +1 -1
  147. package/src/utils/module-format.d.ts +5 -8
  148. package/src/utils/module-format.js +29 -12
  149. package/src/utils/module-format.js.map +1 -1
  150. package/src/utils/npm-scope.d.ts +0 -4
  151. package/src/utils/npm-scope.js +0 -5
  152. package/src/utils/npm-scope.js.map +1 -1
  153. package/src/utils/nx.d.ts +13 -0
  154. package/src/utils/nx.js +24 -1
  155. package/src/utils/nx.js.map +1 -1
  156. package/src/utils/pnpm-workspace.d.ts +1 -12
  157. package/src/utils/pnpm-workspace.js +3 -30
  158. package/src/utils/pnpm-workspace.js.map +1 -1
  159. package/src/utils/project-package-json.d.ts +39 -0
  160. package/src/utils/project-package-json.js +119 -0
  161. package/src/utils/project-package-json.js.map +1 -0
  162. package/src/utils/shared-constructs.js +6 -5
  163. package/src/utils/shared-constructs.js.map +1 -1
  164. package/src/utils/shared-dynamodb-scripts.js +4 -2
  165. package/src/utils/shared-dynamodb-scripts.js.map +1 -1
  166. package/src/utils/shared-infra-scripts.js +5 -4
  167. package/src/utils/shared-infra-scripts.js.map +1 -1
  168. package/src/utils/shared-rdb-scripts.js +14 -1
  169. package/src/utils/shared-rdb-scripts.js.map +1 -1
  170. package/src/utils/shared-shadcn.js +11 -8
  171. package/src/utils/shared-shadcn.js.map +1 -1
  172. package/src/utils/test-git.d.ts +39 -0
  173. package/src/utils/test-git.js +117 -0
  174. package/src/utils/test-git.js.map +1 -0
  175. package/src/utils/test.js +8 -3
  176. package/src/utils/test.js.map +1 -1
  177. package/src/utils/versions.d.ts +7 -1
  178. package/src/utils/versions.js +13 -2
  179. package/src/utils/versions.js.map +1 -1
  180. package/src/bin/aws-nx-mcp.d.ts +0 -2
  181. package/src/bin/aws-nx-mcp.js +0 -14
  182. package/src/bin/aws-nx-mcp.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/commands.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { TS_VERSIONS } from './versions';\n\n/**\n * The nx version the plugin is built against. Commands that download nx\n * (e.g. `nx init`) pin to this version so the workspace's nx matches the\n * plugin's `@nx/*` packages — a mismatch deadlocks `nx sync`.\n */\nexport const NX_VERSION = TS_VERSIONS['@nx/devkit'];\n\n/**\n * Display-friendly command prefixes for each package manager.\n *\n * - `exec`: prefix for running local binaries (e.g. `npx nx`, `pnpm nx`, `bunx nx`)\n * - `run`: prefix for running package.json scripts (e.g. `npm run build`, `pnpm build`)\n *\n * @see docs/src/components/package-manager-exec-command.astro\n * @see docs/src/components/package-manager-short-command.astro\n */\nexport interface PackageManagerDisplayCommands {\n /** Prefix for running local binaries: npx, pnpm, yarn, bunx */\n exec: string;\n /** Prefix for running package.json scripts: `npm run`, pnpm, yarn, bun */\n run: string;\n /** Prefix for `create` commands: `npm create`, `pnpm create`, etc. */\n create: string;\n}\n\nexport const PACKAGE_MANAGER_COMMANDS: Record<\n string,\n PackageManagerDisplayCommands\n> = {\n npm: { exec: 'npx', run: 'npm run', create: 'npm create' },\n pnpm: { exec: 'pnpm', run: 'pnpm', create: 'pnpm create' },\n yarn: { exec: 'yarn', run: 'yarn', create: 'yarn create' },\n bun: { exec: 'bunx', run: 'bun', create: 'bun create' },\n};\n\n/**\n * Build a package manager exec command (e.g. pnpm cmd, npx cmd, bunx cmd)\n */\nexport const buildPackageManagerExecCommand = (pm: string, command: string) => {\n const prefix = PACKAGE_MANAGER_COMMANDS[pm]?.exec ?? pm;\n return `${prefix} ${command}`;\n};\n\n/**\n * Build a short package manager command (e.g. pnpm build, npm run build)\n */\nexport const buildPackageManagerShortCommand = (\n pm: string,\n command: string,\n) => {\n const prefix = PACKAGE_MANAGER_COMMANDS[pm]?.run ?? pm;\n return `${prefix} ${command}`;\n};\n\n/**\n * Build an install command for a given package manager\n */\nexport const buildInstallCommand = (pm: string, pkg: string, dev: boolean) => {\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${dev ? '-D' : '-'}w ${pkg}`;\n case 'yarn':\n return `yarn add ${dev ? '-D ' : ''}${pkg}`;\n case 'npm':\n return `npm install --legacy-peer-deps ${dev ? '-D ' : ''}${pkg}`;\n case 'bun':\n return `bun add ${dev ? '-D ' : ''}${pkg}`;\n default:\n return `${pm} install ${dev ? '-D ' : ''}${pkg}`;\n }\n};\n\n/**\n * Build the command that adds Nx to a non-Nx project, pinned to the nx\n * version the plugin is built against.\n */\nexport const buildNxInitCommand = (pm: string) => {\n const dlxPrefix =\n { npm: 'npx', pnpm: 'pnpm dlx', yarn: 'yarn dlx', bun: 'bunx' }[pm] ??\n 'npx';\n return `${dlxPrefix} nx@${NX_VERSION} init`;\n};\n\n/**\n * Build a command to create a new workspace using @aws/create-nx-workspace.\n *\n * Uses the `create` shorthand for each package manager:\n * npm create @aws/nx-workspace my-project\n * pnpm create @aws/nx-workspace my-project\n * yarn create @aws/nx-workspace my-project\n * bun create @aws/nx-workspace my-project\n *\n * The package manager is auto-detected by @aws/create-nx-workspace from the\n * invoking command, so --pm is not needed.\n */\nexport const buildCreateNxWorkspaceCommand = (\n pm: string,\n workspace: string,\n iac?: 'cdk' | 'terraform',\n tag?: string,\n module?: 'esm' | 'cjs',\n) => {\n const createPrefix = PACKAGE_MANAGER_COMMANDS[pm]?.create ?? `${pm} create`;\n const pkgName = tag ? `@aws/nx-workspace@${tag}` : '@aws/nx-workspace';\n const parts = [\n createPrefix,\n pkgName,\n // npm requires '--' to stop interpreting subsequent flags as npm config\n ...(pm === 'npm' ? ['--'] : []),\n workspace,\n ...(iac ? [`--iac=${iac}`] : []),\n ...(module ? [`--module=${module}`] : []),\n ];\n return parts.join(' ');\n};\n"],"names":["TS_VERSIONS","NX_VERSION","PACKAGE_MANAGER_COMMANDS","npm","exec","run","create","pnpm","yarn","bun","buildPackageManagerExecCommand","pm","command","prefix","buildPackageManagerShortCommand","buildInstallCommand","pkg","dev","buildNxInitCommand","dlxPrefix","buildCreateNxWorkspaceCommand","workspace","iac","tag","module","createPrefix","pkgName","parts","join"],"mappings":"AAAA;;;CAGC,GACD,SAASA,WAAW,QAAQ,gBAAa;AAEzC;;;;CAIC,GACD,OAAO,MAAMC,aAAaD,WAAW,CAAC,aAAa,CAAC;AAoBpD,OAAO,MAAME,2BAGT;IACFC,KAAK;QAAEC,MAAM;QAAOC,KAAK;QAAWC,QAAQ;IAAa;IACzDC,MAAM;QAAEH,MAAM;QAAQC,KAAK;QAAQC,QAAQ;IAAc;IACzDE,MAAM;QAAEJ,MAAM;QAAQC,KAAK;QAAQC,QAAQ;IAAc;IACzDG,KAAK;QAAEL,MAAM;QAAQC,KAAK;QAAOC,QAAQ;IAAa;AACxD,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMI,iCAAiC,CAACC,IAAYC;IACzD,MAAMC,SAASX,wBAAwB,CAACS,GAAG,EAAEP,QAAQO;IACrD,OAAO,GAAGE,OAAO,CAAC,EAAED,SAAS;AAC/B,EAAE;AAEF;;CAEC,GACD,OAAO,MAAME,kCAAkC,CAC7CH,IACAC;IAEA,MAAMC,SAASX,wBAAwB,CAACS,GAAG,EAAEN,OAAOM;IACpD,OAAO,GAAGE,OAAO,CAAC,EAAED,SAAS;AAC/B,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMG,sBAAsB,CAACJ,IAAYK,KAAaC;IAC3D,OAAQN;QACN,KAAK;YACH,OAAO,CAAC,SAAS,EAAEM,MAAM,OAAO,IAAI,EAAE,EAAED,KAAK;QAC/C,KAAK;YACH,OAAO,CAAC,SAAS,EAAEC,MAAM,QAAQ,KAAKD,KAAK;QAC7C,KAAK;YACH,OAAO,CAAC,+BAA+B,EAAEC,MAAM,QAAQ,KAAKD,KAAK;QACnE,KAAK;YACH,OAAO,CAAC,QAAQ,EAAEC,MAAM,QAAQ,KAAKD,KAAK;QAC5C;YACE,OAAO,GAAGL,GAAG,SAAS,EAAEM,MAAM,QAAQ,KAAKD,KAAK;IACpD;AACF,EAAE;AAEF;;;CAGC,GACD,OAAO,MAAME,qBAAqB,CAACP;IACjC,MAAMQ,YACJ;QAAEhB,KAAK;QAAOI,MAAM;QAAYC,MAAM;QAAYC,KAAK;IAAO,CAAC,CAACE,GAAG,IACnE;IACF,OAAO,GAAGQ,UAAU,IAAI,EAAElB,WAAW,KAAK,CAAC;AAC7C,EAAE;AAEF;;;;;;;;;;;CAWC,GACD,OAAO,MAAMmB,gCAAgC,CAC3CT,IACAU,WACAC,KACAC,KACAC;IAEA,MAAMC,eAAevB,wBAAwB,CAACS,GAAG,EAAEL,UAAU,GAAGK,GAAG,OAAO,CAAC;IAC3E,MAAMe,UAAUH,MAAM,CAAC,kBAAkB,EAAEA,KAAK,GAAG;IACnD,MAAMI,QAAQ;QACZF;QACAC;QACA,wEAAwE;WACpEf,OAAO,QAAQ;YAAC;SAAK,GAAG,EAAE;QAC9BU;WACIC,MAAM;YAAC,CAAC,MAAM,EAAEA,KAAK;SAAC,GAAG,EAAE;WAC3BE,SAAS;YAAC,CAAC,SAAS,EAAEA,QAAQ;SAAC,GAAG,EAAE;KACzC;IACD,OAAOG,MAAMC,IAAI,CAAC;AACpB,EAAE"}
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/commands.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { TS_VERSIONS } from './versions';\n\n/**\n * The nx version the plugin is built against. Commands that download nx\n * (e.g. `nx init`) pin to this version so the workspace's nx matches the\n * plugin's `@nx/*` packages — a mismatch deadlocks `nx sync`.\n */\nexport const NX_VERSION = TS_VERSIONS['@nx/devkit'];\n\n/**\n * Display-friendly command prefixes for each package manager.\n *\n * - `exec`: prefix for running local binaries (e.g. `npx nx`, `pnpm nx`, `bunx nx`)\n * - `run`: prefix for running package.json scripts (e.g. `npm run build`, `pnpm build`)\n *\n * @see docs/src/components/package-manager-exec-command.astro\n * @see docs/src/components/package-manager-short-command.astro\n */\nexport interface PackageManagerDisplayCommands {\n /** Prefix for running local binaries: npx, pnpm, yarn, bunx */\n exec: string;\n /** Prefix for running package.json scripts: `npm run`, pnpm, yarn, bun */\n run: string;\n /** Prefix for `create` commands: `npm create`, `pnpm create`, etc. */\n create: string;\n}\n\nexport const PACKAGE_MANAGER_COMMANDS: Record<\n string,\n PackageManagerDisplayCommands\n> = {\n npm: { exec: 'npx', run: 'npm run', create: 'npm create' },\n pnpm: { exec: 'pnpm', run: 'pnpm', create: 'pnpm create' },\n yarn: { exec: 'yarn', run: 'yarn', create: 'yarn create' },\n bun: { exec: 'bunx', run: 'bun', create: 'bun create' },\n};\n\n/**\n * Build a package manager exec command (e.g. pnpm cmd, npx cmd, bunx cmd)\n */\nexport const buildPackageManagerExecCommand = (pm: string, command: string) => {\n const prefix = PACKAGE_MANAGER_COMMANDS[pm]?.exec ?? pm;\n return `${prefix} ${command}`;\n};\n\n/**\n * Build a short package manager command (e.g. pnpm build, npm run build)\n */\nexport const buildPackageManagerShortCommand = (\n pm: string,\n command: string,\n) => {\n const prefix = PACKAGE_MANAGER_COMMANDS[pm]?.run ?? pm;\n return `${prefix} ${command}`;\n};\n\n/**\n * Build an install command. With `project`, targets that project's manifest\n * (pnpm `--filter` by unscoped name, npm/bun by `projectDir` defaulting to\n * `packages/<name>`, yarn by fully-qualified name); otherwise the root.\n */\nexport const buildInstallCommand = (\n pm: string,\n pkg: string,\n dev: boolean,\n project?: string,\n projectDir?: string,\n) => {\n if (project) {\n const shortName = project.split('/').pop();\n const dir = projectDir ?? `packages/${shortName}`;\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${dev ? '-D ' : ''}${pkg} --filter ${shortName}`;\n case 'yarn':\n return `yarn workspace ${project} add ${dev ? '-D ' : ''}${pkg}`;\n case 'npm':\n return `npm install --legacy-peer-deps ${dev ? '-D ' : ''}${pkg} -w ${dir}`;\n case 'bun':\n return `bun add ${dev ? '-D ' : ''}${pkg} --cwd ${dir}`;\n default:\n return `${pm} install ${dev ? '-D ' : ''}${pkg}`;\n }\n }\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${dev ? '-D' : '-'}w ${pkg}`;\n case 'yarn':\n return `yarn add ${dev ? '-D ' : ''}${pkg}`;\n case 'npm':\n return `npm install --legacy-peer-deps ${dev ? '-D ' : ''}${pkg}`;\n case 'bun':\n return `bun add ${dev ? '-D ' : ''}${pkg}`;\n default:\n return `${pm} install ${dev ? '-D ' : ''}${pkg}`;\n }\n};\n\n/**\n * Build the command that adds Nx to a non-Nx project, pinned to the nx\n * version the plugin is built against.\n */\nexport const buildNxInitCommand = (pm: string) => {\n const dlxPrefix =\n { npm: 'npx', pnpm: 'pnpm dlx', yarn: 'yarn dlx', bun: 'bunx' }[pm] ??\n 'npx';\n return `${dlxPrefix} nx@${NX_VERSION} init`;\n};\n\n/**\n * Build a command to create a new workspace using @aws/create-nx-workspace.\n *\n * Uses the `create` shorthand for each package manager:\n * npm create @aws/nx-workspace my-project\n * pnpm create @aws/nx-workspace my-project\n * yarn create @aws/nx-workspace my-project\n * bun create @aws/nx-workspace my-project\n *\n * The package manager is auto-detected by @aws/create-nx-workspace from the\n * invoking command, so --pm is not needed.\n */\nexport const buildCreateNxWorkspaceCommand = (\n pm: string,\n workspace: string,\n iac?: 'cdk' | 'terraform',\n tag?: string,\n module?: 'esm' | 'cjs',\n extraArgs?: string,\n) => {\n const createPrefix = PACKAGE_MANAGER_COMMANDS[pm]?.create ?? `${pm} create`;\n const pkgName = tag ? `@aws/nx-workspace@${tag}` : '@aws/nx-workspace';\n const parts = [\n createPrefix,\n pkgName,\n // npm requires '--' to stop interpreting subsequent flags as npm config\n ...(pm === 'npm' ? ['--'] : []),\n workspace,\n ...(iac ? [`--iac=${iac}`] : []),\n ...(module ? [`--module=${module}`] : []),\n ...(extraArgs ? [extraArgs] : []),\n ];\n return parts.join(' ');\n};\n"],"names":["TS_VERSIONS","NX_VERSION","PACKAGE_MANAGER_COMMANDS","npm","exec","run","create","pnpm","yarn","bun","buildPackageManagerExecCommand","pm","command","prefix","buildPackageManagerShortCommand","buildInstallCommand","pkg","dev","project","projectDir","shortName","split","pop","dir","buildNxInitCommand","dlxPrefix","buildCreateNxWorkspaceCommand","workspace","iac","tag","module","extraArgs","createPrefix","pkgName","parts","join"],"mappings":"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"}
@@ -8,6 +8,17 @@ import type { IacConfig } from '../iac';
8
8
  export * from '../../license/config-types';
9
9
  export type { Containers, ContainersConfig } from '../containers';
10
10
  export type { Iac, IacConfig } from '../iac';
11
+ /**
12
+ * Configuration for how generators manage dependencies via the package manager
13
+ */
14
+ export interface PackageManagerConfig {
15
+ /**
16
+ * Whether generators record dependency versions in the package manager's
17
+ * catalog (pnpm/yarn/bun) via `catalog:` refs. When `false`, direct version
18
+ * ranges are written to each project. Defaults to `true`; no effect on npm.
19
+ */
20
+ catalogs?: boolean;
21
+ }
11
22
  /**
12
23
  * Configuration for the nx plugin
13
24
  */
@@ -24,6 +35,11 @@ export interface AwsNxPluginConfig {
24
35
  * Configuration for container tooling (build/push/login)
25
36
  */
26
37
  containers?: ContainersConfig;
38
+ /**
39
+ * Configuration for how generators manage dependencies via the package
40
+ * manager (e.g. whether to use dependency catalogs)
41
+ */
42
+ packageManager?: PackageManagerConfig;
27
43
  /**
28
44
  * List of tags
29
45
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/config/index.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { LicenseConfig } from '../../license/config-types';\nimport type { ContainersConfig } from '../containers';\nimport type { IacConfig } from '../iac';\n\nexport * from '../../license/config-types';\nexport type { Containers, ContainersConfig } from '../containers';\nexport type { Iac, IacConfig } from '../iac';\n\n/**\n * Configuration for the nx plugin\n */\nexport interface AwsNxPluginConfig {\n /**\n * Configuration for the license sync generator\n */\n license?: LicenseConfig;\n\n /**\n * Configuration for infrastructure as code\n */\n iac?: IacConfig;\n\n /**\n * Configuration for container tooling (build/push/login)\n */\n containers?: ContainersConfig;\n\n /**\n * List of tags\n */\n tags?: string[];\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAKD,cAAc,gCAA6B"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/config/index.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { LicenseConfig } from '../../license/config-types';\nimport type { ContainersConfig } from '../containers';\nimport type { IacConfig } from '../iac';\n\nexport * from '../../license/config-types';\nexport type { Containers, ContainersConfig } from '../containers';\nexport type { Iac, IacConfig } from '../iac';\n\n/**\n * Configuration for how generators manage dependencies via the package manager\n */\nexport interface PackageManagerConfig {\n /**\n * Whether generators record dependency versions in the package manager's\n * catalog (pnpm/yarn/bun) via `catalog:` refs. When `false`, direct version\n * ranges are written to each project. Defaults to `true`; no effect on npm.\n */\n catalogs?: boolean;\n}\n\n/**\n * Configuration for the nx plugin\n */\nexport interface AwsNxPluginConfig {\n /**\n * Configuration for the license sync generator\n */\n license?: LicenseConfig;\n\n /**\n * Configuration for infrastructure as code\n */\n iac?: IacConfig;\n\n /**\n * Configuration for container tooling (build/push/login)\n */\n containers?: ContainersConfig;\n\n /**\n * Configuration for how generators manage dependencies via the package\n * manager (e.g. whether to use dependency catalogs)\n */\n packageManager?: PackageManagerConfig;\n\n /**\n * List of tags\n */\n tags?: string[];\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAKD,cAAc,gCAA6B"}
@@ -14,9 +14,10 @@ export declare const ensureAwsNxPluginConfig: (tree: Tree) => Promise<AwsNxPlugi
14
14
  *
15
15
  * Uses jiti to evaluate the TypeScript source in-memory with proper module
16
16
  * resolution — imports from @aws/nx-plugin/* resolve via alias, and any
17
- * third-party imports resolve from the workspace's node_modules.
17
+ * third-party imports resolve from the workspace's node_modules. Synchronous,
18
+ * since `jiti.evalModule` runs in-memory.
18
19
  */
19
- export declare const readAwsNxPluginConfig: (tree: Tree) => Promise<AwsNxPluginConfig | undefined>;
20
+ export declare const readAwsNxPluginConfig: (tree: Tree) => AwsNxPluginConfig | undefined;
20
21
  /**
21
22
  * Read config directly from disk. Used by executors that run in the real
22
23
  * workspace (not a virtual Tree). Resolves all imports — including
@@ -23,15 +23,16 @@ export const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';
23
23
  generateFiles(tree, joinPathFragments(import.meta.dirname, 'files'), '.', {});
24
24
  }
25
25
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
26
- return await readAwsNxPluginConfig(tree);
26
+ return readAwsNxPluginConfig(tree);
27
27
  };
28
28
  /**
29
29
  * Read config from the aws nx plugin configuration file.
30
30
  *
31
31
  * Uses jiti to evaluate the TypeScript source in-memory with proper module
32
32
  * resolution — imports from @aws/nx-plugin/* resolve via alias, and any
33
- * third-party imports resolve from the workspace's node_modules.
34
- */ export const readAwsNxPluginConfig = async (tree)=>{
33
+ * third-party imports resolve from the workspace's node_modules. Synchronous,
34
+ * since `jiti.evalModule` runs in-memory.
35
+ */ export const readAwsNxPluginConfig = (tree)=>{
35
36
  if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {
36
37
  return undefined;
37
38
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/config/utils.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { generateFiles, joinPathFragments, type Tree } from '@nx/devkit';\nimport { existsSync, readFileSync } from 'fs';\nimport { createJiti } from 'jiti';\nimport { join } from 'path';\nimport { applyGritQL, matchGritQL } from '../ast';\nimport { formatFilesInSubtree } from '../format';\nimport type { AwsNxPluginConfig } from '.';\n\nexport const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';\n\n/**\n * Aliases used by jiti to resolve `@aws/nx-plugin` imports in the config file\n * to this package's source, so the config can be evaluated in-memory.\n */\nconst AWS_NX_PLUGIN_JITI_ALIASES = {\n '@aws/nx-plugin/sdk/license': join(\n import.meta.dirname,\n '..',\n '..',\n 'sdk',\n 'license',\n ),\n '@aws/nx-plugin': join(import.meta.dirname, '..', '..'),\n};\n\n/**\n * Ensure that the config file exists\n */\nexport const ensureAwsNxPluginConfig = async (\n tree: Tree,\n): Promise<AwsNxPluginConfig> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n // Create an empty config file if it doesn't already exist\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n '.',\n {},\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return await readAwsNxPluginConfig(tree)!;\n};\n\n/**\n * Read config from the aws nx plugin configuration file.\n *\n * Uses jiti to evaluate the TypeScript source in-memory with proper module\n * resolution — imports from @aws/nx-plugin/* resolve via alias, and any\n * third-party imports resolve from the workspace's node_modules.\n */\nexport const readAwsNxPluginConfig = async (\n tree: Tree,\n): Promise<AwsNxPluginConfig | undefined> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n return undefined;\n }\n const source = tree.read(AWS_NX_PLUGIN_CONFIG_FILE_NAME, 'utf-8')!;\n const configFilePath = join(tree.root, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n\n const mod = jiti.evalModule(source, { filename: configFilePath });\n return (mod as any).default ?? mod;\n};\n\n/**\n * Read config directly from disk. Used by executors that run in the real\n * workspace (not a virtual Tree). Resolves all imports — including\n * third-party dependencies — from the workspace's node_modules.\n */\nexport const readAwsNxPluginConfigFromDisk = (\n workspaceRoot: string,\n): AwsNxPluginConfig | undefined => {\n const configPath = join(workspaceRoot, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n if (!existsSync(configPath)) return undefined;\n\n const source = readFileSync(configPath, 'utf-8');\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n const mod = jiti.evalModule(source, { filename: configPath });\n return (mod as any).default ?? mod;\n};\n\nconst PLACEHOLDER = '\"__PLACEHOLDER__\"';\n\n/**\n * Use GritQL to set a top-level property in the export default object,\n * then substitute the placeholder with the JSON-serialized value.\n * Preserves all other properties (including JS expressions) untouched.\n */\nconst setConfigProperty = async (\n tree: Tree,\n filePath: string,\n key: string,\n value: unknown,\n): Promise<void> => {\n const json = JSON.stringify(value);\n\n // Check if the property already exists using a named metavariable\n // to avoid ambiguity with anonymous $_ in nested where clauses\n const existsInSatisfies = await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_ satisfies $_\\` }`,\n );\n const existsInPlain =\n !existsInSatisfies &&\n (await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_\\` }`,\n ));\n\n if (existsInSatisfies || existsInPlain) {\n // Replace only this property's value, scoped to the export default\n const within = existsInSatisfies\n ? `within \\`export default $_ satisfies $_\\``\n : `within \\`export default $_\\``;\n await applyGritQL(\n tree,\n filePath,\n `\\`${key}: $old\\` => \\`${key}: ${PLACEHOLDER}\\` where { $old <: ${within} }`,\n );\n } else {\n // Add the new property using GritQL's += (accumulate) operator.\n // For non-empty objects, += appends correctly without double commas.\n // For empty objects, += fails so we fall back to a direct replacement.\n let added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props } satisfies $type\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { } satisfies $type\\` => \\`export default { ${key}: ${PLACEHOLDER} } satisfies $type\\``,\n );\n }\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props }\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n }\n\n if (!added) {\n await applyGritQL(\n tree,\n filePath,\n `\\`export default { }\\` => \\`export default { ${key}: ${PLACEHOLDER} }\\``,\n );\n }\n }\n\n // Substitute the placeholder with the actual JSON value\n const content = tree.read(filePath)!.toString();\n tree.write(filePath, content.replace(PLACEHOLDER, json));\n};\n\n/**\n * Update the aws nx plugin config file.\n * Only the specified top-level keys are replaced; all other properties\n * (including those containing JS expressions) are left untouched in source.\n */\nexport const updateAwsNxPluginConfig = async (\n tree: Tree,\n configUpdate: Partial<AwsNxPluginConfig>,\n): Promise<void> => {\n const filePath = AWS_NX_PLUGIN_CONFIG_FILE_NAME;\n\n for (const [key, value] of Object.entries(configUpdate)) {\n await setConfigProperty(tree, filePath, key, value);\n }\n\n // Prettier formats the result into properly indented TypeScript\n await formatFilesInSubtree(tree, filePath);\n};\n"],"names":["generateFiles","joinPathFragments","existsSync","readFileSync","createJiti","join","applyGritQL","matchGritQL","formatFilesInSubtree","AWS_NX_PLUGIN_CONFIG_FILE_NAME","AWS_NX_PLUGIN_JITI_ALIASES","dirname","ensureAwsNxPluginConfig","tree","exists","readAwsNxPluginConfig","undefined","source","read","configFilePath","root","jiti","filename","alias","mod","evalModule","default","readAwsNxPluginConfigFromDisk","workspaceRoot","configPath","PLACEHOLDER","setConfigProperty","filePath","key","value","json","JSON","stringify","existsInSatisfies","existsInPlain","within","added","content","toString","write","replace","updateAwsNxPluginConfig","configUpdate","Object","entries"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/config/utils.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { generateFiles, joinPathFragments, type Tree } from '@nx/devkit';\nimport { existsSync, readFileSync } from 'fs';\nimport { createJiti } from 'jiti';\nimport { join } from 'path';\nimport { applyGritQL, matchGritQL } from '../ast';\nimport { formatFilesInSubtree } from '../format';\nimport type { AwsNxPluginConfig } from '.';\n\nexport const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';\n\n/**\n * Aliases used by jiti to resolve `@aws/nx-plugin` imports in the config file\n * to this package's source, so the config can be evaluated in-memory.\n */\nconst AWS_NX_PLUGIN_JITI_ALIASES = {\n '@aws/nx-plugin/sdk/license': join(\n import.meta.dirname,\n '..',\n '..',\n 'sdk',\n 'license',\n ),\n '@aws/nx-plugin': join(import.meta.dirname, '..', '..'),\n};\n\n/**\n * Ensure that the config file exists\n */\nexport const ensureAwsNxPluginConfig = async (\n tree: Tree,\n): Promise<AwsNxPluginConfig> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n // Create an empty config file if it doesn't already exist\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n '.',\n {},\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return readAwsNxPluginConfig(tree)!;\n};\n\n/**\n * Read config from the aws nx plugin configuration file.\n *\n * Uses jiti to evaluate the TypeScript source in-memory with proper module\n * resolution — imports from @aws/nx-plugin/* resolve via alias, and any\n * third-party imports resolve from the workspace's node_modules. Synchronous,\n * since `jiti.evalModule` runs in-memory.\n */\nexport const readAwsNxPluginConfig = (\n tree: Tree,\n): AwsNxPluginConfig | undefined => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n return undefined;\n }\n const source = tree.read(AWS_NX_PLUGIN_CONFIG_FILE_NAME, 'utf-8')!;\n const configFilePath = join(tree.root, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n\n const mod = jiti.evalModule(source, { filename: configFilePath });\n return (mod as any).default ?? mod;\n};\n\n/**\n * Read config directly from disk. Used by executors that run in the real\n * workspace (not a virtual Tree). Resolves all imports — including\n * third-party dependencies — from the workspace's node_modules.\n */\nexport const readAwsNxPluginConfigFromDisk = (\n workspaceRoot: string,\n): AwsNxPluginConfig | undefined => {\n const configPath = join(workspaceRoot, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n if (!existsSync(configPath)) return undefined;\n\n const source = readFileSync(configPath, 'utf-8');\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n const mod = jiti.evalModule(source, { filename: configPath });\n return (mod as any).default ?? mod;\n};\n\nconst PLACEHOLDER = '\"__PLACEHOLDER__\"';\n\n/**\n * Use GritQL to set a top-level property in the export default object,\n * then substitute the placeholder with the JSON-serialized value.\n * Preserves all other properties (including JS expressions) untouched.\n */\nconst setConfigProperty = async (\n tree: Tree,\n filePath: string,\n key: string,\n value: unknown,\n): Promise<void> => {\n const json = JSON.stringify(value);\n\n // Check if the property already exists using a named metavariable\n // to avoid ambiguity with anonymous $_ in nested where clauses\n const existsInSatisfies = await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_ satisfies $_\\` }`,\n );\n const existsInPlain =\n !existsInSatisfies &&\n (await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_\\` }`,\n ));\n\n if (existsInSatisfies || existsInPlain) {\n // Replace only this property's value, scoped to the export default\n const within = existsInSatisfies\n ? `within \\`export default $_ satisfies $_\\``\n : `within \\`export default $_\\``;\n await applyGritQL(\n tree,\n filePath,\n `\\`${key}: $old\\` => \\`${key}: ${PLACEHOLDER}\\` where { $old <: ${within} }`,\n );\n } else {\n // Add the new property using GritQL's += (accumulate) operator.\n // For non-empty objects, += appends correctly without double commas.\n // For empty objects, += fails so we fall back to a direct replacement.\n let added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props } satisfies $type\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { } satisfies $type\\` => \\`export default { ${key}: ${PLACEHOLDER} } satisfies $type\\``,\n );\n }\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props }\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n }\n\n if (!added) {\n await applyGritQL(\n tree,\n filePath,\n `\\`export default { }\\` => \\`export default { ${key}: ${PLACEHOLDER} }\\``,\n );\n }\n }\n\n // Substitute the placeholder with the actual JSON value\n const content = tree.read(filePath)!.toString();\n tree.write(filePath, content.replace(PLACEHOLDER, json));\n};\n\n/**\n * Update the aws nx plugin config file.\n * Only the specified top-level keys are replaced; all other properties\n * (including those containing JS expressions) are left untouched in source.\n */\nexport const updateAwsNxPluginConfig = async (\n tree: Tree,\n configUpdate: Partial<AwsNxPluginConfig>,\n): Promise<void> => {\n const filePath = AWS_NX_PLUGIN_CONFIG_FILE_NAME;\n\n for (const [key, value] of Object.entries(configUpdate)) {\n await setConfigProperty(tree, filePath, key, value);\n }\n\n // Prettier formats the result into properly indented TypeScript\n await formatFilesInSubtree(tree, filePath);\n};\n"],"names":["generateFiles","joinPathFragments","existsSync","readFileSync","createJiti","join","applyGritQL","matchGritQL","formatFilesInSubtree","AWS_NX_PLUGIN_CONFIG_FILE_NAME","AWS_NX_PLUGIN_JITI_ALIASES","dirname","ensureAwsNxPluginConfig","tree","exists","readAwsNxPluginConfig","undefined","source","read","configFilePath","root","jiti","filename","alias","mod","evalModule","default","readAwsNxPluginConfigFromDisk","workspaceRoot","configPath","PLACEHOLDER","setConfigProperty","filePath","key","value","json","JSON","stringify","existsInSatisfies","existsInPlain","within","added","content","toString","write","replace","updateAwsNxPluginConfig","configUpdate","Object","entries"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
- */ import { addDependenciesToPackageJson, generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
4
+ */ import { generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
5
5
  import { addTargetToLocalDev } from "../../../connection/local-dev.js";
6
6
  import runtimeConfigGenerator from "../../../ts/react-website/runtime-config/generator.js";
7
7
  import { addSingleImport, applyGritQL } from "../../ast.js";
8
+ import { addDependenciesToPackageJson } from "../../dependencies.js";
8
9
  import { updateGitIgnore } from "../../git.js";
9
10
  import { kebabCase, toClassName } from "../../names.js";
10
11
  import { sortObjectKeys } from "../../object.js";
@@ -136,7 +137,7 @@ import { withVersions } from "../../versions.js";
136
137
  '@tanstack/react-query-devtools'
137
138
  ]), withVersions([
138
139
  '@smithy/types'
139
- ]));
140
+ ]), joinPathFragments(frontendProjectConfig.root, 'package.json'));
140
141
  };
141
142
 
142
143
  //# sourceMappingURL=react.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/utils/connection/open-api/react.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTargetToLocalDev } from '../../../connection/local-dev';\nimport runtimeConfigGenerator from '../../../ts/react-website/runtime-config/generator';\nimport { addSingleImport, applyGritQL } from '../../ast';\nimport { updateGitIgnore } from '../../git';\nimport { kebabCase, toClassName } from '../../names';\nimport { sortObjectKeys } from '../../object';\nimport { withVersions } from '../../versions';\n\nexport interface AddOpenApiReactClientOptions {\n /**\n * The react project to add the openapi client and build targets to\n */\n frontendProjectConfig: ProjectConfiguration;\n /**\n * The backend project which serves the api\n */\n backendProjectConfig: ProjectConfiguration;\n /**\n * The project which builds/generates the openapi spec\n */\n specBuildProject: ProjectConfiguration;\n /**\n * Name of the api\n */\n apiName: string;\n /**\n * Path to the openapi spec from the workspace root\n */\n specPath: string;\n /**\n * Fully qualified target name for the target that builds/generates the openapi spec\n */\n specBuildTargetName: string;\n /**\n * Authentication method\n */\n auth: 'iam' | 'cognito' | 'custom';\n /**\n * Port on which the backend project's local server listens\n */\n port: number;\n /**\n * When true, the generated provider reads from runtimeConfig.agentRuntimes\n * and converts Bedrock AgentCore Runtime ARNs to HTTP URLs.\n * When false (default), reads from runtimeConfig.apis directly.\n */\n isAgentRuntime?: boolean;\n /**\n * When true, skips the dev target setup. Use this when the caller\n * handles dev target configuration separately (e.g. agent connections\n * that use a component-specific dev target instead of 'serve').\n */\n skipLocalDev?: boolean;\n}\n\n/**\n * Adds an OpenAPI React client to the frontend project along with supporting build targets\n */\nexport const addOpenApiReactClient = async (\n tree: Tree,\n {\n apiName,\n frontendProjectConfig,\n backendProjectConfig,\n specBuildProject,\n specPath,\n specBuildTargetName,\n auth,\n port,\n isAgentRuntime = false,\n skipLocalDev = false,\n }: AddOpenApiReactClientOptions,\n) => {\n const clientGenTarget = `generate:${kebabCase(apiName)}-client`;\n const clientGenWatchTarget = `watch-${clientGenTarget}`;\n\n const generatedClientDir = joinPathFragments('generated', kebabCase(apiName));\n const generatedClientDirFromRoot = joinPathFragments(\n frontendProjectConfig.sourceRoot,\n generatedClientDir,\n );\n\n // Add TypeScript client generation to Frontend project.json\n updateProjectConfiguration(tree, frontendProjectConfig.name, {\n ...frontendProjectConfig,\n targets: sortObjectKeys({\n ...frontendProjectConfig.targets,\n // Generate should run before compile and bundle as the client is created as part of the website src\n ...Object.fromEntries(\n ['compile', 'bundle'].map((target) => [\n target,\n {\n ...frontendProjectConfig.targets?.[target],\n dependsOn: [\n ...(\n frontendProjectConfig.targets?.[target]?.dependsOn ?? []\n ).filter((t) => t !== clientGenTarget),\n clientGenTarget,\n ],\n },\n ]),\n ),\n [clientGenTarget]: {\n cache: true,\n executor: 'nx:run-commands',\n inputs: [\n {\n dependentTasksOutputFiles: '**/*.json',\n },\n ],\n outputs: [\n joinPathFragments('{workspaceRoot}', generatedClientDirFromRoot),\n ],\n options: {\n commands: [\n `nx g @aws/nx-plugin:open-api#ts-hooks --openApiSpecPath=\"${specPath}\" --outputPath=\"${generatedClientDirFromRoot}\" --no-interactive`,\n ],\n },\n dependsOn: [specBuildTargetName],\n },\n // Watch target for regenerating the client\n [clientGenWatchTarget]: {\n executor: 'nx:run-commands',\n options: {\n commands: [\n `nx watch --projects=${specBuildProject.name} --includeDependencies -- nx run ${frontendProjectConfig.name}:\"${clientGenTarget}\"`,\n ],\n },\n continuous: true,\n },\n }),\n });\n\n const relativeSrcDir = frontendProjectConfig.sourceRoot.slice(\n frontendProjectConfig.root.length + 1,\n );\n\n // Ignore the generated client by default\n // Users can safely remove the entry from the .gitignore if they prefer to check it in\n updateGitIgnore(tree, frontendProjectConfig.root, (patterns) => [\n ...patterns,\n joinPathFragments(relativeSrcDir, generatedClientDir),\n ]);\n\n // Ensure that the frontend has runtime config as we'll use the url for creating the client\n await runtimeConfigGenerator(tree, {\n project: frontendProjectConfig.name,\n });\n\n // Add sigv4 fetch\n if (auth === 'iam') {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, '../../files/website/hooks/sigv4'),\n joinPathFragments(frontendProjectConfig.sourceRoot, 'hooks'),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n }\n\n // Generate the tanstack query provider if it does not exist already\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n '../../files/website/components/tanstack-query',\n ),\n joinPathFragments(frontendProjectConfig.sourceRoot, 'components'),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n const apiNameClassName = toClassName(apiName);\n\n // Add a hook to instantiate the client\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n frontendProjectConfig.sourceRoot,\n {\n auth,\n apiName,\n apiNameClassName,\n generatedClientDir,\n isAgentRuntime,\n },\n );\n\n // Update main.tsx to add required providers\n const mainTsxPath = joinPathFragments(\n frontendProjectConfig.sourceRoot,\n 'main.tsx',\n );\n\n // Add the query client provider if it doesn't exist already\n await addSingleImport(\n tree,\n mainTsxPath,\n 'QueryClientProvider',\n './components/QueryClientProvider',\n );\n await applyGritQL(\n tree,\n mainTsxPath,\n '`<App />` => `<QueryClientProvider><App /></QueryClientProvider>` where { $program <: not contains `<QueryClientProvider>$_</QueryClientProvider>` }',\n );\n\n // Add the api provider if it does not exist\n const providerName = `${apiNameClassName}Provider`;\n await addSingleImport(\n tree,\n mainTsxPath,\n providerName,\n `./components/${providerName}`,\n );\n await applyGritQL(\n tree,\n mainTsxPath,\n `\\`<App />\\` => \\`<${providerName}><App /></${providerName}>\\` where { $program <: not contains \\`<${providerName}>$_</${providerName}>\\` }`,\n );\n\n // Update the dev target on the website to use our local server.\n // Callers that handle the dev target separately (e.g. agent connections) set skipLocalDev.\n if (!skipLocalDev) {\n await addTargetToLocalDev(\n tree,\n frontendProjectConfig.name,\n backendProjectConfig.name,\n {\n url: `http://localhost:${port}/`,\n apiName,\n // Additionally add a dependency on the generate watch command to ensure that local\n // API changes that affect the client are also reloaded.\n // We include a dependency on the generate target as watch ONLY triggers on a change,\n // and we need to ensure the client is generated the first time if not already present.\n additionalDependencyTargets: [clientGenTarget, clientGenWatchTarget],\n },\n );\n }\n\n addDependenciesToPackageJson(\n tree,\n withVersions([\n ...((auth === 'iam'\n ? [\n 'oidc-client-ts',\n 'react-oidc-context',\n '@aws-sdk/credential-provider-cognito-identity',\n 'aws4fetch',\n ]\n : []) as any),\n ...((auth === 'cognito' ? ['react-oidc-context'] : []) as any),\n '@tanstack/react-query',\n '@tanstack/react-query-devtools',\n ]),\n withVersions(['@smithy/types']),\n );\n};\n"],"names":["addDependenciesToPackageJson","generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addTargetToLocalDev","runtimeConfigGenerator","addSingleImport","applyGritQL","updateGitIgnore","kebabCase","toClassName","sortObjectKeys","withVersions","addOpenApiReactClient","tree","apiName","frontendProjectConfig","backendProjectConfig","specBuildProject","specPath","specBuildTargetName","auth","port","isAgentRuntime","skipLocalDev","clientGenTarget","clientGenWatchTarget","generatedClientDir","generatedClientDirFromRoot","sourceRoot","name","targets","Object","fromEntries","map","target","dependsOn","filter","t","cache","executor","inputs","dependentTasksOutputFiles","outputs","options","commands","continuous","relativeSrcDir","slice","root","length","patterns","project","dirname","overwriteStrategy","KeepExisting","apiNameClassName","mainTsxPath","providerName","url","additionalDependencyTargets"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/utils/connection/open-api/react.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTargetToLocalDev } from '../../../connection/local-dev';\nimport runtimeConfigGenerator from '../../../ts/react-website/runtime-config/generator';\nimport { addSingleImport, applyGritQL } from '../../ast';\nimport { addDependenciesToPackageJson } from '../../dependencies';\nimport { updateGitIgnore } from '../../git';\nimport { kebabCase, toClassName } from '../../names';\nimport { sortObjectKeys } from '../../object';\nimport { withVersions } from '../../versions';\n\nexport interface AddOpenApiReactClientOptions {\n /**\n * The react project to add the openapi client and build targets to\n */\n frontendProjectConfig: ProjectConfiguration;\n /**\n * The backend project which serves the api\n */\n backendProjectConfig: ProjectConfiguration;\n /**\n * The project which builds/generates the openapi spec\n */\n specBuildProject: ProjectConfiguration;\n /**\n * Name of the api\n */\n apiName: string;\n /**\n * Path to the openapi spec from the workspace root\n */\n specPath: string;\n /**\n * Fully qualified target name for the target that builds/generates the openapi spec\n */\n specBuildTargetName: string;\n /**\n * Authentication method\n */\n auth: 'iam' | 'cognito' | 'custom';\n /**\n * Port on which the backend project's local server listens\n */\n port: number;\n /**\n * When true, the generated provider reads from runtimeConfig.agentRuntimes\n * and converts Bedrock AgentCore Runtime ARNs to HTTP URLs.\n * When false (default), reads from runtimeConfig.apis directly.\n */\n isAgentRuntime?: boolean;\n /**\n * When true, skips the dev target setup. Use this when the caller\n * handles dev target configuration separately (e.g. agent connections\n * that use a component-specific dev target instead of 'serve').\n */\n skipLocalDev?: boolean;\n}\n\n/**\n * Adds an OpenAPI React client to the frontend project along with supporting build targets\n */\nexport const addOpenApiReactClient = async (\n tree: Tree,\n {\n apiName,\n frontendProjectConfig,\n backendProjectConfig,\n specBuildProject,\n specPath,\n specBuildTargetName,\n auth,\n port,\n isAgentRuntime = false,\n skipLocalDev = false,\n }: AddOpenApiReactClientOptions,\n) => {\n const clientGenTarget = `generate:${kebabCase(apiName)}-client`;\n const clientGenWatchTarget = `watch-${clientGenTarget}`;\n\n const generatedClientDir = joinPathFragments('generated', kebabCase(apiName));\n const generatedClientDirFromRoot = joinPathFragments(\n frontendProjectConfig.sourceRoot,\n generatedClientDir,\n );\n\n // Add TypeScript client generation to Frontend project.json\n updateProjectConfiguration(tree, frontendProjectConfig.name, {\n ...frontendProjectConfig,\n targets: sortObjectKeys({\n ...frontendProjectConfig.targets,\n // Generate should run before compile and bundle as the client is created as part of the website src\n ...Object.fromEntries(\n ['compile', 'bundle'].map((target) => [\n target,\n {\n ...frontendProjectConfig.targets?.[target],\n dependsOn: [\n ...(\n frontendProjectConfig.targets?.[target]?.dependsOn ?? []\n ).filter((t) => t !== clientGenTarget),\n clientGenTarget,\n ],\n },\n ]),\n ),\n [clientGenTarget]: {\n cache: true,\n executor: 'nx:run-commands',\n inputs: [\n {\n dependentTasksOutputFiles: '**/*.json',\n },\n ],\n outputs: [\n joinPathFragments('{workspaceRoot}', generatedClientDirFromRoot),\n ],\n options: {\n commands: [\n `nx g @aws/nx-plugin:open-api#ts-hooks --openApiSpecPath=\"${specPath}\" --outputPath=\"${generatedClientDirFromRoot}\" --no-interactive`,\n ],\n },\n dependsOn: [specBuildTargetName],\n },\n // Watch target for regenerating the client\n [clientGenWatchTarget]: {\n executor: 'nx:run-commands',\n options: {\n commands: [\n `nx watch --projects=${specBuildProject.name} --includeDependencies -- nx run ${frontendProjectConfig.name}:\"${clientGenTarget}\"`,\n ],\n },\n continuous: true,\n },\n }),\n });\n\n const relativeSrcDir = frontendProjectConfig.sourceRoot.slice(\n frontendProjectConfig.root.length + 1,\n );\n\n // Ignore the generated client by default\n // Users can safely remove the entry from the .gitignore if they prefer to check it in\n updateGitIgnore(tree, frontendProjectConfig.root, (patterns) => [\n ...patterns,\n joinPathFragments(relativeSrcDir, generatedClientDir),\n ]);\n\n // Ensure that the frontend has runtime config as we'll use the url for creating the client\n await runtimeConfigGenerator(tree, {\n project: frontendProjectConfig.name,\n });\n\n // Add sigv4 fetch\n if (auth === 'iam') {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, '../../files/website/hooks/sigv4'),\n joinPathFragments(frontendProjectConfig.sourceRoot, 'hooks'),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n }\n\n // Generate the tanstack query provider if it does not exist already\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n '../../files/website/components/tanstack-query',\n ),\n joinPathFragments(frontendProjectConfig.sourceRoot, 'components'),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n const apiNameClassName = toClassName(apiName);\n\n // Add a hook to instantiate the client\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n frontendProjectConfig.sourceRoot,\n {\n auth,\n apiName,\n apiNameClassName,\n generatedClientDir,\n isAgentRuntime,\n },\n );\n\n // Update main.tsx to add required providers\n const mainTsxPath = joinPathFragments(\n frontendProjectConfig.sourceRoot,\n 'main.tsx',\n );\n\n // Add the query client provider if it doesn't exist already\n await addSingleImport(\n tree,\n mainTsxPath,\n 'QueryClientProvider',\n './components/QueryClientProvider',\n );\n await applyGritQL(\n tree,\n mainTsxPath,\n '`<App />` => `<QueryClientProvider><App /></QueryClientProvider>` where { $program <: not contains `<QueryClientProvider>$_</QueryClientProvider>` }',\n );\n\n // Add the api provider if it does not exist\n const providerName = `${apiNameClassName}Provider`;\n await addSingleImport(\n tree,\n mainTsxPath,\n providerName,\n `./components/${providerName}`,\n );\n await applyGritQL(\n tree,\n mainTsxPath,\n `\\`<App />\\` => \\`<${providerName}><App /></${providerName}>\\` where { $program <: not contains \\`<${providerName}>$_</${providerName}>\\` }`,\n );\n\n // Update the dev target on the website to use our local server.\n // Callers that handle the dev target separately (e.g. agent connections) set skipLocalDev.\n if (!skipLocalDev) {\n await addTargetToLocalDev(\n tree,\n frontendProjectConfig.name,\n backendProjectConfig.name,\n {\n url: `http://localhost:${port}/`,\n apiName,\n // Additionally add a dependency on the generate watch command to ensure that local\n // API changes that affect the client are also reloaded.\n // We include a dependency on the generate target as watch ONLY triggers on a change,\n // and we need to ensure the client is generated the first time if not already present.\n additionalDependencyTargets: [clientGenTarget, clientGenWatchTarget],\n },\n );\n }\n\n addDependenciesToPackageJson(\n tree,\n withVersions([\n ...((auth === 'iam'\n ? [\n 'oidc-client-ts',\n 'react-oidc-context',\n '@aws-sdk/credential-provider-cognito-identity',\n 'aws4fetch',\n ]\n : []) as any),\n ...((auth === 'cognito' ? ['react-oidc-context'] : []) as any),\n '@tanstack/react-query',\n '@tanstack/react-query-devtools',\n ]),\n withVersions(['@smithy/types']),\n joinPathFragments(frontendProjectConfig.root, 'package.json'),\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addTargetToLocalDev","runtimeConfigGenerator","addSingleImport","applyGritQL","addDependenciesToPackageJson","updateGitIgnore","kebabCase","toClassName","sortObjectKeys","withVersions","addOpenApiReactClient","tree","apiName","frontendProjectConfig","backendProjectConfig","specBuildProject","specPath","specBuildTargetName","auth","port","isAgentRuntime","skipLocalDev","clientGenTarget","clientGenWatchTarget","generatedClientDir","generatedClientDirFromRoot","sourceRoot","name","targets","Object","fromEntries","map","target","dependsOn","filter","t","cache","executor","inputs","dependentTasksOutputFiles","outputs","options","commands","continuous","relativeSrcDir","slice","root","length","patterns","project","dirname","overwriteStrategy","KeepExisting","apiNameClassName","mainTsxPath","providerName","url","additionalDependencyTargets"],"mappings":"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"}
@@ -33,7 +33,7 @@ const isOnPath = (binary)=>{
33
33
  * to docker when nothing has been configured.
34
34
  */ export const resolveContainers = async (tree, option)=>{
35
35
  if (option === 'inherit') {
36
- const pluginConfig = await readAwsNxPluginConfig(tree);
36
+ const pluginConfig = readAwsNxPluginConfig(tree);
37
37
  const engine = pluginConfig?.containers?.engine ?? 'docker';
38
38
  if (!CONTAINER_ENGINES.includes(engine)) {
39
39
  throw new Error(`containers.engine in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME} must be one of ${CONTAINER_ENGINES.join(', ')}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/containers.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { Tree } from '@nx/devkit';\nimport { execSync } from 'child_process';\nimport {\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n readAwsNxPluginConfig,\n} from './config/utils';\n\nexport const CONTAINER_ENGINES = ['docker', 'finch'] as const;\n\nexport type Containers = (typeof CONTAINER_ENGINES)[number];\n\nexport type ContainersOption = Containers | 'inherit';\n\n/**\n * Configuration for container tooling\n */\nexport interface ContainersConfig {\n /**\n * Container engine used for build/push/login operations\n */\n engine: Containers;\n}\n\nconst isOnPath = (binary: string): boolean => {\n try {\n const which = process.platform === 'win32' ? 'where' : 'command -v';\n execSync(`${which} ${binary}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Detect which container engine is available on the host. Prefers docker;\n * falls back to finch when only finch is installed; defaults to docker\n * when neither is found.\n */\nexport const inferContainers = (): Containers => {\n if (isOnPath('docker')) return 'docker';\n if (isOnPath('finch')) return 'finch';\n return 'docker';\n};\n\n/**\n * Given a container engine option, resolve the actual engine to use.\n * `Inherit` reads the value from the workspace plugin config, defaulting\n * to docker when nothing has been configured.\n */\nexport const resolveContainers = async (\n tree: Tree,\n option: ContainersOption,\n): Promise<Containers> => {\n if (option === 'inherit') {\n const pluginConfig = await readAwsNxPluginConfig(tree);\n const engine = pluginConfig?.containers?.engine ?? 'docker';\n if (!CONTAINER_ENGINES.includes(engine)) {\n throw new Error(\n `containers.engine in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME} must be one of ${CONTAINER_ENGINES.join(\n ', ',\n )}`,\n );\n }\n return engine;\n }\n return option;\n};\n"],"names":["execSync","AWS_NX_PLUGIN_CONFIG_FILE_NAME","readAwsNxPluginConfig","CONTAINER_ENGINES","isOnPath","binary","which","process","platform","stdio","inferContainers","resolveContainers","tree","option","pluginConfig","engine","containers","includes","Error","join"],"mappings":"AAAA;;;CAGC,GAED,SAASA,QAAQ,QAAQ,gBAAgB;AACzC,SACEC,8BAA8B,EAC9BC,qBAAqB,QAChB,oBAAiB;AAExB,OAAO,MAAMC,oBAAoB;IAAC;IAAU;CAAQ,CAAU;AAgB9D,MAAMC,WAAW,CAACC;IAChB,IAAI;QACF,MAAMC,QAAQC,QAAQC,QAAQ,KAAK,UAAU,UAAU;QACvDR,SAAS,GAAGM,MAAM,CAAC,EAAED,QAAQ,EAAE;YAAEI,OAAO;QAAS;QACjD,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA;;;;CAIC,GACD,OAAO,MAAMC,kBAAkB;IAC7B,IAAIN,SAAS,WAAW,OAAO;IAC/B,IAAIA,SAAS,UAAU,OAAO;IAC9B,OAAO;AACT,EAAE;AAEF;;;;CAIC,GACD,OAAO,MAAMO,oBAAoB,OAC/BC,MACAC;IAEA,IAAIA,WAAW,WAAW;QACxB,MAAMC,eAAe,MAAMZ,sBAAsBU;QACjD,MAAMG,SAASD,cAAcE,YAAYD,UAAU;QACnD,IAAI,CAACZ,kBAAkBc,QAAQ,CAACF,SAAS;YACvC,MAAM,IAAIG,MACR,CAAC,qBAAqB,EAAEjB,+BAA+B,gBAAgB,EAAEE,kBAAkBgB,IAAI,CAC7F,OACC;QAEP;QACA,OAAOJ;IACT;IACA,OAAOF;AACT,EAAE"}
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/containers.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { Tree } from '@nx/devkit';\nimport { execSync } from 'child_process';\nimport {\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n readAwsNxPluginConfig,\n} from './config/utils';\n\nexport const CONTAINER_ENGINES = ['docker', 'finch'] as const;\n\nexport type Containers = (typeof CONTAINER_ENGINES)[number];\n\nexport type ContainersOption = Containers | 'inherit';\n\n/**\n * Configuration for container tooling\n */\nexport interface ContainersConfig {\n /**\n * Container engine used for build/push/login operations\n */\n engine: Containers;\n}\n\nconst isOnPath = (binary: string): boolean => {\n try {\n const which = process.platform === 'win32' ? 'where' : 'command -v';\n execSync(`${which} ${binary}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Detect which container engine is available on the host. Prefers docker;\n * falls back to finch when only finch is installed; defaults to docker\n * when neither is found.\n */\nexport const inferContainers = (): Containers => {\n if (isOnPath('docker')) return 'docker';\n if (isOnPath('finch')) return 'finch';\n return 'docker';\n};\n\n/**\n * Given a container engine option, resolve the actual engine to use.\n * `Inherit` reads the value from the workspace plugin config, defaulting\n * to docker when nothing has been configured.\n */\nexport const resolveContainers = async (\n tree: Tree,\n option: ContainersOption,\n): Promise<Containers> => {\n if (option === 'inherit') {\n const pluginConfig = readAwsNxPluginConfig(tree);\n const engine = pluginConfig?.containers?.engine ?? 'docker';\n if (!CONTAINER_ENGINES.includes(engine)) {\n throw new Error(\n `containers.engine in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME} must be one of ${CONTAINER_ENGINES.join(\n ', ',\n )}`,\n );\n }\n return engine;\n }\n return option;\n};\n"],"names":["execSync","AWS_NX_PLUGIN_CONFIG_FILE_NAME","readAwsNxPluginConfig","CONTAINER_ENGINES","isOnPath","binary","which","process","platform","stdio","inferContainers","resolveContainers","tree","option","pluginConfig","engine","containers","includes","Error","join"],"mappings":"AAAA;;;CAGC,GAED,SAASA,QAAQ,QAAQ,gBAAgB;AACzC,SACEC,8BAA8B,EAC9BC,qBAAqB,QAChB,oBAAiB;AAExB,OAAO,MAAMC,oBAAoB;IAAC;IAAU;CAAQ,CAAU;AAgB9D,MAAMC,WAAW,CAACC;IAChB,IAAI;QACF,MAAMC,QAAQC,QAAQC,QAAQ,KAAK,UAAU,UAAU;QACvDR,SAAS,GAAGM,MAAM,CAAC,EAAED,QAAQ,EAAE;YAAEI,OAAO;QAAS;QACjD,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA;;;;CAIC,GACD,OAAO,MAAMC,kBAAkB;IAC7B,IAAIN,SAAS,WAAW,OAAO;IAC/B,IAAIA,SAAS,UAAU,OAAO;IAC9B,OAAO;AACT,EAAE;AAEF;;;;CAIC,GACD,OAAO,MAAMO,oBAAoB,OAC/BC,MACAC;IAEA,IAAIA,WAAW,WAAW;QACxB,MAAMC,eAAeZ,sBAAsBU;QAC3C,MAAMG,SAASD,cAAcE,YAAYD,UAAU;QACnD,IAAI,CAACZ,kBAAkBc,QAAQ,CAACF,SAAS;YACvC,MAAM,IAAIG,MACR,CAAC,qBAAqB,EAAEjB,+BAA+B,gBAAgB,EAAEE,kBAAkBgB,IAAI,CAC7F,OACC;QAEP;QACA,OAAOJ;IACT;IACA,OAAOF;AACT,EAAE"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { type GeneratorCallback, type PackageManager, type Tree } from '@nx/devkit';
6
+ export declare const detectWorkspacePackageManager: (tree: Tree) => PackageManager;
7
+ /** Clears the catalog support cache. Only needed by tests. */
8
+ export declare const resetCatalogSupportCache: () => void;
9
+ export declare const getLocalDependencySpecifier: (tree: Tree) => string;
10
+ export declare const supportsCatalogs: (tree: Tree) => boolean;
11
+ export declare const catalogsEnabled: (tree: Tree) => boolean;
12
+ /**
13
+ * Drop-in replacement for devkit's `addDependenciesToPackageJson` that records
14
+ * versions in the package manager's catalog when enabled. Callers pass a
15
+ * project manifest path for runtime deps (so `noUndeclaredDependencies` passes)
16
+ * and the root for shared tooling.
17
+ */
18
+ export declare const addDependenciesToPackageJson: (tree: Tree, dependencies: Record<string, string>, devDependencies: Record<string, string>, packageJsonPath?: string) => GeneratorCallback;
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { detectPackageManager, addDependenciesToPackageJson as devkitAddDependenciesToPackageJson, getPackageManagerVersion, readJson, updateJson } from "@nx/devkit";
5
+ import yaml from "js-yaml";
6
+ import { coerce, gt, gte } from "semver";
7
+ import { readAwsNxPluginConfig } from "./config/utils.js";
8
+ // Minimum version that introduced catalog support per package manager (npm has none).
9
+ const CATALOG_SUPPORT = {
10
+ pnpm: '9.5.0',
11
+ yarn: '4.10.0',
12
+ bun: '1.2.14'
13
+ };
14
+ // Prefer tree markers over devkit's `detectPackageManager`, which reads the
15
+ // real filesystem and is nondeterministic for virtual trees in tests.
16
+ export const detectWorkspacePackageManager = (tree)=>tree.exists('pnpm-workspace.yaml') ? 'pnpm' : detectPackageManager(tree.root);
17
+ // Coerce a single simple range to a version. Rejects compound ranges
18
+ // (whitespace / `||`), which coerce would silently reduce, plus tags/protocols.
19
+ const parseSimpleRange = (version)=>{
20
+ const trimmed = version.trim();
21
+ if (/\s|\|\|/.test(trimmed)) {
22
+ return undefined;
23
+ }
24
+ return coerce(trimmed, {
25
+ includePrerelease: true
26
+ }) ?? undefined;
27
+ };
28
+ const versionAtLeast = (version, minimum)=>gte(parseSimpleRange(version) ?? '0.0.0', parseSimpleRange(minimum) ?? '0.0.0');
29
+ // Only a strict upgrade replaces an existing catalog entry, so generating a
30
+ // project never downgrades a version the user raised. Uncomparable entries
31
+ // (tags, complex ranges) are kept.
32
+ const isVersionUpgrade = (incoming, existing)=>{
33
+ const existingParsed = parseSimpleRange(existing);
34
+ const incomingParsed = parseSimpleRange(incoming);
35
+ if (!existingParsed || !incomingParsed) {
36
+ return false;
37
+ }
38
+ return gt(incomingParsed, existingParsed);
39
+ };
40
+ // Keyed by root + package manager; detecting support shells out for a version.
41
+ const catalogSupportCache = new Map();
42
+ /** Clears the catalog support cache. Only needed by tests. */ export const resetCatalogSupportCache = ()=>{
43
+ catalogSupportCache.clear();
44
+ };
45
+ // Local-project specifier: the `workspace:` protocol where supported (pnpm,
46
+ // bun, yarn berry), `*` on npm and yarn classic which reject it.
47
+ export const getLocalDependencySpecifier = (tree)=>{
48
+ const packageManager = detectWorkspacePackageManager(tree);
49
+ if (packageManager === 'npm') {
50
+ return '*';
51
+ }
52
+ if (packageManager === 'yarn') {
53
+ let major = 2;
54
+ try {
55
+ major = Number.parseInt(getPackageManagerVersion('yarn', tree.root).split('.')[0], 10);
56
+ } catch {
57
+ // Not installed (e.g. tests) — assume berry.
58
+ }
59
+ if (major < 2) {
60
+ return '*';
61
+ }
62
+ }
63
+ return 'workspace:*';
64
+ };
65
+ export const supportsCatalogs = (tree)=>{
66
+ const packageManager = detectWorkspacePackageManager(tree);
67
+ const cacheKey = `${tree.root}|${packageManager}`;
68
+ const cached = catalogSupportCache.get(cacheKey);
69
+ if (cached !== undefined) {
70
+ return cached;
71
+ }
72
+ const minimumVersion = CATALOG_SUPPORT[packageManager];
73
+ let supported = false;
74
+ if (minimumVersion) {
75
+ try {
76
+ supported = versionAtLeast(getPackageManagerVersion(packageManager, tree.root), minimumVersion);
77
+ } catch {
78
+ // Not installed (e.g. tests) — assume a modern version.
79
+ supported = true;
80
+ }
81
+ }
82
+ catalogSupportCache.set(cacheKey, supported);
83
+ return supported;
84
+ };
85
+ // True when the package manager supports catalogs and the workspace hasn't
86
+ // opted out via `packageManager.catalogs: false` in aws-nx-plugin.config.mts.
87
+ export const catalogsEnabled = (tree)=>{
88
+ if (!supportsCatalogs(tree)) {
89
+ return false;
90
+ }
91
+ const config = readAwsNxPluginConfig(tree);
92
+ return config?.packageManager?.catalogs !== false;
93
+ };
94
+ /**
95
+ * Drop-in replacement for devkit's `addDependenciesToPackageJson` that records
96
+ * versions in the package manager's catalog when enabled. Callers pass a
97
+ * project manifest path for runtime deps (so `noUndeclaredDependencies` passes)
98
+ * and the root for shared tooling.
99
+ */ export const addDependenciesToPackageJson = (tree, dependencies, devDependencies, packageJsonPath = 'package.json')=>{
100
+ const callback = devkitAddDependenciesToPackageJson(tree, dependencies, devDependencies, packageJsonPath);
101
+ if (catalogsEnabled(tree)) {
102
+ const packageNames = [
103
+ ...Object.keys(dependencies),
104
+ ...Object.keys(devDependencies)
105
+ ];
106
+ convertDependenciesToCatalog(tree, packageJsonPath, packageNames);
107
+ // Convert any matching root ranges Nx wrote behind our back (e.g.
108
+ // `@types/node`, `react`) so they don't resolve to a second copy alongside
109
+ // the catalog version. Skipped when the caller already targeted the root.
110
+ if (packageJsonPath !== 'package.json') {
111
+ convertDependenciesToCatalog(tree, 'package.json', packageNames);
112
+ }
113
+ }
114
+ return callback;
115
+ };
116
+ // Nx generators read these versions from the root manifest and coerce without
117
+ // a null guard; Nx ships no bun catalog manager, so an unresolved `catalog:`
118
+ // crashes them. Keep direct ranges on bun (react-dom pinned with react).
119
+ const BUN_INTROSPECTED_PACKAGES = new Set([
120
+ 'vite',
121
+ 'react',
122
+ 'react-dom'
123
+ ]);
124
+ const isCatalogExcluded = (tree, packageName)=>detectWorkspacePackageManager(tree) === 'bun' && BUN_INTROSPECTED_PACKAGES.has(packageName);
125
+ // Convert direct version ranges to `catalog:` references in a single manifest
126
+ // and record the range in the workspace catalog. Protocol specifiers
127
+ // (catalog:/workspace:/...) are left alone.
128
+ const convertDependenciesToCatalog = (tree, packageJsonPath, packageNames)=>{
129
+ const catalogUpdates = {};
130
+ updateJson(tree, packageJsonPath, (json)=>{
131
+ for (const field of [
132
+ 'dependencies',
133
+ 'devDependencies'
134
+ ]){
135
+ for (const packageName of packageNames){
136
+ const version = json[field]?.[packageName];
137
+ if (version && !version.includes(':') && !isCatalogExcluded(tree, packageName)) {
138
+ catalogUpdates[packageName] = version;
139
+ json[field][packageName] = 'catalog:';
140
+ }
141
+ }
142
+ }
143
+ return json;
144
+ });
145
+ if (Object.keys(catalogUpdates).length > 0) {
146
+ writeCatalogVersions(tree, catalogUpdates);
147
+ }
148
+ };
149
+ // Record ranges in the default catalog, creating it if absent. Only strict
150
+ // upgrades replace existing entries (see `isVersionUpgrade`).
151
+ const writeCatalogVersions = (tree, updates)=>{
152
+ const applyUpdates = (catalog)=>{
153
+ const existing = catalog ?? {};
154
+ const applicable = Object.fromEntries(Object.entries(updates).filter(([name, version])=>existing[name] === undefined || isVersionUpgrade(version, existing[name])));
155
+ if (Object.keys(applicable).length === 0) {
156
+ return undefined;
157
+ }
158
+ return {
159
+ ...existing,
160
+ ...applicable
161
+ };
162
+ };
163
+ switch(detectWorkspacePackageManager(tree)){
164
+ case 'pnpm':
165
+ {
166
+ const workspaceYaml = yaml.load(tree.read('pnpm-workspace.yaml', 'utf-8') ?? '') ?? {};
167
+ const catalog = applyUpdates(workspaceYaml.catalog);
168
+ if (catalog) {
169
+ tree.write('pnpm-workspace.yaml', yaml.dump({
170
+ ...workspaceYaml,
171
+ catalog
172
+ }, {
173
+ quotingType: "'"
174
+ }));
175
+ }
176
+ break;
177
+ }
178
+ case 'yarn':
179
+ {
180
+ const yarnRc = yaml.load(tree.read('.yarnrc.yml', 'utf-8') ?? '') ?? {};
181
+ const catalog = applyUpdates(yarnRc.catalog);
182
+ if (catalog) {
183
+ tree.write('.yarnrc.yml', yaml.dump({
184
+ ...yarnRc,
185
+ catalog
186
+ }, {
187
+ quotingType: "'"
188
+ }));
189
+ }
190
+ break;
191
+ }
192
+ case 'bun':
193
+ {
194
+ const catalog = applyUpdates(readJson(tree, 'package.json').catalog);
195
+ if (catalog) {
196
+ updateJson(tree, 'package.json', (json)=>({
197
+ ...json,
198
+ catalog
199
+ }));
200
+ }
201
+ break;
202
+ }
203
+ }
204
+ };
205
+
206
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/dependencies.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n detectPackageManager,\n addDependenciesToPackageJson as devkitAddDependenciesToPackageJson,\n type GeneratorCallback,\n getPackageManagerVersion,\n type PackageManager,\n readJson,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport yaml from 'js-yaml';\nimport { coerce, gt, gte } from 'semver';\nimport { readAwsNxPluginConfig } from './config/utils';\n\n// Minimum version that introduced catalog support per package manager (npm has none).\nconst CATALOG_SUPPORT: Partial<Record<PackageManager, string>> = {\n pnpm: '9.5.0',\n yarn: '4.10.0',\n bun: '1.2.14',\n};\n\n// Prefer tree markers over devkit's `detectPackageManager`, which reads the\n// real filesystem and is nondeterministic for virtual trees in tests.\nexport const detectWorkspacePackageManager = (tree: Tree): PackageManager =>\n tree.exists('pnpm-workspace.yaml') ? 'pnpm' : detectPackageManager(tree.root);\n\n// Coerce a single simple range to a version. Rejects compound ranges\n// (whitespace / `||`), which coerce would silently reduce, plus tags/protocols.\nconst parseSimpleRange = (version: string) => {\n const trimmed = version.trim();\n if (/\\s|\\|\\|/.test(trimmed)) {\n return undefined;\n }\n return coerce(trimmed, { includePrerelease: true }) ?? undefined;\n};\n\nconst versionAtLeast = (version: string, minimum: string): boolean =>\n gte(\n parseSimpleRange(version) ?? '0.0.0',\n parseSimpleRange(minimum) ?? '0.0.0',\n );\n\n// Only a strict upgrade replaces an existing catalog entry, so generating a\n// project never downgrades a version the user raised. Uncomparable entries\n// (tags, complex ranges) are kept.\nconst isVersionUpgrade = (incoming: string, existing: string): boolean => {\n const existingParsed = parseSimpleRange(existing);\n const incomingParsed = parseSimpleRange(incoming);\n if (!existingParsed || !incomingParsed) {\n return false;\n }\n return gt(incomingParsed, existingParsed);\n};\n\n// Keyed by root + package manager; detecting support shells out for a version.\nconst catalogSupportCache = new Map<string, boolean>();\n\n/** Clears the catalog support cache. Only needed by tests. */\nexport const resetCatalogSupportCache = (): void => {\n catalogSupportCache.clear();\n};\n\n// Local-project specifier: the `workspace:` protocol where supported (pnpm,\n// bun, yarn berry), `*` on npm and yarn classic which reject it.\nexport const getLocalDependencySpecifier = (tree: Tree): string => {\n const packageManager = detectWorkspacePackageManager(tree);\n if (packageManager === 'npm') {\n return '*';\n }\n if (packageManager === 'yarn') {\n let major = 2;\n try {\n major = Number.parseInt(\n getPackageManagerVersion('yarn', tree.root).split('.')[0],\n 10,\n );\n } catch {\n // Not installed (e.g. tests) — assume berry.\n }\n if (major < 2) {\n return '*';\n }\n }\n return 'workspace:*';\n};\n\nexport const supportsCatalogs = (tree: Tree): boolean => {\n const packageManager = detectWorkspacePackageManager(tree);\n const cacheKey = `${tree.root}|${packageManager}`;\n const cached = catalogSupportCache.get(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n const minimumVersion = CATALOG_SUPPORT[packageManager];\n let supported = false;\n if (minimumVersion) {\n try {\n supported = versionAtLeast(\n getPackageManagerVersion(packageManager, tree.root),\n minimumVersion,\n );\n } catch {\n // Not installed (e.g. tests) — assume a modern version.\n supported = true;\n }\n }\n catalogSupportCache.set(cacheKey, supported);\n return supported;\n};\n\n// True when the package manager supports catalogs and the workspace hasn't\n// opted out via `packageManager.catalogs: false` in aws-nx-plugin.config.mts.\nexport const catalogsEnabled = (tree: Tree): boolean => {\n if (!supportsCatalogs(tree)) {\n return false;\n }\n const config = readAwsNxPluginConfig(tree);\n return config?.packageManager?.catalogs !== false;\n};\n\n/**\n * Drop-in replacement for devkit's `addDependenciesToPackageJson` that records\n * versions in the package manager's catalog when enabled. Callers pass a\n * project manifest path for runtime deps (so `noUndeclaredDependencies` passes)\n * and the root for shared tooling.\n */\nexport const addDependenciesToPackageJson = (\n tree: Tree,\n dependencies: Record<string, string>,\n devDependencies: Record<string, string>,\n packageJsonPath = 'package.json',\n): GeneratorCallback => {\n const callback = devkitAddDependenciesToPackageJson(\n tree,\n dependencies,\n devDependencies,\n packageJsonPath,\n );\n\n if (catalogsEnabled(tree)) {\n const packageNames = [\n ...Object.keys(dependencies),\n ...Object.keys(devDependencies),\n ];\n convertDependenciesToCatalog(tree, packageJsonPath, packageNames);\n // Convert any matching root ranges Nx wrote behind our back (e.g.\n // `@types/node`, `react`) so they don't resolve to a second copy alongside\n // the catalog version. Skipped when the caller already targeted the root.\n if (packageJsonPath !== 'package.json') {\n convertDependenciesToCatalog(tree, 'package.json', packageNames);\n }\n }\n\n return callback;\n};\n\n// Nx generators read these versions from the root manifest and coerce without\n// a null guard; Nx ships no bun catalog manager, so an unresolved `catalog:`\n// crashes them. Keep direct ranges on bun (react-dom pinned with react).\nconst BUN_INTROSPECTED_PACKAGES = new Set<string>([\n 'vite',\n 'react',\n 'react-dom',\n]);\n\nconst isCatalogExcluded = (tree: Tree, packageName: string): boolean =>\n detectWorkspacePackageManager(tree) === 'bun' &&\n BUN_INTROSPECTED_PACKAGES.has(packageName);\n\n// Convert direct version ranges to `catalog:` references in a single manifest\n// and record the range in the workspace catalog. Protocol specifiers\n// (catalog:/workspace:/...) are left alone.\nconst convertDependenciesToCatalog = (\n tree: Tree,\n packageJsonPath: string,\n packageNames: string[],\n): void => {\n const catalogUpdates: Record<string, string> = {};\n\n updateJson(tree, packageJsonPath, (json) => {\n for (const field of ['dependencies', 'devDependencies'] as const) {\n for (const packageName of packageNames) {\n const version = json[field]?.[packageName];\n if (\n version &&\n !version.includes(':') &&\n !isCatalogExcluded(tree, packageName)\n ) {\n catalogUpdates[packageName] = version;\n json[field][packageName] = 'catalog:';\n }\n }\n }\n return json;\n });\n\n if (Object.keys(catalogUpdates).length > 0) {\n writeCatalogVersions(tree, catalogUpdates);\n }\n};\n\n// Record ranges in the default catalog, creating it if absent. Only strict\n// upgrades replace existing entries (see `isVersionUpgrade`).\nconst writeCatalogVersions = (\n tree: Tree,\n updates: Record<string, string>,\n): void => {\n const applyUpdates = (\n catalog: Record<string, string> | undefined,\n ): Record<string, string> | undefined => {\n const existing = catalog ?? {};\n const applicable = Object.fromEntries(\n Object.entries(updates).filter(\n ([name, version]) =>\n existing[name] === undefined ||\n isVersionUpgrade(version, existing[name]),\n ),\n );\n if (Object.keys(applicable).length === 0) {\n return undefined;\n }\n return { ...existing, ...applicable };\n };\n\n switch (detectWorkspacePackageManager(tree)) {\n case 'pnpm': {\n const workspaceYaml =\n (yaml.load(tree.read('pnpm-workspace.yaml', 'utf-8') ?? '') as Record<\n string,\n unknown\n >) ?? {};\n const catalog = applyUpdates(\n workspaceYaml.catalog as Record<string, string> | undefined,\n );\n if (catalog) {\n tree.write(\n 'pnpm-workspace.yaml',\n yaml.dump({ ...workspaceYaml, catalog }, { quotingType: \"'\" }),\n );\n }\n break;\n }\n case 'yarn': {\n const yarnRc =\n (yaml.load(tree.read('.yarnrc.yml', 'utf-8') ?? '') as Record<\n string,\n unknown\n >) ?? {};\n const catalog = applyUpdates(\n yarnRc.catalog as Record<string, string> | undefined,\n );\n if (catalog) {\n tree.write(\n '.yarnrc.yml',\n yaml.dump({ ...yarnRc, catalog }, { quotingType: \"'\" }),\n );\n }\n break;\n }\n case 'bun': {\n const catalog = applyUpdates(\n readJson<{ catalog?: Record<string, string> }>(tree, 'package.json')\n .catalog,\n );\n if (catalog) {\n updateJson(tree, 'package.json', (json) => ({ ...json, catalog }));\n }\n break;\n }\n }\n};\n"],"names":["detectPackageManager","addDependenciesToPackageJson","devkitAddDependenciesToPackageJson","getPackageManagerVersion","readJson","updateJson","yaml","coerce","gt","gte","readAwsNxPluginConfig","CATALOG_SUPPORT","pnpm","yarn","bun","detectWorkspacePackageManager","tree","exists","root","parseSimpleRange","version","trimmed","trim","test","undefined","includePrerelease","versionAtLeast","minimum","isVersionUpgrade","incoming","existing","existingParsed","incomingParsed","catalogSupportCache","Map","resetCatalogSupportCache","clear","getLocalDependencySpecifier","packageManager","major","Number","parseInt","split","supportsCatalogs","cacheKey","cached","get","minimumVersion","supported","set","catalogsEnabled","config","catalogs","dependencies","devDependencies","packageJsonPath","callback","packageNames","Object","keys","convertDependenciesToCatalog","BUN_INTROSPECTED_PACKAGES","Set","isCatalogExcluded","packageName","has","catalogUpdates","json","field","includes","length","writeCatalogVersions","updates","applyUpdates","catalog","applicable","fromEntries","entries","filter","name","workspaceYaml","load","read","write","dump","quotingType","yarnRc"],"mappings":"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"}
@@ -3,6 +3,14 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { type ProjectConfiguration, type Tree } from '@nx/devkit';
6
+ /**
7
+ * Substitution variables for the vended Node `Dockerfile` templates: the npm
8
+ * version to install globally, and the versions its dependency overrides pin.
9
+ */
10
+ export declare const nodeImageVersions: () => {
11
+ npmVersion: "12.0.1";
12
+ minimatchVersion: "10.2.5";
13
+ };
6
14
  export interface DockerScanTargetOptions {
7
15
  /**
8
16
  * Project configuration to add the scan target to (mutated in place).
@@ -4,12 +4,19 @@
4
4
  */ import { joinPathFragments } from "@nx/devkit";
5
5
  import { FsCommands } from "./fs.js";
6
6
  import { addDependencyToTargetIfNotPresent } from "./nx.js";
7
- import { CONTAINER_VERSIONS } from "./versions.js";
7
+ import { CONTAINER_VERSIONS, TS_VERSIONS } from "./versions.js";
8
8
  const TRIVY_IGNORE_FILE = '.trivyignore';
9
9
  const TRIVY_IGNORE_CONTENTS = `# Trivy ignore file. Add one vulnerability ID (e.g. CVE-2021-12345) per line to
10
10
  # suppress it during the image scan (\`nx run-many --target trivy\`).
11
11
  # https://trivy.dev/latest/docs/configuration/filtering/#by-finding-ids
12
12
  `;
13
+ /**
14
+ * Substitution variables for the vended Node `Dockerfile` templates: the npm
15
+ * version to install globally, and the versions its dependency overrides pin.
16
+ */ export const nodeImageVersions = ()=>({
17
+ npmVersion: TS_VERSIONS.npm,
18
+ minimatchVersion: TS_VERSIONS.minimatch
19
+ });
13
20
  /**
14
21
  * Add a cacheable Trivy scan target for the images built by a docker target
15
22
  * and wire it under the aggregate \`trivy\` target. The scan is not part of