@aws/nx-plugin 1.0.0-rc.94 → 1.0.0-rc.96

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 (86) hide show
  1. package/LICENSE-THIRD-PARTY +234 -38
  2. package/migrations.json +54 -1
  3. package/package.json +6 -6
  4. package/src/infra/app/__snapshots__/generator.spec.ts.snap +4 -10
  5. package/src/migrations/latest/agent-connection-pin-strands-peers/metadata.json +3 -0
  6. package/src/migrations/latest/agent-connection-pin-strands-peers/migration.d.ts +18 -0
  7. package/src/migrations/latest/agent-connection-pin-strands-peers/migration.js +38 -0
  8. package/src/migrations/latest/agent-connection-pin-strands-peers/migration.js.map +1 -0
  9. package/src/migrations/latest/ignore-package-manager-temp-files/metadata.json +3 -0
  10. package/src/migrations/latest/ignore-package-manager-temp-files/migration.d.ts +12 -0
  11. package/src/migrations/latest/ignore-package-manager-temp-files/migration.js +25 -0
  12. package/src/migrations/latest/ignore-package-manager-temp-files/migration.js.map +1 -0
  13. package/src/migrations/latest/rolldown-config-bundle-transient/metadata.json +3 -0
  14. package/src/migrations/latest/rolldown-config-bundle-transient/migration.d.ts +6 -0
  15. package/src/migrations/latest/rolldown-config-bundle-transient/migration.js +80 -0
  16. package/src/migrations/latest/rolldown-config-bundle-transient/migration.js.map +1 -0
  17. package/src/migrations/latest/shadcn-package-imports-exports/metadata.json +3 -0
  18. package/src/migrations/latest/shadcn-package-imports-exports/migration.d.ts +6 -0
  19. package/src/migrations/latest/shadcn-package-imports-exports/migration.js +184 -0
  20. package/src/migrations/latest/shadcn-package-imports-exports/migration.js.map +1 -0
  21. package/src/preset/__snapshots__/generator.spec.ts.snap +8 -6
  22. package/src/py/agent/a2a-connection/generator.d.ts +1 -1
  23. package/src/py/agent/gateway-connection/generator.d.ts +1 -1
  24. package/src/py/agent/mcp-connection/generator.d.ts +1 -1
  25. package/src/py/agent/react-connection/generator.d.ts +29 -0
  26. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +4 -1
  27. package/src/ts/agent/a2a-connection/generator.d.ts +4 -0
  28. package/src/ts/agent/gateway-connection/generator.d.ts +4 -0
  29. package/src/ts/agent/generator.d.ts +4 -0
  30. package/src/ts/agent/mcp-connection/generator.d.ts +4 -0
  31. package/src/ts/agent/react-connection/generator.d.ts +37 -0
  32. package/src/ts/lib/generator.d.ts +13 -0
  33. package/src/ts/lib/generator.js +3 -2
  34. package/src/ts/lib/generator.js.map +1 -1
  35. package/src/ts/lib/ts-project-utils.d.ts +17 -1
  36. package/src/ts/lib/ts-project-utils.js +29 -0
  37. package/src/ts/lib/ts-project-utils.js.map +1 -1
  38. package/src/ts/lib/vitest.d.ts +6 -0
  39. package/src/ts/lib/vitest.js +16 -1
  40. package/src/ts/lib/vitest.js.map +1 -1
  41. package/src/ts/react-website/agui/generator.d.ts +21 -0
  42. package/src/ts/react-website/agui/generator.js +2 -1
  43. package/src/ts/react-website/agui/generator.js.map +1 -1
  44. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +28 -22
  45. package/src/ts/react-website/app/generator.d.ts +42 -0
  46. package/src/ts/react-website/app/generator.js +4 -2
  47. package/src/ts/react-website/app/generator.js.map +1 -1
  48. package/src/utils/agent-connection/agent-connection.d.ts +2 -0
  49. package/src/utils/agent-connection/agent-connection.js +11 -4
  50. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  51. package/src/utils/bundle/bundle.js +10 -0
  52. package/src/utils/bundle/bundle.js.map +1 -1
  53. package/src/utils/dependencies.js +1 -10
  54. package/src/utils/dependencies.js.map +1 -1
  55. package/src/utils/files/common/shadcn/src/components/ui/alert.tsx.template +1 -1
  56. package/src/utils/files/common/shadcn/src/components/ui/avatar.tsx.template +1 -1
  57. package/src/utils/files/common/shadcn/src/components/ui/breadcrumb.tsx.template +1 -1
  58. package/src/utils/files/common/shadcn/src/components/ui/button.tsx.template +1 -1
  59. package/src/utils/files/common/shadcn/src/components/ui/card.tsx.template +1 -1
  60. package/src/utils/files/common/shadcn/src/components/ui/input.tsx.template +1 -1
  61. package/src/utils/files/common/shadcn/src/components/ui/separator.tsx.template +1 -1
  62. package/src/utils/files/common/shadcn/src/components/ui/sheet.tsx.template +1 -1
  63. package/src/utils/files/common/shadcn/src/components/ui/sidebar.tsx.template +8 -8
  64. package/src/utils/files/common/shadcn/src/components/ui/skeleton.tsx.template +1 -1
  65. package/src/utils/files/common/shadcn/src/components/ui/spinner.tsx.template +1 -1
  66. package/src/utils/files/common/shadcn/src/components/ui/textarea.tsx.template +1 -1
  67. package/src/utils/files/common/shadcn/src/components/ui/tooltip.tsx.template +1 -1
  68. package/src/utils/files/shadcn/components.json.template +5 -5
  69. package/src/utils/format.d.ts +16 -0
  70. package/src/utils/format.js +15 -0
  71. package/src/utils/format.js.map +1 -1
  72. package/src/utils/init.js +11 -4
  73. package/src/utils/init.js.map +1 -1
  74. package/src/utils/pnpm-workspace.d.ts +5 -5
  75. package/src/utils/pnpm-workspace.js +5 -5
  76. package/src/utils/pnpm-workspace.js.map +1 -1
  77. package/src/utils/shared-shadcn.d.ts +22 -0
  78. package/src/utils/shared-shadcn.js +39 -28
  79. package/src/utils/shared-shadcn.js.map +1 -1
  80. package/src/utils/test.js +15 -0
  81. package/src/utils/test.js.map +1 -1
  82. package/src/utils/version-upgrade-migration/sync-vended-versions.js +4 -4
  83. package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
  84. package/src/utils/versions.d.ts +10 -9
  85. package/src/utils/versions.js +10 -8
  86. package/src/utils/versions.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/bundle/bundle.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type TargetConfiguration,\n type Tree,\n} from '@nx/devkit';\nimport { applyGritQL } from '../ast.js';\nimport {\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from '../declared-dependencies.js';\nimport { addDependenciesToPackageJson } from '../dependencies.js';\nimport {\n addArtifactDependencyToTargets,\n addDependencyToTargetIfNotPresent,\n normalizeTargetKeyOrder,\n} from '../nx.js';\nimport { getRelativePathToRoot } from '../paths.js';\nimport {\n type ITsDepVersion,\n LAMBDA_RUNTIME_VERSIONS,\n withVersions,\n} from '../versions.js';\n\n/** Dependencies a caller must declare to add a TypeScript bundle target. */\nexport const BUNDLE_DEPENDENCIES = [\n { name: 'rolldown' },\n] as const satisfies readonly { name: ITsDepVersion }[];\n\nexport interface AddPythonBundleTargetOptions {\n /**\n * Python platform\n * @default x86_64-manylinux_2_28\n */\n pythonPlatform?: 'x86_64-manylinux_2_28' | 'aarch64-manylinux_2_28';\n}\n\ninterface CreatePythonBundleTargetOptions\n extends Required<AddPythonBundleTargetOptions> {\n /**\n * Python package name\n */\n packageName: string;\n\n /**\n * Name of the bundle target, used for the outdir for the bundle\n */\n bundleTargetName: string;\n}\n\n/**\n * Create a target for bundling a python project\n */\nconst createPythonBundleTarget = ({\n packageName,\n pythonPlatform,\n bundleTargetName,\n}: CreatePythonBundleTargetOptions): TargetConfiguration => {\n return {\n cache: true,\n // The bundle holds exported dependencies and the entrypoint script, never\n // test files, so tests are excluded via `production`.\n inputs: ['production', '^production'],\n executor: 'nx:run-commands',\n outputs: [`{workspaceRoot}/dist/{projectRoot}/${bundleTargetName}`],\n options: {\n commands: [\n `uv export --frozen --no-dev --no-editable --project {projectRoot} --package ${packageName} -o dist/{projectRoot}/${bundleTargetName}/requirements.txt`,\n // `--python-version` pins wheel resolution to the Lambda Python runtime,\n // so the bundle cannot be built against whichever interpreter happens to\n // be on the build machine.\n `uv pip install -n --no-deps --no-installer-metadata --no-compile-bytecode --python-platform ${pythonPlatform} --python-version ${LAMBDA_RUNTIME_VERSIONS.python} --target dist/{projectRoot}/${bundleTargetName} -r dist/{projectRoot}/${bundleTargetName}/requirements.txt`,\n ],\n parallel: false,\n },\n };\n};\n\n/**\n * Adds a bundle target to the given project if it does not exist, and updates the build target to depend on it\n */\nexport const addPythonBundleTarget = (\n project: ProjectConfiguration,\n opts?: AddPythonBundleTargetOptions,\n) => {\n if (!project.targets) {\n project.targets = {};\n }\n\n const pythonPlatform = opts?.pythonPlatform ?? 'x86_64-manylinux_2_28';\n const bundleTargetName =\n pythonPlatform === 'aarch64-manylinux_2_28' ? 'bundle-arm' : 'bundle-x86';\n\n if (!project.targets?.[bundleTargetName]) {\n project.targets[bundleTargetName] = normalizeTargetKeyOrder({\n ...createPythonBundleTarget({\n packageName: project.name,\n pythonPlatform,\n bundleTargetName,\n }),\n dependsOn: ['compile'],\n });\n }\n\n // Add a \"bundle\" target which depends on either bundle-arm or bundle-x86 (or both)\n addDependencyToTargetIfNotPresent(project, 'bundle', bundleTargetName);\n addArtifactDependencyToTargets(project, 'bundle');\n\n return {\n bundleTargetName,\n bundleOutputDir: joinPathFragments('dist', project.root, bundleTargetName),\n };\n};\n\nexport interface AddTypeScriptBundleTargetOptions {\n /**\n * Path to the target file relative to the project dir\n */\n targetFilePath: string;\n\n /**\n * Sub directory to write bundled index.js file to (if any)\n * Outputs to dist/{projectRoot}/bundle/{bundleOutputDir}/index.js\n */\n bundleOutputDir?: string;\n\n /**\n * Modules to omit from the bundle and treat as external\n */\n external?: (string | RegExp)[];\n\n /**\n * Target platform for the bundle\n * @default 'node'\n */\n platform?: 'node' | 'browser' | 'neutral';\n}\n\n/**\n * Add a TypeScript bundle target using rolldown\n */\nexport const addTypeScriptBundleTarget = async <\n const D extends DependencyDeclaration,\n>(\n tree: Tree,\n project: ProjectConfiguration,\n opts: AddTypeScriptBundleTargetOptions,\n declaration: D & MustDeclare<typeof BUNDLE_DEPENDENCIES, D>,\n) => {\n project.targets ??= {};\n\n // Generate empty rolldown config if it doesn't exist\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'ts'),\n project.root,\n {},\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Add the bundle target\n if (!project.targets.bundle) {\n project.targets.bundle = normalizeTargetKeyOrder({\n cache: true,\n // Declared rather than left to Nx's implicit `[\"default\", \"^default\"]`,\n // which reads a dependency's whole project directory: rolldown resolves\n // dependencies through the build artifacts `default` already tracks, so\n // `^default` only adds files no bundle can contain.\n inputs: ['default'],\n outputs: [`{workspaceRoot}/dist/{projectRoot}/bundle`],\n executor: 'nx:run-commands',\n options: {\n command: 'rolldown -c rolldown.config.ts',\n cwd: '{projectRoot}',\n },\n dependsOn: ['compile'],\n });\n }\n\n // Add bundle to the build target\n addArtifactDependencyToTargets(project, 'bundle');\n\n const rolldownConfigPath = joinPathFragments(\n project.root,\n 'rolldown.config.ts',\n );\n\n const outputFile = joinPathFragments(\n getRelativePathToRoot(tree, project.name),\n 'dist',\n project.root,\n 'bundle',\n opts.bundleOutputDir ?? '.',\n 'index.js',\n );\n\n const external = opts.external?.length\n ? opts.external\n .map((ext) =>\n typeof ext === 'string' ? `'${ext}'` : `/${ext.source}/`,\n )\n .join(', ')\n : '';\n\n const entry = `{\n tsconfig: 'tsconfig.lib.json',\n input: '${opts.targetFilePath}',\n output: { file: '${outputFile}', format: 'cjs', codeSplitting: false },\n platform: '${opts.platform ?? 'node'}',\n ${external ? `external: [${external}],` : ''}\n }`;\n\n // Use GritQL to append the config entry to the defineConfig array.\n // First try the non-empty array case using the accumulate (+=) operator,\n // with an idempotency guard that checks the input path is not already present.\n const appended = await applyGritQL(\n tree,\n rolldownConfigPath,\n `\\`defineConfig([$items])\\` where { $items <: not contains \\`'${opts.targetFilePath}'\\`, $items += \", ${entry}\" }`,\n );\n\n if (!appended) {\n // Empty array — GritQL's += cannot accumulate into an empty list, so we\n // first insert a placeholder to make the array non-empty, then replace\n // the placeholder with the real entry via += (which handles regex\n // literals that are invalid inside GritQL backtick snippets).\n const inserted = await applyGritQL(\n tree,\n rolldownConfigPath,\n `\\`defineConfig([])\\` => \\`defineConfig([__PLACEHOLDER__])\\``,\n );\n if (inserted) {\n await applyGritQL(\n tree,\n rolldownConfigPath,\n `\\`defineConfig([$items])\\` where { $items <: \\`__PLACEHOLDER__\\` => ., $items += \"${entry}\" }`,\n );\n }\n }\n\n addDependenciesToPackageJson(\n tree,\n {},\n withVersions(forDependencies<typeof BUNDLE_DEPENDENCIES>(declaration), [\n 'rolldown',\n ]),\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","applyGritQL","forDependencies","addDependenciesToPackageJson","addArtifactDependencyToTargets","addDependencyToTargetIfNotPresent","normalizeTargetKeyOrder","getRelativePathToRoot","LAMBDA_RUNTIME_VERSIONS","withVersions","BUNDLE_DEPENDENCIES","name","createPythonBundleTarget","packageName","pythonPlatform","bundleTargetName","cache","inputs","executor","outputs","options","commands","python","parallel","addPythonBundleTarget","project","opts","targets","dependsOn","bundleOutputDir","root","addTypeScriptBundleTarget","tree","declaration","dirname","overwriteStrategy","KeepExisting","bundle","command","cwd","rolldownConfigPath","outputFile","external","length","map","ext","source","join","entry","targetFilePath","platform","appended","inserted"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/bundle/bundle.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type TargetConfiguration,\n type Tree,\n} from '@nx/devkit';\nimport { applyGritQL } from '../ast.js';\nimport {\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from '../declared-dependencies.js';\nimport { addDependenciesToPackageJson } from '../dependencies.js';\nimport { ROLLDOWN_CONFIG_BUNDLE_GLOB } from '../format.js';\nimport { updateGitIgnore } from '../git.js';\nimport {\n addArtifactDependencyToTargets,\n addDependencyToTargetIfNotPresent,\n normalizeTargetKeyOrder,\n} from '../nx.js';\nimport { getRelativePathToRoot } from '../paths.js';\nimport {\n type ITsDepVersion,\n LAMBDA_RUNTIME_VERSIONS,\n withVersions,\n} from '../versions.js';\n\n/** Dependencies a caller must declare to add a TypeScript bundle target. */\nexport const BUNDLE_DEPENDENCIES = [\n { name: 'rolldown' },\n] as const satisfies readonly { name: ITsDepVersion }[];\n\nexport interface AddPythonBundleTargetOptions {\n /**\n * Python platform\n * @default x86_64-manylinux_2_28\n */\n pythonPlatform?: 'x86_64-manylinux_2_28' | 'aarch64-manylinux_2_28';\n}\n\ninterface CreatePythonBundleTargetOptions\n extends Required<AddPythonBundleTargetOptions> {\n /**\n * Python package name\n */\n packageName: string;\n\n /**\n * Name of the bundle target, used for the outdir for the bundle\n */\n bundleTargetName: string;\n}\n\n/**\n * Create a target for bundling a python project\n */\nconst createPythonBundleTarget = ({\n packageName,\n pythonPlatform,\n bundleTargetName,\n}: CreatePythonBundleTargetOptions): TargetConfiguration => {\n return {\n cache: true,\n // The bundle holds exported dependencies and the entrypoint script, never\n // test files, so tests are excluded via `production`.\n inputs: ['production', '^production'],\n executor: 'nx:run-commands',\n outputs: [`{workspaceRoot}/dist/{projectRoot}/${bundleTargetName}`],\n options: {\n commands: [\n `uv export --frozen --no-dev --no-editable --project {projectRoot} --package ${packageName} -o dist/{projectRoot}/${bundleTargetName}/requirements.txt`,\n // `--python-version` pins wheel resolution to the Lambda Python runtime,\n // so the bundle cannot be built against whichever interpreter happens to\n // be on the build machine.\n `uv pip install -n --no-deps --no-installer-metadata --no-compile-bytecode --python-platform ${pythonPlatform} --python-version ${LAMBDA_RUNTIME_VERSIONS.python} --target dist/{projectRoot}/${bundleTargetName} -r dist/{projectRoot}/${bundleTargetName}/requirements.txt`,\n ],\n parallel: false,\n },\n };\n};\n\n/**\n * Adds a bundle target to the given project if it does not exist, and updates the build target to depend on it\n */\nexport const addPythonBundleTarget = (\n project: ProjectConfiguration,\n opts?: AddPythonBundleTargetOptions,\n) => {\n if (!project.targets) {\n project.targets = {};\n }\n\n const pythonPlatform = opts?.pythonPlatform ?? 'x86_64-manylinux_2_28';\n const bundleTargetName =\n pythonPlatform === 'aarch64-manylinux_2_28' ? 'bundle-arm' : 'bundle-x86';\n\n if (!project.targets?.[bundleTargetName]) {\n project.targets[bundleTargetName] = normalizeTargetKeyOrder({\n ...createPythonBundleTarget({\n packageName: project.name,\n pythonPlatform,\n bundleTargetName,\n }),\n dependsOn: ['compile'],\n });\n }\n\n // Add a \"bundle\" target which depends on either bundle-arm or bundle-x86 (or both)\n addDependencyToTargetIfNotPresent(project, 'bundle', bundleTargetName);\n addArtifactDependencyToTargets(project, 'bundle');\n\n return {\n bundleTargetName,\n bundleOutputDir: joinPathFragments('dist', project.root, bundleTargetName),\n };\n};\n\nexport interface AddTypeScriptBundleTargetOptions {\n /**\n * Path to the target file relative to the project dir\n */\n targetFilePath: string;\n\n /**\n * Sub directory to write bundled index.js file to (if any)\n * Outputs to dist/{projectRoot}/bundle/{bundleOutputDir}/index.js\n */\n bundleOutputDir?: string;\n\n /**\n * Modules to omit from the bundle and treat as external\n */\n external?: (string | RegExp)[];\n\n /**\n * Target platform for the bundle\n * @default 'node'\n */\n platform?: 'node' | 'browser' | 'neutral';\n}\n\n/**\n * Add a TypeScript bundle target using rolldown\n */\nexport const addTypeScriptBundleTarget = async <\n const D extends DependencyDeclaration,\n>(\n tree: Tree,\n project: ProjectConfiguration,\n opts: AddTypeScriptBundleTargetOptions,\n declaration: D & MustDeclare<typeof BUNDLE_DEPENDENCIES, D>,\n) => {\n project.targets ??= {};\n\n // Generate empty rolldown config if it doesn't exist\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'ts'),\n project.root,\n {},\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Loading a TypeScript config bundles it to `rolldown.config.<hash>.js` beside\n // itself, imports it, then unlinks it. Kept out of git so the transient file\n // can never be committed, nor picked up by `license#sync`, which builds its\n // candidate set from git-visible files.\n updateGitIgnore(tree, project.root, (patterns) =>\n patterns.includes(ROLLDOWN_CONFIG_BUNDLE_GLOB)\n ? patterns\n : [...patterns, ROLLDOWN_CONFIG_BUNDLE_GLOB],\n );\n\n // Add the bundle target\n if (!project.targets.bundle) {\n project.targets.bundle = normalizeTargetKeyOrder({\n cache: true,\n // Declared rather than left to Nx's implicit `[\"default\", \"^default\"]`,\n // which reads a dependency's whole project directory: rolldown resolves\n // dependencies through the build artifacts `default` already tracks, so\n // `^default` only adds files no bundle can contain.\n inputs: ['default'],\n outputs: [`{workspaceRoot}/dist/{projectRoot}/bundle`],\n executor: 'nx:run-commands',\n options: {\n command: 'rolldown -c rolldown.config.ts',\n cwd: '{projectRoot}',\n },\n dependsOn: ['compile'],\n });\n }\n\n // Add bundle to the build target\n addArtifactDependencyToTargets(project, 'bundle');\n\n const rolldownConfigPath = joinPathFragments(\n project.root,\n 'rolldown.config.ts',\n );\n\n const outputFile = joinPathFragments(\n getRelativePathToRoot(tree, project.name),\n 'dist',\n project.root,\n 'bundle',\n opts.bundleOutputDir ?? '.',\n 'index.js',\n );\n\n const external = opts.external?.length\n ? opts.external\n .map((ext) =>\n typeof ext === 'string' ? `'${ext}'` : `/${ext.source}/`,\n )\n .join(', ')\n : '';\n\n const entry = `{\n tsconfig: 'tsconfig.lib.json',\n input: '${opts.targetFilePath}',\n output: { file: '${outputFile}', format: 'cjs', codeSplitting: false },\n platform: '${opts.platform ?? 'node'}',\n ${external ? `external: [${external}],` : ''}\n }`;\n\n // Use GritQL to append the config entry to the defineConfig array.\n // First try the non-empty array case using the accumulate (+=) operator,\n // with an idempotency guard that checks the input path is not already present.\n const appended = await applyGritQL(\n tree,\n rolldownConfigPath,\n `\\`defineConfig([$items])\\` where { $items <: not contains \\`'${opts.targetFilePath}'\\`, $items += \", ${entry}\" }`,\n );\n\n if (!appended) {\n // Empty array — GritQL's += cannot accumulate into an empty list, so we\n // first insert a placeholder to make the array non-empty, then replace\n // the placeholder with the real entry via += (which handles regex\n // literals that are invalid inside GritQL backtick snippets).\n const inserted = await applyGritQL(\n tree,\n rolldownConfigPath,\n `\\`defineConfig([])\\` => \\`defineConfig([__PLACEHOLDER__])\\``,\n );\n if (inserted) {\n await applyGritQL(\n tree,\n rolldownConfigPath,\n `\\`defineConfig([$items])\\` where { $items <: \\`__PLACEHOLDER__\\` => ., $items += \"${entry}\" }`,\n );\n }\n }\n\n addDependenciesToPackageJson(\n tree,\n {},\n withVersions(forDependencies<typeof BUNDLE_DEPENDENCIES>(declaration), [\n 'rolldown',\n ]),\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","applyGritQL","forDependencies","addDependenciesToPackageJson","ROLLDOWN_CONFIG_BUNDLE_GLOB","updateGitIgnore","addArtifactDependencyToTargets","addDependencyToTargetIfNotPresent","normalizeTargetKeyOrder","getRelativePathToRoot","LAMBDA_RUNTIME_VERSIONS","withVersions","BUNDLE_DEPENDENCIES","name","createPythonBundleTarget","packageName","pythonPlatform","bundleTargetName","cache","inputs","executor","outputs","options","commands","python","parallel","addPythonBundleTarget","project","opts","targets","dependsOn","bundleOutputDir","root","addTypeScriptBundleTarget","tree","declaration","dirname","overwriteStrategy","KeepExisting","patterns","includes","bundle","command","cwd","rolldownConfigPath","outputFile","external","length","map","ext","source","join","entry","targetFilePath","platform","appended","inserted"],"mappings":"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"}
@@ -113,15 +113,6 @@ export const catalogsEnabled = (tree)=>{
113
113
  }
114
114
  return callback;
115
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
116
  // Convert direct version ranges to `catalog:` references in a single manifest
126
117
  // and record the range in the workspace catalog. Protocol specifiers
127
118
  // (catalog:/workspace:/...) are left alone.
@@ -134,7 +125,7 @@ const convertDependenciesToCatalog = (tree, packageJsonPath, packageNames)=>{
134
125
  ]){
135
126
  for (const packageName of packageNames){
136
127
  const version = json[field]?.[packageName];
137
- if (version && !version.includes(':') && !isCatalogExcluded(tree, packageName)) {
128
+ if (version && !version.includes(':')) {
138
129
  catalogUpdates[packageName] = version;
139
130
  json[field][packageName] = 'catalog:';
140
131
  }
@@ -1 +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.js';\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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"}
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.js';\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// 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 (version && !version.includes(':')) {\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","catalogUpdates","json","field","packageName","includes","length","writeCatalogVersions","updates","applyUpdates","catalog","applicable","fromEntries","entries","filter","name","workspaceYaml","load","read","write","dump","quotingType","yarnRc"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as React from "react"
2
2
  import { cva, type VariantProps } from "class-variance-authority"
3
3
 
4
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
4
+ import { cn } from "#lib/utils"
5
5
 
6
6
  const alertVariants = cva(
7
7
  "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
@@ -3,7 +3,7 @@
3
3
  import * as React from "react"
4
4
  import { Avatar as AvatarPrimitive } from "radix-ui"
5
5
 
6
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
6
+ import { cn } from "#lib/utils"
7
7
 
8
8
  function Avatar({
9
9
  className,
@@ -2,7 +2,7 @@ import * as React from "react"
2
2
  import { ChevronRight, MoreHorizontal } from "lucide-react"
3
3
  import { Slot } from "radix-ui"
4
4
 
5
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
5
+ import { cn } from "#lib/utils"
6
6
 
7
7
  function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
8
8
  return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
@@ -2,7 +2,7 @@ import * as React from "react"
2
2
  import { cva, type VariantProps } from "class-variance-authority"
3
3
  import { Slot } from "radix-ui"
4
4
 
5
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
5
+ import { cn } from "#lib/utils"
6
6
 
7
7
  const buttonVariants = cva(
8
8
  "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
@@ -1,6 +1,6 @@
1
1
  import * as React from "react"
2
2
 
3
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
3
+ import { cn } from "#lib/utils"
4
4
 
5
5
  function Card({ className, ...props }: React.ComponentProps<"div">) {
6
6
  return (
@@ -1,6 +1,6 @@
1
1
  import * as React from "react"
2
2
 
3
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
3
+ import { cn } from "#lib/utils"
4
4
 
5
5
  function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
6
  return (
@@ -3,7 +3,7 @@
3
3
  import * as React from "react"
4
4
  import { Separator as SeparatorPrimitive } from "radix-ui"
5
5
 
6
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
6
+ import { cn } from "#lib/utils"
7
7
 
8
8
  function Separator({
9
9
  className,
@@ -4,7 +4,7 @@ import * as React from "react"
4
4
  import { XIcon } from "lucide-react"
5
5
  import { Dialog as SheetPrimitive } from "radix-ui"
6
6
 
7
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
7
+ import { cn } from "#lib/utils"
8
8
 
9
9
  function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
10
10
  return <SheetPrimitive.Root data-slot="sheet" {...props} />
@@ -5,25 +5,25 @@ import { cva, type VariantProps } from "class-variance-authority"
5
5
  import { PanelLeftIcon } from "lucide-react"
6
6
  import { Slot } from "radix-ui"
7
7
 
8
- import { useIsMobile } from "<%= scopeAlias %>common-shadcn/hooks/use-mobile"
9
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
10
- import { Button } from "<%= scopeAlias %>common-shadcn/components/ui/button"
11
- import { Input } from "<%= scopeAlias %>common-shadcn/components/ui/input"
12
- import { Separator } from "<%= scopeAlias %>common-shadcn/components/ui/separator"
8
+ import { useIsMobile } from "#hooks/use-mobile"
9
+ import { cn } from "#lib/utils"
10
+ import { Button } from "#components/ui/button"
11
+ import { Input } from "#components/ui/input"
12
+ import { Separator } from "#components/ui/separator"
13
13
  import {
14
14
  Sheet,
15
15
  SheetContent,
16
16
  SheetDescription,
17
17
  SheetHeader,
18
18
  SheetTitle,
19
- } from "<%= scopeAlias %>common-shadcn/components/ui/sheet"
20
- import { Skeleton } from "<%= scopeAlias %>common-shadcn/components/ui/skeleton"
19
+ } from "#components/ui/sheet"
20
+ import { Skeleton } from "#components/ui/skeleton"
21
21
  import {
22
22
  Tooltip,
23
23
  TooltipContent,
24
24
  TooltipProvider,
25
25
  TooltipTrigger,
26
- } from "<%= scopeAlias %>common-shadcn/components/ui/tooltip"
26
+ } from "#components/ui/tooltip"
27
27
 
28
28
  const SIDEBAR_COOKIE_NAME = "sidebar_state"
29
29
  const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
@@ -1,4 +1,4 @@
1
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
1
+ import { cn } from "#lib/utils"
2
2
 
3
3
  function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
4
  return (
@@ -1,6 +1,6 @@
1
1
  import { Loader2Icon } from "lucide-react"
2
2
 
3
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
3
+ import { cn } from "#lib/utils"
4
4
 
5
5
  function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
6
6
  return (
@@ -1,6 +1,6 @@
1
1
  import * as React from "react"
2
2
 
3
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
3
+ import { cn } from "#lib/utils"
4
4
 
5
5
  function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
6
  return (
@@ -3,7 +3,7 @@
3
3
  import * as React from "react"
4
4
  import { Tooltip as TooltipPrimitive } from "radix-ui"
5
5
 
6
- import { cn } from "<%= scopeAlias %>common-shadcn/lib/utils"
6
+ import { cn } from "#lib/utils"
7
7
 
8
8
  function TooltipProvider({
9
9
  delayDuration = 0,
@@ -11,10 +11,10 @@
11
11
  },
12
12
  "iconLibrary": "lucide",
13
13
  "aliases": {
14
- "components": "<%= sharedShadcnAlias %>/components",
15
- "utils": "<%= sharedShadcnAlias %>/lib/utils",
16
- "hooks": "<%= sharedShadcnAlias %>/hooks",
17
- "lib": "<%= sharedShadcnAlias %>/lib",
18
- "ui": "<%= sharedShadcnAlias %>/components/ui"
14
+ "components": "#components",
15
+ "utils": "#lib/utils",
16
+ "hooks": "#hooks",
17
+ "lib": "#lib",
18
+ "ui": "#components/ui"
19
19
  }
20
20
  }
@@ -13,6 +13,22 @@ export declare const BIOME_WASM_VERSION: string;
13
13
  * reporter writes — from formatting and linting.
14
14
  */
15
15
  export declare const BIOME_TEST_OUTPUT_EXCLUDE = "!**/test-output";
16
+ /**
17
+ * The transient bundle rolldown writes beside a `rolldown.config.ts` while
18
+ * loading it.
19
+ *
20
+ * Loading a TypeScript config bundles it to `rolldown.config.<hash>.js` in the
21
+ * config's own directory, imports it, then unlinks it. That file exists for as
22
+ * long as the bundle takes, so a `format` or `lint` target running concurrently
23
+ * in the same project sees a machine-generated file — reported unformatted,
24
+ * failing the target for no fault of the source.
25
+ *
26
+ * `.*js` rather than `.js`, since the extension follows the config's own: a
27
+ * `.mts` config bundles to `.mjs`, a `.cts` one to `.cjs`.
28
+ */
29
+ export declare const ROLLDOWN_CONFIG_BUNDLE_GLOB = "**/rolldown.config.*.*js";
30
+ /** Keeps rolldown's transient config bundle out of formatting and linting. */
31
+ export declare const BIOME_ROLLDOWN_CONFIG_BUNDLE_EXCLUDE = "!**/rolldown.config.*.*js";
16
32
  /**
17
33
  * The biome.json vended into a new workspace. The pnpm catalog resolver is only
18
34
  * included on pnpm workspaces, since `experimentalPnpmCatalogs` is Biome's only
@@ -16,6 +16,20 @@ import { TS_VERSIONS } from "./versions.js";
16
16
  * Excludes test reports — including the vendored scripts vitest's coverage HTML
17
17
  * reporter writes — from formatting and linting.
18
18
  */ export const BIOME_TEST_OUTPUT_EXCLUDE = '!**/test-output';
19
+ /**
20
+ * The transient bundle rolldown writes beside a `rolldown.config.ts` while
21
+ * loading it.
22
+ *
23
+ * Loading a TypeScript config bundles it to `rolldown.config.<hash>.js` in the
24
+ * config's own directory, imports it, then unlinks it. That file exists for as
25
+ * long as the bundle takes, so a `format` or `lint` target running concurrently
26
+ * in the same project sees a machine-generated file — reported unformatted,
27
+ * failing the target for no fault of the source.
28
+ *
29
+ * `.*js` rather than `.js`, since the extension follows the config's own: a
30
+ * `.mts` config bundles to `.mjs`, a `.cts` one to `.cjs`.
31
+ */ export const ROLLDOWN_CONFIG_BUNDLE_GLOB = '**/rolldown.config.*.*js';
32
+ /** Keeps rolldown's transient config bundle out of formatting and linting. */ export const BIOME_ROLLDOWN_CONFIG_BUNDLE_EXCLUDE = `!${ROLLDOWN_CONFIG_BUNDLE_GLOB}`;
19
33
  /**
20
34
  * The biome.json vended into a new workspace. The pnpm catalog resolver is only
21
35
  * included on pnpm workspaces, since `experimentalPnpmCatalogs` is Biome's only
@@ -74,6 +88,7 @@ import { TS_VERSIONS } from "./versions.js";
74
88
  '!**/dist',
75
89
  '!**/out-tsc',
76
90
  BIOME_TEST_OUTPUT_EXCLUDE,
91
+ BIOME_ROLLDOWN_CONFIG_BUNDLE_EXCLUDE,
77
92
  '!**/node_modules',
78
93
  '!**/.nx',
79
94
  '!**/.venv',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/format.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Biome } from '@biomejs/js-api/nodejs';\nimport { getProjects, type Tree } from '@nx/devkit';\nimport { createRequire } from 'module';\nimport path from 'path';\nimport { type RuffOptions, ruffFixAndFormat } from './ruff.js';\nimport { tryReadToml } from './toml.js';\nimport { TS_VERSIONS } from './versions.js';\n\n/**\n * The Biome release the wasm bindings are built from. Must match\n * `TS_VERSIONS['@biomejs/biome']`, the CLI the vended targets run.\n */\nexport const BIOME_WASM_VERSION: string = createRequire(import.meta.url)(\n '@biomejs/wasm-nodejs/package.json',\n).version;\n\n/**\n * Excludes test reports — including the vendored scripts vitest's coverage HTML\n * reporter writes — from formatting and linting.\n */\nexport const BIOME_TEST_OUTPUT_EXCLUDE = '!**/test-output';\n\n/**\n * The biome.json vended into a new workspace. The pnpm catalog resolver is only\n * included on pnpm workspaces, since `experimentalPnpmCatalogs` is Biome's only\n * catalog resolver and reads `pnpm-workspace.yaml` exclusively — it does nothing\n * for yarn or bun catalogs, so vending it there would be misleading.\n */\nexport const getDefaultBiomeConfig = (tree: Tree) => ({\n $schema: `https://biomejs.dev/schemas/${TS_VERSIONS['@biomejs/biome']}/schema.json`,\n root: true,\n formatter: {\n enabled: true,\n indentStyle: 'space',\n indentWidth: 2,\n lineWidth: 80,\n },\n javascript: {\n formatter: {\n quoteStyle: 'single',\n trailingCommas: 'all',\n },\n // Resolve `catalog:` versions from pnpm-workspace.yaml (pnpm workspaces only).\n ...(tree.exists('pnpm-workspace.yaml')\n ? { resolver: { experimentalPnpmCatalogs: true } }\n : {}),\n },\n css: {\n formatter: {\n quoteStyle: 'single',\n },\n linter: {\n enabled: false,\n },\n },\n linter: {\n enabled: true,\n rules: {\n preset: 'none',\n correctness: {\n // Every project must declare the third-party dependencies its source\n // code imports in its own package.json.\n noUndeclaredDependencies: 'error',\n },\n },\n },\n assist: {\n actions: {\n source: {\n organizeImports: 'on',\n },\n },\n },\n files: {\n includes: [\n '**',\n '!**/dist',\n '!**/out-tsc',\n BIOME_TEST_OUTPUT_EXCLUDE,\n '!**/node_modules',\n '!**/.nx',\n '!**/.venv',\n // GritQL codemod cache written by generators — its sample sources\n // otherwise pollute a bare `biome check .` with parse errors.\n '!**/.grit',\n '!**/*.css',\n '!**/*.gen.*',\n '!**/generated/**',\n '!**/tsconfig*.json',\n ],\n },\n // Config files, build scripts and tests use root tooling rather than\n // declaring it per-project, so the undeclared-dependency rule is off for them.\n overrides: [\n {\n includes: [\n '**/*.config.{ts,mts,cts,js,mjs,cjs}',\n '**/*.{spec,test}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}',\n '**/*.stories.{ts,tsx}',\n ],\n linter: {\n rules: {\n correctness: {\n noUndeclaredDependencies: 'off',\n },\n },\n },\n },\n ],\n});\n\nconst BIOME_FORMATTABLE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n '.json',\n '.jsonc',\n '.css',\n]);\n\n/** Matches `tsconfig.json` and variants like `tsconfig.lib.json`. */\nconst isTsConfig = (filePath: string): boolean =>\n /(^|\\/)tsconfig[^/]*\\.json$/.test(filePath);\n\nexport interface FormatFilesInSubtreeOptions {\n /**\n * Paths, relative to the workspace root, to leave untouched.\n *\n * For files another tool owns the formatting of: formatting them here makes\n * generation non-idempotent, since the tool rewrites them in its own shape on\n * the next run and the workspace flips between the two forms.\n */\n readonly ignore?: readonly string[];\n}\n\n/**\n * Paths declared ignored for a tree, which stay ignored for every later call.\n *\n * A call formats every change pending in the tree, not only the ones its caller\n * made, so the list cannot be scoped to the call that passes it: generators\n * composing on one tree would reformat a file an earlier generator had excluded.\n * Once the generator that owns a file declares it ignored, it stays ignored for\n * the rest of the run.\n */\nconst treeIgnoredPaths = new WeakMap<Tree, Set<string>>();\n\n/**\n * Tree paths are workspace-relative and forward-slash separated. Normalise so a\n * caller building a path with `path.join` on Windows still matches.\n */\nconst normalizeTreePath = (filePath: string): string =>\n filePath.split(path.sep).join('/').replace(/^\\.\\//, '');\n\n/**\n * Format files in the given directory within the tree.\n * Handles both TypeScript/JavaScript/JSON (via biome) and Python (via ruff) files.\n * See https://github.com/nrwl/nx/blob/4cd640a9187954505d12de5b6d76a90d8ce4c2eb/packages/devkit/src/generators/format-files.ts#L11\n */\nexport async function formatFilesInSubtree(\n tree: Tree,\n dir?: string,\n options?: FormatFilesInSubtreeOptions,\n): Promise<void> {\n let ignored = treeIgnoredPaths.get(tree);\n if (options?.ignore?.length) {\n if (!ignored) {\n ignored = new Set();\n treeIgnoredPaths.set(tree, ignored);\n }\n for (const filePath of options.ignore) {\n ignored.add(normalizeTreePath(filePath));\n }\n }\n const changedFiles = tree\n .listChanges()\n .filter((file) => file.type !== 'DELETE')\n .filter((file) => (dir ? file.path.startsWith(dir) : true))\n .filter((file) => !ignored?.has(normalizeTreePath(file.path)));\n\n const pyFiles = changedFiles.filter((file) => file.path.endsWith('.py'));\n const otherFiles = changedFiles.filter(\n (file) =>\n BIOME_FORMATTABLE_EXTENSIONS.has(path.extname(file.path)) &&\n // tsconfigs are not biome-managed: they're excluded from the vended\n // format target (Nx's typescript-sync rewrites them without formatting),\n // so formatting them at generation would only diverge from the form\n // written on later runs. Leave them as updateJson/writeJson emit them so\n // repeated generation stays idempotent.\n !isTsConfig(file.path),\n );\n\n // Resolve each project's ruff settings (module names, line-length) so files\n // are formatted to match the on-disk build (see getPythonProjectRuffConfigs).\n const pythonProjectConfigs = pyFiles.length\n ? getPythonProjectRuffConfigs(tree)\n : [];\n\n // Format Python files with ruff (lint fixes + formatting)\n for (const file of pyFiles) {\n try {\n const content = ruffFixAndFormat(\n file.content.toString('utf-8'),\n file.path,\n resolveRuffOptions(\n readRuffConfig(tree, file.path),\n getOwningProjectRuffConfig(file.path, pythonProjectConfigs),\n ),\n );\n tree.write(file.path, content);\n } catch {\n // Silently skip ruff formatting failures\n }\n }\n\n if (otherFiles.length === 0) return;\n\n formatWithBiome(tree, otherFiles);\n}\n\n/**\n * The Biome configuration to format with: the workspace's own `biome.json`, else\n * the config we vend.\n *\n * Read through the tree, which falls back to disk for a file it doesn't hold. So\n * this resolves the most current config either way — the workspace's on-disk one,\n * or the version a generator has just written to the tree and not yet flushed,\n * which shelling out to the CLI could never see.\n */\nfunction readBiomeConfig(tree: Tree): unknown {\n const config = tree.read('biome.json', 'utf-8');\n if (config) {\n try {\n return JSON.parse(config);\n } catch {\n // Malformed config — fall through to the config we vend\n }\n }\n return getDefaultBiomeConfig(tree);\n}\n\n/**\n * Format files with Biome in-process, reusing one instance across the batch.\n *\n * Replaces one `biome format --stdin-file-path` process per file, which\n * dominated generation at ~70ms each: `formatFilesInSubtree` formats every\n * change accumulated in the tree, not only the ones its caller made, so\n * generators sharing a tree reformat the same files once per call. In-process is\n * ~0.5ms per file. Output was verified byte-identical across the plugin's whole\n * source tree, except that the CLI corrupts control characters passed through\n * stdin (a NUL in a template literal) where formatting in-process preserves them.\n */\nfunction formatWithBiome(\n tree: Tree,\n files: { path: string; content: Buffer | null }[],\n): void {\n try {\n const biome = new Biome();\n const { projectKey } = biome.openProject();\n biome.applyConfiguration(projectKey, readBiomeConfig(tree));\n\n for (const file of files) {\n try {\n const { content } = biome.formatContent(\n projectKey,\n file.content?.toString('utf-8') ?? '',\n { filePath: file.path },\n );\n tree.write(file.path, content);\n } catch {\n // Leave individual files that fail to format untouched\n }\n }\n } catch {\n // Silently skip formatting failures\n }\n}\n\n/**\n * Read the ruff config for a file, by walking from its directory up to the\n * workspace root looking for `.ruff.toml`, `ruff.toml`, or a `pyproject.toml`\n * with a `[tool.ruff]` section — the same files, in the same order, that ruff\n * itself resolves. The walk stops at the workspace root so a stray config in a\n * parent of the workspace (or the home directory) is never treated as the\n * project's.\n *\n * The settings are read rather than merely detected because formatting runs\n * in-process against tree content, so ruff never sees the file's location and\n * cannot resolve the config itself (see {@link resolveRuffOptions}).\n *\n * Reads go through the tree, which falls through to disk for files this run has\n * not touched, so a config the generator has just written in memory is picked up\n * as well as one already on disk.\n */\nfunction readRuffConfig(tree: Tree, filePath: string): RuffOptions | undefined {\n let dir = path.dirname(filePath);\n while (true) {\n for (const name of ['.ruff.toml', 'ruff.toml']) {\n const config = tryReadToml(tree, path.join(dir, name));\n if (config) {\n return config as RuffOptions;\n }\n }\n const ruff = (tryReadToml(tree, path.join(dir, 'pyproject.toml')) as any)\n ?.tool?.ruff;\n if (ruff) {\n return ruff as RuffOptions;\n }\n // Stop once the workspace root ('.') has been checked.\n if (dir === '.' || dir === '' || dir === path.dirname(dir)) {\n return undefined;\n }\n dir = path.dirname(dir);\n }\n}\n\n/**\n * The `[tool.ruff.lint].select` generated Python projects vend. Generation\n * formats before that config lands on disk, so it is pinned here to keep\n * generated files clean under the project's own `lint` target rather than under\n * whatever ruff's defaults happen to be for the pinned release.\n */\nconst DEFAULT_RUFF_SELECT = ['E', 'F', 'UP', 'B', 'SIM', 'I'];\n\ninterface PythonProjectRuffConfig {\n /** Project root, normalised to use forward slashes. */\n readonly root: string;\n /** Top-level importable module names declared by the project. */\n readonly modules: string[];\n /** The project's `[tool.ruff].line-length`, if set. */\n readonly lineLength?: number;\n /**\n * Ruff `target-version` (eg `py314`) derived from `[project].requires-python`.\n * Generation formats via stdin with no pyproject, so it must be passed\n * explicitly — ruff's formatting differs by target.\n */\n readonly targetVersion?: string;\n /** The project's `[tool.ruff.lint].select`, if set. */\n readonly select?: string[];\n}\n\n/**\n * Derive ruff's `target-version` (eg `py314`) from a PEP 508\n * `requires-python` specifier (eg `>=3.14`). Ruff targets the minimum\n * supported version, so take the lowest `major.minor` mentioned.\n */\nexport const requiresPythonToRuffTarget = (\n requiresPython: unknown,\n): string | undefined => {\n if (typeof requiresPython !== 'string') {\n return undefined;\n }\n let min: { major: number; minor: number } | undefined;\n for (const match of requiresPython.matchAll(/(\\d+)\\.(\\d+)/g)) {\n const major = Number(match[1]);\n const minor = Number(match[2]);\n if (\n !min ||\n major < min.major ||\n (major === min.major && minor < min.minor)\n ) {\n min = { major, minor };\n }\n }\n return min ? `py${min.major}${min.minor}` : undefined;\n};\n\n/**\n * Map each Nx project with a `pyproject.toml` to the ruff settings the on-disk\n * build enforces for it: its top-level module names (from\n * `[tool.hatch.build.targets.wheel].packages`), its `[tool.ruff].line-length`\n * and its `[tool.ruff.lint].select`.\n */\nfunction getPythonProjectRuffConfigs(tree: Tree): PythonProjectRuffConfig[] {\n const configs: PythonProjectRuffConfig[] = [];\n\n for (const project of getProjects(tree).values()) {\n // Projects without a pyproject.toml, or whose one cannot be parsed, have no\n // ruff settings to contribute.\n const pyproject = tryReadToml(\n tree,\n path.join(project.root, 'pyproject.toml'),\n ) as any;\n if (!pyproject) {\n continue;\n }\n const wheelPackages: unknown =\n pyproject?.tool?.hatch?.build?.targets?.wheel?.packages;\n // Record the top-level module segment (`pkg/sub` -> `pkg`), which is\n // all `known-first-party` keys off.\n const modules = Array.isArray(wheelPackages)\n ? wheelPackages\n .filter((pkg): pkg is string => typeof pkg === 'string' && !!pkg)\n .map((pkg) => pkg.split('/')[0])\n : [];\n const lineLength: unknown = pyproject?.tool?.ruff?.['line-length'];\n const targetVersion = requiresPythonToRuffTarget(\n pyproject?.project?.['requires-python'],\n );\n const selected: unknown = pyproject?.tool?.ruff?.lint?.select;\n const select = Array.isArray(selected)\n ? selected.filter(\n (rule): rule is string => typeof rule === 'string' && !!rule,\n )\n : undefined;\n if (\n modules.length ||\n typeof lineLength === 'number' ||\n targetVersion ||\n select?.length\n ) {\n configs.push({\n root: project.root.split(path.sep).join('/'),\n modules,\n lineLength: typeof lineLength === 'number' ? lineLength : undefined,\n targetVersion,\n select: select?.length ? select : undefined,\n });\n }\n }\n\n return configs;\n}\n\n/**\n * Resolve the ruff config for the project that owns a file (the project with\n * the longest root that is a prefix of the file path). Ruff runs per-project on\n * disk, so a file's settings come from its own project — only its own module is\n * first-party (sibling workspace packages are third-party) and its own\n * line-length applies — and scoping this way keeps in-tree formatting\n * consistent with the on-disk build.\n */\nfunction getOwningProjectRuffConfig(\n filePath: string,\n configs: PythonProjectRuffConfig[],\n): PythonProjectRuffConfig | undefined {\n let owner: PythonProjectRuffConfig | undefined;\n for (const config of configs) {\n if (\n (filePath === config.root || filePath.startsWith(`${config.root}/`)) &&\n (!owner || config.root.length > owner.root.length)\n ) {\n owner = config;\n }\n }\n return owner;\n}\n\n/**\n * Resolve the ruff settings to format a Python file with, mirroring what the\n * file's build enforces.\n *\n * Ruff's own config discovery never runs: settings are passed to the linter\n * directly rather than resolved from the file's location, which it never sees.\n * That also means a stray config above the workspace (or in the home directory)\n * can never be picked up.\n *\n * `config` is the file's nearest ruff config, whose rule selection is honoured\n * as-is. Without one, ruff would fall back to its own defaults, which change\n * between releases — 0.16 widened them from `E` and `F` to 36 rule prefixes — so\n * generation would apply fixes the project's build never asks for (eg `RUF022`\n * reordering `__all__`). Instead the project's own `lint.select` is pinned, so\n * generation enforces exactly what `lint` does and nothing more.\n *\n * `projectConfig` layers on the settings derived from the owning project rather\n * than declared under `[tool.ruff]`: `known-first-party` (the project's own\n * modules, from its wheel packages) keeps its imports in their own group, and\n * `target-version` (from its `requires-python`) matches the formatting the build\n * produces.\n */\nfunction resolveRuffOptions(\n config: RuffOptions | undefined,\n projectConfig?: PythonProjectRuffConfig,\n): RuffOptions {\n const lint: Record<string, unknown> = { ...config?.lint };\n // Pin the rule selection only when deferring to ruff's defaults would\n // otherwise apply rules the project's build does not enforce.\n if (!config) {\n lint.select = projectConfig?.select ?? DEFAULT_RUFF_SELECT;\n }\n if (projectConfig?.modules.length) {\n lint.isort = {\n ...(lint.isort as object | undefined),\n 'known-first-party': projectConfig.modules,\n };\n }\n return {\n ...config,\n ...(typeof projectConfig?.lineLength === 'number'\n ? { 'line-length': projectConfig.lineLength }\n : {}),\n ...(projectConfig?.targetVersion\n ? { 'target-version': projectConfig.targetVersion }\n : {}),\n lint,\n };\n}\n"],"names":["Biome","getProjects","createRequire","path","ruffFixAndFormat","tryReadToml","TS_VERSIONS","BIOME_WASM_VERSION","url","version","BIOME_TEST_OUTPUT_EXCLUDE","getDefaultBiomeConfig","tree","$schema","root","formatter","enabled","indentStyle","indentWidth","lineWidth","javascript","quoteStyle","trailingCommas","exists","resolver","experimentalPnpmCatalogs","css","linter","rules","preset","correctness","noUndeclaredDependencies","assist","actions","source","organizeImports","files","includes","overrides","BIOME_FORMATTABLE_EXTENSIONS","Set","isTsConfig","filePath","test","treeIgnoredPaths","WeakMap","normalizeTreePath","split","sep","join","replace","formatFilesInSubtree","dir","options","ignored","get","ignore","length","set","add","changedFiles","listChanges","filter","file","type","startsWith","has","pyFiles","endsWith","otherFiles","extname","pythonProjectConfigs","getPythonProjectRuffConfigs","content","toString","resolveRuffOptions","readRuffConfig","getOwningProjectRuffConfig","write","formatWithBiome","readBiomeConfig","config","read","JSON","parse","biome","projectKey","openProject","applyConfiguration","formatContent","dirname","name","ruff","tool","undefined","DEFAULT_RUFF_SELECT","requiresPythonToRuffTarget","requiresPython","min","match","matchAll","major","Number","minor","configs","project","values","pyproject","wheelPackages","hatch","build","targets","wheel","packages","modules","Array","isArray","pkg","map","lineLength","targetVersion","selected","lint","select","rule","push","owner","projectConfig","isort"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/format.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Biome } from '@biomejs/js-api/nodejs';\nimport { getProjects, type Tree } from '@nx/devkit';\nimport { createRequire } from 'module';\nimport path from 'path';\nimport { type RuffOptions, ruffFixAndFormat } from './ruff.js';\nimport { tryReadToml } from './toml.js';\nimport { TS_VERSIONS } from './versions.js';\n\n/**\n * The Biome release the wasm bindings are built from. Must match\n * `TS_VERSIONS['@biomejs/biome']`, the CLI the vended targets run.\n */\nexport const BIOME_WASM_VERSION: string = createRequire(import.meta.url)(\n '@biomejs/wasm-nodejs/package.json',\n).version;\n\n/**\n * Excludes test reports — including the vendored scripts vitest's coverage HTML\n * reporter writes — from formatting and linting.\n */\nexport const BIOME_TEST_OUTPUT_EXCLUDE = '!**/test-output';\n\n/**\n * The transient bundle rolldown writes beside a `rolldown.config.ts` while\n * loading it.\n *\n * Loading a TypeScript config bundles it to `rolldown.config.<hash>.js` in the\n * config's own directory, imports it, then unlinks it. That file exists for as\n * long as the bundle takes, so a `format` or `lint` target running concurrently\n * in the same project sees a machine-generated file — reported unformatted,\n * failing the target for no fault of the source.\n *\n * `.*js` rather than `.js`, since the extension follows the config's own: a\n * `.mts` config bundles to `.mjs`, a `.cts` one to `.cjs`.\n */\nexport const ROLLDOWN_CONFIG_BUNDLE_GLOB = '**/rolldown.config.*.*js';\n\n/** Keeps rolldown's transient config bundle out of formatting and linting. */\nexport const BIOME_ROLLDOWN_CONFIG_BUNDLE_EXCLUDE = `!${ROLLDOWN_CONFIG_BUNDLE_GLOB}`;\n\n/**\n * The biome.json vended into a new workspace. The pnpm catalog resolver is only\n * included on pnpm workspaces, since `experimentalPnpmCatalogs` is Biome's only\n * catalog resolver and reads `pnpm-workspace.yaml` exclusively — it does nothing\n * for yarn or bun catalogs, so vending it there would be misleading.\n */\nexport const getDefaultBiomeConfig = (tree: Tree) => ({\n $schema: `https://biomejs.dev/schemas/${TS_VERSIONS['@biomejs/biome']}/schema.json`,\n root: true,\n formatter: {\n enabled: true,\n indentStyle: 'space',\n indentWidth: 2,\n lineWidth: 80,\n },\n javascript: {\n formatter: {\n quoteStyle: 'single',\n trailingCommas: 'all',\n },\n // Resolve `catalog:` versions from pnpm-workspace.yaml (pnpm workspaces only).\n ...(tree.exists('pnpm-workspace.yaml')\n ? { resolver: { experimentalPnpmCatalogs: true } }\n : {}),\n },\n css: {\n formatter: {\n quoteStyle: 'single',\n },\n linter: {\n enabled: false,\n },\n },\n linter: {\n enabled: true,\n rules: {\n preset: 'none',\n correctness: {\n // Every project must declare the third-party dependencies its source\n // code imports in its own package.json.\n noUndeclaredDependencies: 'error',\n },\n },\n },\n assist: {\n actions: {\n source: {\n organizeImports: 'on',\n },\n },\n },\n files: {\n includes: [\n '**',\n '!**/dist',\n '!**/out-tsc',\n BIOME_TEST_OUTPUT_EXCLUDE,\n BIOME_ROLLDOWN_CONFIG_BUNDLE_EXCLUDE,\n '!**/node_modules',\n '!**/.nx',\n '!**/.venv',\n // GritQL codemod cache written by generators — its sample sources\n // otherwise pollute a bare `biome check .` with parse errors.\n '!**/.grit',\n '!**/*.css',\n '!**/*.gen.*',\n '!**/generated/**',\n '!**/tsconfig*.json',\n ],\n },\n // Config files, build scripts and tests use root tooling rather than\n // declaring it per-project, so the undeclared-dependency rule is off for them.\n overrides: [\n {\n includes: [\n '**/*.config.{ts,mts,cts,js,mjs,cjs}',\n '**/*.{spec,test}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}',\n '**/*.stories.{ts,tsx}',\n ],\n linter: {\n rules: {\n correctness: {\n noUndeclaredDependencies: 'off',\n },\n },\n },\n },\n ],\n});\n\nconst BIOME_FORMATTABLE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n '.json',\n '.jsonc',\n '.css',\n]);\n\n/** Matches `tsconfig.json` and variants like `tsconfig.lib.json`. */\nconst isTsConfig = (filePath: string): boolean =>\n /(^|\\/)tsconfig[^/]*\\.json$/.test(filePath);\n\nexport interface FormatFilesInSubtreeOptions {\n /**\n * Paths, relative to the workspace root, to leave untouched.\n *\n * For files another tool owns the formatting of: formatting them here makes\n * generation non-idempotent, since the tool rewrites them in its own shape on\n * the next run and the workspace flips between the two forms.\n */\n readonly ignore?: readonly string[];\n}\n\n/**\n * Paths declared ignored for a tree, which stay ignored for every later call.\n *\n * A call formats every change pending in the tree, not only the ones its caller\n * made, so the list cannot be scoped to the call that passes it: generators\n * composing on one tree would reformat a file an earlier generator had excluded.\n * Once the generator that owns a file declares it ignored, it stays ignored for\n * the rest of the run.\n */\nconst treeIgnoredPaths = new WeakMap<Tree, Set<string>>();\n\n/**\n * Tree paths are workspace-relative and forward-slash separated. Normalise so a\n * caller building a path with `path.join` on Windows still matches.\n */\nconst normalizeTreePath = (filePath: string): string =>\n filePath.split(path.sep).join('/').replace(/^\\.\\//, '');\n\n/**\n * Format files in the given directory within the tree.\n * Handles both TypeScript/JavaScript/JSON (via biome) and Python (via ruff) files.\n * See https://github.com/nrwl/nx/blob/4cd640a9187954505d12de5b6d76a90d8ce4c2eb/packages/devkit/src/generators/format-files.ts#L11\n */\nexport async function formatFilesInSubtree(\n tree: Tree,\n dir?: string,\n options?: FormatFilesInSubtreeOptions,\n): Promise<void> {\n let ignored = treeIgnoredPaths.get(tree);\n if (options?.ignore?.length) {\n if (!ignored) {\n ignored = new Set();\n treeIgnoredPaths.set(tree, ignored);\n }\n for (const filePath of options.ignore) {\n ignored.add(normalizeTreePath(filePath));\n }\n }\n const changedFiles = tree\n .listChanges()\n .filter((file) => file.type !== 'DELETE')\n .filter((file) => (dir ? file.path.startsWith(dir) : true))\n .filter((file) => !ignored?.has(normalizeTreePath(file.path)));\n\n const pyFiles = changedFiles.filter((file) => file.path.endsWith('.py'));\n const otherFiles = changedFiles.filter(\n (file) =>\n BIOME_FORMATTABLE_EXTENSIONS.has(path.extname(file.path)) &&\n // tsconfigs are not biome-managed: they're excluded from the vended\n // format target (Nx's typescript-sync rewrites them without formatting),\n // so formatting them at generation would only diverge from the form\n // written on later runs. Leave them as updateJson/writeJson emit them so\n // repeated generation stays idempotent.\n !isTsConfig(file.path),\n );\n\n // Resolve each project's ruff settings (module names, line-length) so files\n // are formatted to match the on-disk build (see getPythonProjectRuffConfigs).\n const pythonProjectConfigs = pyFiles.length\n ? getPythonProjectRuffConfigs(tree)\n : [];\n\n // Format Python files with ruff (lint fixes + formatting)\n for (const file of pyFiles) {\n try {\n const content = ruffFixAndFormat(\n file.content.toString('utf-8'),\n file.path,\n resolveRuffOptions(\n readRuffConfig(tree, file.path),\n getOwningProjectRuffConfig(file.path, pythonProjectConfigs),\n ),\n );\n tree.write(file.path, content);\n } catch {\n // Silently skip ruff formatting failures\n }\n }\n\n if (otherFiles.length === 0) return;\n\n formatWithBiome(tree, otherFiles);\n}\n\n/**\n * The Biome configuration to format with: the workspace's own `biome.json`, else\n * the config we vend.\n *\n * Read through the tree, which falls back to disk for a file it doesn't hold. So\n * this resolves the most current config either way — the workspace's on-disk one,\n * or the version a generator has just written to the tree and not yet flushed,\n * which shelling out to the CLI could never see.\n */\nfunction readBiomeConfig(tree: Tree): unknown {\n const config = tree.read('biome.json', 'utf-8');\n if (config) {\n try {\n return JSON.parse(config);\n } catch {\n // Malformed config — fall through to the config we vend\n }\n }\n return getDefaultBiomeConfig(tree);\n}\n\n/**\n * Format files with Biome in-process, reusing one instance across the batch.\n *\n * Replaces one `biome format --stdin-file-path` process per file, which\n * dominated generation at ~70ms each: `formatFilesInSubtree` formats every\n * change accumulated in the tree, not only the ones its caller made, so\n * generators sharing a tree reformat the same files once per call. In-process is\n * ~0.5ms per file. Output was verified byte-identical across the plugin's whole\n * source tree, except that the CLI corrupts control characters passed through\n * stdin (a NUL in a template literal) where formatting in-process preserves them.\n */\nfunction formatWithBiome(\n tree: Tree,\n files: { path: string; content: Buffer | null }[],\n): void {\n try {\n const biome = new Biome();\n const { projectKey } = biome.openProject();\n biome.applyConfiguration(projectKey, readBiomeConfig(tree));\n\n for (const file of files) {\n try {\n const { content } = biome.formatContent(\n projectKey,\n file.content?.toString('utf-8') ?? '',\n { filePath: file.path },\n );\n tree.write(file.path, content);\n } catch {\n // Leave individual files that fail to format untouched\n }\n }\n } catch {\n // Silently skip formatting failures\n }\n}\n\n/**\n * Read the ruff config for a file, by walking from its directory up to the\n * workspace root looking for `.ruff.toml`, `ruff.toml`, or a `pyproject.toml`\n * with a `[tool.ruff]` section — the same files, in the same order, that ruff\n * itself resolves. The walk stops at the workspace root so a stray config in a\n * parent of the workspace (or the home directory) is never treated as the\n * project's.\n *\n * The settings are read rather than merely detected because formatting runs\n * in-process against tree content, so ruff never sees the file's location and\n * cannot resolve the config itself (see {@link resolveRuffOptions}).\n *\n * Reads go through the tree, which falls through to disk for files this run has\n * not touched, so a config the generator has just written in memory is picked up\n * as well as one already on disk.\n */\nfunction readRuffConfig(tree: Tree, filePath: string): RuffOptions | undefined {\n let dir = path.dirname(filePath);\n while (true) {\n for (const name of ['.ruff.toml', 'ruff.toml']) {\n const config = tryReadToml(tree, path.join(dir, name));\n if (config) {\n return config as RuffOptions;\n }\n }\n const ruff = (tryReadToml(tree, path.join(dir, 'pyproject.toml')) as any)\n ?.tool?.ruff;\n if (ruff) {\n return ruff as RuffOptions;\n }\n // Stop once the workspace root ('.') has been checked.\n if (dir === '.' || dir === '' || dir === path.dirname(dir)) {\n return undefined;\n }\n dir = path.dirname(dir);\n }\n}\n\n/**\n * The `[tool.ruff.lint].select` generated Python projects vend. Generation\n * formats before that config lands on disk, so it is pinned here to keep\n * generated files clean under the project's own `lint` target rather than under\n * whatever ruff's defaults happen to be for the pinned release.\n */\nconst DEFAULT_RUFF_SELECT = ['E', 'F', 'UP', 'B', 'SIM', 'I'];\n\ninterface PythonProjectRuffConfig {\n /** Project root, normalised to use forward slashes. */\n readonly root: string;\n /** Top-level importable module names declared by the project. */\n readonly modules: string[];\n /** The project's `[tool.ruff].line-length`, if set. */\n readonly lineLength?: number;\n /**\n * Ruff `target-version` (eg `py314`) derived from `[project].requires-python`.\n * Generation formats via stdin with no pyproject, so it must be passed\n * explicitly — ruff's formatting differs by target.\n */\n readonly targetVersion?: string;\n /** The project's `[tool.ruff.lint].select`, if set. */\n readonly select?: string[];\n}\n\n/**\n * Derive ruff's `target-version` (eg `py314`) from a PEP 508\n * `requires-python` specifier (eg `>=3.14`). Ruff targets the minimum\n * supported version, so take the lowest `major.minor` mentioned.\n */\nexport const requiresPythonToRuffTarget = (\n requiresPython: unknown,\n): string | undefined => {\n if (typeof requiresPython !== 'string') {\n return undefined;\n }\n let min: { major: number; minor: number } | undefined;\n for (const match of requiresPython.matchAll(/(\\d+)\\.(\\d+)/g)) {\n const major = Number(match[1]);\n const minor = Number(match[2]);\n if (\n !min ||\n major < min.major ||\n (major === min.major && minor < min.minor)\n ) {\n min = { major, minor };\n }\n }\n return min ? `py${min.major}${min.minor}` : undefined;\n};\n\n/**\n * Map each Nx project with a `pyproject.toml` to the ruff settings the on-disk\n * build enforces for it: its top-level module names (from\n * `[tool.hatch.build.targets.wheel].packages`), its `[tool.ruff].line-length`\n * and its `[tool.ruff.lint].select`.\n */\nfunction getPythonProjectRuffConfigs(tree: Tree): PythonProjectRuffConfig[] {\n const configs: PythonProjectRuffConfig[] = [];\n\n for (const project of getProjects(tree).values()) {\n // Projects without a pyproject.toml, or whose one cannot be parsed, have no\n // ruff settings to contribute.\n const pyproject = tryReadToml(\n tree,\n path.join(project.root, 'pyproject.toml'),\n ) as any;\n if (!pyproject) {\n continue;\n }\n const wheelPackages: unknown =\n pyproject?.tool?.hatch?.build?.targets?.wheel?.packages;\n // Record the top-level module segment (`pkg/sub` -> `pkg`), which is\n // all `known-first-party` keys off.\n const modules = Array.isArray(wheelPackages)\n ? wheelPackages\n .filter((pkg): pkg is string => typeof pkg === 'string' && !!pkg)\n .map((pkg) => pkg.split('/')[0])\n : [];\n const lineLength: unknown = pyproject?.tool?.ruff?.['line-length'];\n const targetVersion = requiresPythonToRuffTarget(\n pyproject?.project?.['requires-python'],\n );\n const selected: unknown = pyproject?.tool?.ruff?.lint?.select;\n const select = Array.isArray(selected)\n ? selected.filter(\n (rule): rule is string => typeof rule === 'string' && !!rule,\n )\n : undefined;\n if (\n modules.length ||\n typeof lineLength === 'number' ||\n targetVersion ||\n select?.length\n ) {\n configs.push({\n root: project.root.split(path.sep).join('/'),\n modules,\n lineLength: typeof lineLength === 'number' ? lineLength : undefined,\n targetVersion,\n select: select?.length ? select : undefined,\n });\n }\n }\n\n return configs;\n}\n\n/**\n * Resolve the ruff config for the project that owns a file (the project with\n * the longest root that is a prefix of the file path). Ruff runs per-project on\n * disk, so a file's settings come from its own project — only its own module is\n * first-party (sibling workspace packages are third-party) and its own\n * line-length applies — and scoping this way keeps in-tree formatting\n * consistent with the on-disk build.\n */\nfunction getOwningProjectRuffConfig(\n filePath: string,\n configs: PythonProjectRuffConfig[],\n): PythonProjectRuffConfig | undefined {\n let owner: PythonProjectRuffConfig | undefined;\n for (const config of configs) {\n if (\n (filePath === config.root || filePath.startsWith(`${config.root}/`)) &&\n (!owner || config.root.length > owner.root.length)\n ) {\n owner = config;\n }\n }\n return owner;\n}\n\n/**\n * Resolve the ruff settings to format a Python file with, mirroring what the\n * file's build enforces.\n *\n * Ruff's own config discovery never runs: settings are passed to the linter\n * directly rather than resolved from the file's location, which it never sees.\n * That also means a stray config above the workspace (or in the home directory)\n * can never be picked up.\n *\n * `config` is the file's nearest ruff config, whose rule selection is honoured\n * as-is. Without one, ruff would fall back to its own defaults, which change\n * between releases — 0.16 widened them from `E` and `F` to 36 rule prefixes — so\n * generation would apply fixes the project's build never asks for (eg `RUF022`\n * reordering `__all__`). Instead the project's own `lint.select` is pinned, so\n * generation enforces exactly what `lint` does and nothing more.\n *\n * `projectConfig` layers on the settings derived from the owning project rather\n * than declared under `[tool.ruff]`: `known-first-party` (the project's own\n * modules, from its wheel packages) keeps its imports in their own group, and\n * `target-version` (from its `requires-python`) matches the formatting the build\n * produces.\n */\nfunction resolveRuffOptions(\n config: RuffOptions | undefined,\n projectConfig?: PythonProjectRuffConfig,\n): RuffOptions {\n const lint: Record<string, unknown> = { ...config?.lint };\n // Pin the rule selection only when deferring to ruff's defaults would\n // otherwise apply rules the project's build does not enforce.\n if (!config) {\n lint.select = projectConfig?.select ?? DEFAULT_RUFF_SELECT;\n }\n if (projectConfig?.modules.length) {\n lint.isort = {\n ...(lint.isort as object | undefined),\n 'known-first-party': projectConfig.modules,\n };\n }\n return {\n ...config,\n ...(typeof projectConfig?.lineLength === 'number'\n ? { 'line-length': projectConfig.lineLength }\n : {}),\n ...(projectConfig?.targetVersion\n ? { 'target-version': projectConfig.targetVersion }\n : {}),\n lint,\n };\n}\n"],"names":["Biome","getProjects","createRequire","path","ruffFixAndFormat","tryReadToml","TS_VERSIONS","BIOME_WASM_VERSION","url","version","BIOME_TEST_OUTPUT_EXCLUDE","ROLLDOWN_CONFIG_BUNDLE_GLOB","BIOME_ROLLDOWN_CONFIG_BUNDLE_EXCLUDE","getDefaultBiomeConfig","tree","$schema","root","formatter","enabled","indentStyle","indentWidth","lineWidth","javascript","quoteStyle","trailingCommas","exists","resolver","experimentalPnpmCatalogs","css","linter","rules","preset","correctness","noUndeclaredDependencies","assist","actions","source","organizeImports","files","includes","overrides","BIOME_FORMATTABLE_EXTENSIONS","Set","isTsConfig","filePath","test","treeIgnoredPaths","WeakMap","normalizeTreePath","split","sep","join","replace","formatFilesInSubtree","dir","options","ignored","get","ignore","length","set","add","changedFiles","listChanges","filter","file","type","startsWith","has","pyFiles","endsWith","otherFiles","extname","pythonProjectConfigs","getPythonProjectRuffConfigs","content","toString","resolveRuffOptions","readRuffConfig","getOwningProjectRuffConfig","write","formatWithBiome","readBiomeConfig","config","read","JSON","parse","biome","projectKey","openProject","applyConfiguration","formatContent","dirname","name","ruff","tool","undefined","DEFAULT_RUFF_SELECT","requiresPythonToRuffTarget","requiresPython","min","match","matchAll","major","Number","minor","configs","project","values","pyproject","wheelPackages","hatch","build","targets","wheel","packages","modules","Array","isArray","pkg","map","lineLength","targetVersion","selected","lint","select","rule","push","owner","projectConfig","isort"],"mappings":"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"}
package/src/utils/init.js CHANGED
@@ -12,6 +12,7 @@ import { forDependencies } from "./declared-dependencies.js";
12
12
  import { addDependenciesToPackageJson, detectWorkspacePackageManager } from "./dependencies.js";
13
13
  import { getDefaultBiomeConfig } from "./format.js";
14
14
  import { describeGeneratorForCatalogue, generatorsJsonEntries } from "./generators.js";
15
+ import { updateGitIgnore } from "./git.js";
15
16
  import { configureMcpServers } from "./mcp.js";
16
17
  import { getNpmScope } from "./npm-scope.js";
17
18
  import { mergeTargetDefault, nxPluginMcpDependency, nxPluginSelfDependency } from "./nx.js";
@@ -41,10 +42,11 @@ export const DEFAULT_PARALLEL = 8;
41
42
  }
42
43
  ];
43
44
  // Built dependencies whose install scripts the generated workspace trusts.
44
- // `onlyBuiltDependencies` is the pnpm 10 key (silently ignored by pnpm 11);
45
- // pnpm 11 reads `allowBuilds` instead. Any dep NOT in this allowlist will
46
- // have its install scripts skipped with a warning — matching pnpm 10's
47
- // default behaviour. The user can opt-in later via `pnpm approve-builds`.
45
+ // `onlyBuiltDependencies` is the pnpm 10 key (silently ignored from pnpm 11
46
+ // onwards); pnpm 11 and above read `allowBuilds` instead. Any dep NOT in this
47
+ // allowlist will have its install scripts skipped with a warning — matching
48
+ // pnpm 10's default behaviour. The user can opt-in later via
49
+ // `pnpm approve-builds`.
48
50
  export const PNPM_BUILT_DEPENDENCIES = [
49
51
  '@swc/core',
50
52
  'esbuild',
@@ -101,6 +103,11 @@ export const PNPM_BUILT_DEPENDENCIES = [
101
103
  */ const setUpWorkspaces = (tree, catalogs)=>{
102
104
  if (detectWorkspacePackageManager(tree) === 'pnpm') {
103
105
  setUpPnpmWorkspace(tree, catalogs);
106
+ // pnpm creates these at the workspace root while it materialises packages.
107
+ updateGitIgnore(tree, '.', (patterns)=>[
108
+ ...patterns,
109
+ '_tmp_*'
110
+ ]);
104
111
  } else {
105
112
  updateJson(tree, 'package.json', (json)=>{
106
113
  // The `workspaces` field may be the object form ({ "packages": [...] })