@aws/nx-plugin 1.0.0-rc.94 → 1.0.0-rc.95
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.
- package/migrations.json +21 -1
- package/package.json +1 -1
- package/src/migrations/latest/agent-connection-pin-strands-peers/metadata.json +3 -0
- package/src/migrations/latest/agent-connection-pin-strands-peers/migration.d.ts +18 -0
- package/src/migrations/latest/agent-connection-pin-strands-peers/migration.js +38 -0
- package/src/migrations/latest/agent-connection-pin-strands-peers/migration.js.map +1 -0
- package/src/migrations/latest/ignore-package-manager-temp-files/metadata.json +3 -0
- package/src/migrations/latest/ignore-package-manager-temp-files/migration.d.ts +12 -0
- package/src/migrations/latest/ignore-package-manager-temp-files/migration.js +25 -0
- package/src/migrations/latest/ignore-package-manager-temp-files/migration.js.map +1 -0
- package/src/migrations/latest/rolldown-config-bundle-transient/metadata.json +3 -0
- package/src/migrations/latest/rolldown-config-bundle-transient/migration.d.ts +6 -0
- package/src/migrations/latest/rolldown-config-bundle-transient/migration.js +80 -0
- package/src/migrations/latest/rolldown-config-bundle-transient/migration.js.map +1 -0
- package/src/migrations/latest/shadcn-package-imports-exports/metadata.json +3 -0
- package/src/migrations/latest/shadcn-package-imports-exports/migration.d.ts +6 -0
- package/src/migrations/latest/shadcn-package-imports-exports/migration.js +184 -0
- package/src/migrations/latest/shadcn-package-imports-exports/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +5 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +4 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +4 -0
- package/src/ts/agent/gateway-connection/generator.d.ts +4 -0
- package/src/ts/agent/generator.d.ts +4 -0
- package/src/ts/agent/mcp-connection/generator.d.ts +4 -0
- package/src/ts/react-website/agui/generator.js +2 -1
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/ts/react-website/app/generator.js +2 -1
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/utils/agent-connection/agent-connection.d.ts +2 -0
- package/src/utils/agent-connection/agent-connection.js +11 -4
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/bundle/bundle.js +10 -0
- package/src/utils/bundle/bundle.js.map +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/alert.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/avatar.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/breadcrumb.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/button.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/card.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/input.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/separator.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/sheet.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/sidebar.tsx.template +8 -8
- package/src/utils/files/common/shadcn/src/components/ui/skeleton.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/spinner.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/textarea.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/tooltip.tsx.template +1 -1
- package/src/utils/files/shadcn/components.json.template +5 -5
- package/src/utils/format.d.ts +16 -0
- package/src/utils/format.js +15 -0
- package/src/utils/format.js.map +1 -1
- package/src/utils/init.js +11 -4
- package/src/utils/init.js.map +1 -1
- package/src/utils/pnpm-workspace.d.ts +5 -5
- package/src/utils/pnpm-workspace.js +5 -5
- package/src/utils/pnpm-workspace.js.map +1 -1
- package/src/utils/shared-shadcn.d.ts +9 -0
- package/src/utils/shared-shadcn.js +36 -26
- package/src/utils/shared-shadcn.js.map +1 -1
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import { applyGritQL } from "../ast.js";
|
|
6
6
|
import { forDependencies } from "../declared-dependencies.js";
|
|
7
7
|
import { addDependenciesToPackageJson } from "../dependencies.js";
|
|
8
|
+
import { ROLLDOWN_CONFIG_BUNDLE_GLOB } from "../format.js";
|
|
9
|
+
import { updateGitIgnore } from "../git.js";
|
|
8
10
|
import { addArtifactDependencyToTargets, addDependencyToTargetIfNotPresent, normalizeTargetKeyOrder } from "../nx.js";
|
|
9
11
|
import { getRelativePathToRoot } from "../paths.js";
|
|
10
12
|
import { LAMBDA_RUNTIME_VERSIONS, withVersions } from "../versions.js";
|
|
@@ -76,6 +78,14 @@ import { LAMBDA_RUNTIME_VERSIONS, withVersions } from "../versions.js";
|
|
|
76
78
|
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'ts'), project.root, {}, {
|
|
77
79
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
78
80
|
});
|
|
81
|
+
// Loading a TypeScript config bundles it to `rolldown.config.<hash>.js` beside
|
|
82
|
+
// itself, imports it, then unlinks it. Kept out of git so the transient file
|
|
83
|
+
// can never be committed, nor picked up by `license#sync`, which builds its
|
|
84
|
+
// candidate set from git-visible files.
|
|
85
|
+
updateGitIgnore(tree, project.root, (patterns)=>patterns.includes(ROLLDOWN_CONFIG_BUNDLE_GLOB) ? patterns : [
|
|
86
|
+
...patterns,
|
|
87
|
+
ROLLDOWN_CONFIG_BUNDLE_GLOB
|
|
88
|
+
]);
|
|
79
89
|
// Add the bundle target
|
|
80
90
|
if (!project.targets.bundle) {
|
|
81
91
|
project.targets.bundle = normalizeTargetKeyOrder({
|
|
@@ -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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"}
|
|
@@ -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 "
|
|
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",
|
|
@@ -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 "
|
|
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 "
|
|
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",
|
|
@@ -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 "
|
|
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 "
|
|
9
|
-
import { cn } from "
|
|
10
|
-
import { Button } from "
|
|
11
|
-
import { Input } from "
|
|
12
|
-
import { Separator } from "
|
|
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 "
|
|
20
|
-
import { Skeleton } from "
|
|
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 "
|
|
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
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
},
|
|
12
12
|
"iconLibrary": "lucide",
|
|
13
13
|
"aliases": {
|
|
14
|
-
"components": "
|
|
15
|
-
"utils": "
|
|
16
|
-
"hooks": "
|
|
17
|
-
"lib": "
|
|
18
|
-
"ui": "
|
|
14
|
+
"components": "#components",
|
|
15
|
+
"utils": "#lib/utils",
|
|
16
|
+
"hooks": "#hooks",
|
|
17
|
+
"lib": "#lib",
|
|
18
|
+
"ui": "#components/ui"
|
|
19
19
|
}
|
|
20
20
|
}
|
package/src/utils/format.d.ts
CHANGED
|
@@ -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
|
package/src/utils/format.js
CHANGED
|
@@ -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',
|
package/src/utils/format.js.map
CHANGED
|
@@ -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":"AAAA;;;CAGC,GAED,SAASA,KAAK,QAAQ,yBAAyB;AAC/C,SAASC,WAAW,QAAmB,aAAa;AACpD,SAASC,aAAa,QAAQ,SAAS;AACvC,OAAOC,UAAU,OAAO;AACxB,SAA2BC,gBAAgB,QAAQ,YAAY;AAC/D,SAASC,WAAW,QAAQ,YAAY;AACxC,SAASC,WAAW,QAAQ,gBAAgB;AAE5C;;;CAGC,GACD,OAAO,MAAMC,qBAA6BL,cAAc,YAAYM,GAAG,EACrE,qCACAC,OAAO,CAAC;AAEV;;;CAGC,GACD,OAAO,MAAMC,4BAA4B,kBAAkB;AAE3D;;;;;CAKC,GACD,OAAO,MAAMC,wBAAwB,CAACC,OAAgB,CAAA;QACpDC,SAAS,CAAC,4BAA4B,EAAEP,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC;QACnFQ,MAAM;QACNC,WAAW;YACTC,SAAS;YACTC,aAAa;YACbC,aAAa;YACbC,WAAW;QACb;QACAC,YAAY;YACVL,WAAW;gBACTM,YAAY;gBACZC,gBAAgB;YAClB;YACA,+EAA+E;YAC/E,GAAIV,KAAKW,MAAM,CAAC,yBACZ;gBAAEC,UAAU;oBAAEC,0BAA0B;gBAAK;YAAE,IAC/C,CAAC,CAAC;QACR;QACAC,KAAK;YACHX,WAAW;gBACTM,YAAY;YACd;YACAM,QAAQ;gBACNX,SAAS;YACX;QACF;QACAW,QAAQ;YACNX,SAAS;YACTY,OAAO;gBACLC,QAAQ;gBACRC,aAAa;oBACX,qEAAqE;oBACrE,wCAAwC;oBACxCC,0BAA0B;gBAC5B;YACF;QACF;QACAC,QAAQ;YACNC,SAAS;gBACPC,QAAQ;oBACNC,iBAAiB;gBACnB;YACF;QACF;QACAC,OAAO;YACLC,UAAU;gBACR;gBACA;gBACA;gBACA3B;gBACA;gBACA;gBACA;gBACA,kEAAkE;gBAClE,8DAA8D;gBAC9D;gBACA;gBACA;gBACA;gBACA;aACD;QACH;QACA,qEAAqE;QACrE,+EAA+E;QAC/E4B,WAAW;YACT;gBACED,UAAU;oBACR;oBACA;oBACA;iBACD;gBACDV,QAAQ;oBACNC,OAAO;wBACLE,aAAa;4BACXC,0BAA0B;wBAC5B;oBACF;gBACF;YACF;SACD;IACH,CAAA,EAAG;AAEH,MAAMQ,+BAA+B,IAAIC,IAAI;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,mEAAmE,GACnE,MAAMC,aAAa,CAACC,WAClB,6BAA6BC,IAAI,CAACD;AAapC;;;;;;;;CAQC,GACD,MAAME,mBAAmB,IAAIC;AAE7B;;;CAGC,GACD,MAAMC,oBAAoB,CAACJ,WACzBA,SAASK,KAAK,CAAC5C,KAAK6C,GAAG,EAAEC,IAAI,CAAC,KAAKC,OAAO,CAAC,SAAS;AAEtD;;;;CAIC,GACD,OAAO,eAAeC,qBACpBvC,IAAU,EACVwC,GAAY,EACZC,OAAqC;IAErC,IAAIC,UAAUV,iBAAiBW,GAAG,CAAC3C;IACnC,IAAIyC,SAASG,QAAQC,QAAQ;QAC3B,IAAI,CAACH,SAAS;YACZA,UAAU,IAAId;YACdI,iBAAiBc,GAAG,CAAC9C,MAAM0C;QAC7B;QACA,KAAK,MAAMZ,YAAYW,QAAQG,MAAM,CAAE;YACrCF,QAAQK,GAAG,CAACb,kBAAkBJ;QAChC;IACF;IACA,MAAMkB,eAAehD,KAClBiD,WAAW,GACXC,MAAM,CAAC,CAACC,OAASA,KAAKC,IAAI,KAAK,UAC/BF,MAAM,CAAC,CAACC,OAAUX,MAAMW,KAAK5D,IAAI,CAAC8D,UAAU,CAACb,OAAO,MACpDU,MAAM,CAAC,CAACC,OAAS,CAACT,SAASY,IAAIpB,kBAAkBiB,KAAK5D,IAAI;IAE7D,MAAMgE,UAAUP,aAAaE,MAAM,CAAC,CAACC,OAASA,KAAK5D,IAAI,CAACiE,QAAQ,CAAC;IACjE,MAAMC,aAAaT,aAAaE,MAAM,CACpC,CAACC,OACCxB,6BAA6B2B,GAAG,CAAC/D,KAAKmE,OAAO,CAACP,KAAK5D,IAAI,MACvD,oEAAoE;QACpE,yEAAyE;QACzE,oEAAoE;QACpE,yEAAyE;QACzE,wCAAwC;QACxC,CAACsC,WAAWsB,KAAK5D,IAAI;IAGzB,4EAA4E;IAC5E,8EAA8E;IAC9E,MAAMoE,uBAAuBJ,QAAQV,MAAM,GACvCe,4BAA4B5D,QAC5B,EAAE;IAEN,0DAA0D;IAC1D,KAAK,MAAMmD,QAAQI,QAAS;QAC1B,IAAI;YACF,MAAMM,UAAUrE,iBACd2D,KAAKU,OAAO,CAACC,QAAQ,CAAC,UACtBX,KAAK5D,IAAI,EACTwE,mBACEC,eAAehE,MAAMmD,KAAK5D,IAAI,GAC9B0E,2BAA2Bd,KAAK5D,IAAI,EAAEoE;YAG1C3D,KAAKkE,KAAK,CAACf,KAAK5D,IAAI,EAAEsE;QACxB,EAAE,OAAM;QACN,yCAAyC;QAC3C;IACF;IAEA,IAAIJ,WAAWZ,MAAM,KAAK,GAAG;IAE7BsB,gBAAgBnE,MAAMyD;AACxB;AAEA;;;;;;;;CAQC,GACD,SAASW,gBAAgBpE,IAAU;IACjC,MAAMqE,SAASrE,KAAKsE,IAAI,CAAC,cAAc;IACvC,IAAID,QAAQ;QACV,IAAI;YACF,OAAOE,KAAKC,KAAK,CAACH;QACpB,EAAE,OAAM;QACN,wDAAwD;QAC1D;IACF;IACA,OAAOtE,sBAAsBC;AAC/B;AAEA;;;;;;;;;;CAUC,GACD,SAASmE,gBACPnE,IAAU,EACVwB,KAAiD;IAEjD,IAAI;QACF,MAAMiD,QAAQ,IAAIrF;QAClB,MAAM,EAAEsF,UAAU,EAAE,GAAGD,MAAME,WAAW;QACxCF,MAAMG,kBAAkB,CAACF,YAAYN,gBAAgBpE;QAErD,KAAK,MAAMmD,QAAQ3B,MAAO;YACxB,IAAI;gBACF,MAAM,EAAEqC,OAAO,EAAE,GAAGY,MAAMI,aAAa,CACrCH,YACAvB,KAAKU,OAAO,EAAEC,SAAS,YAAY,IACnC;oBAAEhC,UAAUqB,KAAK5D,IAAI;gBAAC;gBAExBS,KAAKkE,KAAK,CAACf,KAAK5D,IAAI,EAAEsE;YACxB,EAAE,OAAM;YACN,uDAAuD;YACzD;QACF;IACF,EAAE,OAAM;IACN,oCAAoC;IACtC;AACF;AAEA;;;;;;;;;;;;;;;CAeC,GACD,SAASG,eAAehE,IAAU,EAAE8B,QAAgB;IAClD,IAAIU,MAAMjD,KAAKuF,OAAO,CAAChD;IACvB,MAAO,KAAM;QACX,KAAK,MAAMiD,QAAQ;YAAC;YAAc;SAAY,CAAE;YAC9C,MAAMV,SAAS5E,YAAYO,MAAMT,KAAK8C,IAAI,CAACG,KAAKuC;YAChD,IAAIV,QAAQ;gBACV,OAAOA;YACT;QACF;QACA,MAAMW,OAAQvF,YAAYO,MAAMT,KAAK8C,IAAI,CAACG,KAAK,oBAC3CyC,MAAMD;QACV,IAAIA,MAAM;YACR,OAAOA;QACT;QACA,uDAAuD;QACvD,IAAIxC,QAAQ,OAAOA,QAAQ,MAAMA,QAAQjD,KAAKuF,OAAO,CAACtC,MAAM;YAC1D,OAAO0C;QACT;QACA1C,MAAMjD,KAAKuF,OAAO,CAACtC;IACrB;AACF;AAEA;;;;;CAKC,GACD,MAAM2C,sBAAsB;IAAC;IAAK;IAAK;IAAM;IAAK;IAAO;CAAI;AAmB7D;;;;CAIC,GACD,OAAO,MAAMC,6BAA6B,CACxCC;IAEA,IAAI,OAAOA,mBAAmB,UAAU;QACtC,OAAOH;IACT;IACA,IAAII;IACJ,KAAK,MAAMC,SAASF,eAAeG,QAAQ,CAAC,iBAAkB;QAC5D,MAAMC,QAAQC,OAAOH,KAAK,CAAC,EAAE;QAC7B,MAAMI,QAAQD,OAAOH,KAAK,CAAC,EAAE;QAC7B,IACE,CAACD,OACDG,QAAQH,IAAIG,KAAK,IAChBA,UAAUH,IAAIG,KAAK,IAAIE,QAAQL,IAAIK,KAAK,EACzC;YACAL,MAAM;gBAAEG;gBAAOE;YAAM;QACvB;IACF;IACA,OAAOL,MAAM,CAAC,EAAE,EAAEA,IAAIG,KAAK,GAAGH,IAAIK,KAAK,EAAE,GAAGT;AAC9C,EAAE;AAEF;;;;;CAKC,GACD,SAAStB,4BAA4B5D,IAAU;IAC7C,MAAM4F,UAAqC,EAAE;IAE7C,KAAK,MAAMC,WAAWxG,YAAYW,MAAM8F,MAAM,GAAI;QAChD,4EAA4E;QAC5E,+BAA+B;QAC/B,MAAMC,YAAYtG,YAChBO,MACAT,KAAK8C,IAAI,CAACwD,QAAQ3F,IAAI,EAAE;QAE1B,IAAI,CAAC6F,WAAW;YACd;QACF;QACA,MAAMC,gBACJD,WAAWd,MAAMgB,OAAOC,OAAOC,SAASC,OAAOC;QACjD,qEAAqE;QACrE,oCAAoC;QACpC,MAAMC,UAAUC,MAAMC,OAAO,CAACR,iBAC1BA,cACG9C,MAAM,CAAC,CAACuD,MAAuB,OAAOA,QAAQ,YAAY,CAAC,CAACA,KAC5DC,GAAG,CAAC,CAACD,MAAQA,IAAItE,KAAK,CAAC,IAAI,CAAC,EAAE,IACjC,EAAE;QACN,MAAMwE,aAAsBZ,WAAWd,MAAMD,MAAM,CAAC,cAAc;QAClE,MAAM4B,gBAAgBxB,2BACpBW,WAAWF,SAAS,CAAC,kBAAkB;QAEzC,MAAMgB,WAAoBd,WAAWd,MAAMD,MAAM8B,MAAMC;QACvD,MAAMA,SAASR,MAAMC,OAAO,CAACK,YACzBA,SAAS3D,MAAM,CACb,CAAC8D,OAAyB,OAAOA,SAAS,YAAY,CAAC,CAACA,QAE1D9B;QACJ,IACEoB,QAAQzD,MAAM,IACd,OAAO8D,eAAe,YACtBC,iBACAG,QAAQlE,QACR;YACA+C,QAAQqB,IAAI,CAAC;gBACX/G,MAAM2F,QAAQ3F,IAAI,CAACiC,KAAK,CAAC5C,KAAK6C,GAAG,EAAEC,IAAI,CAAC;gBACxCiE;gBACAK,YAAY,OAAOA,eAAe,WAAWA,aAAazB;gBAC1D0B;gBACAG,QAAQA,QAAQlE,SAASkE,SAAS7B;YACpC;QACF;IACF;IAEA,OAAOU;AACT;AAEA;;;;;;;CAOC,GACD,SAAS3B,2BACPnC,QAAgB,EAChB8D,OAAkC;IAElC,IAAIsB;IACJ,KAAK,MAAM7C,UAAUuB,QAAS;QAC5B,IACE,AAAC9D,CAAAA,aAAauC,OAAOnE,IAAI,IAAI4B,SAASuB,UAAU,CAAC,GAAGgB,OAAOnE,IAAI,CAAC,CAAC,CAAC,CAAA,KACjE,CAAA,CAACgH,SAAS7C,OAAOnE,IAAI,CAAC2C,MAAM,GAAGqE,MAAMhH,IAAI,CAAC2C,MAAM,AAAD,GAChD;YACAqE,QAAQ7C;QACV;IACF;IACA,OAAO6C;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,SAASnD,mBACPM,MAA+B,EAC/B8C,aAAuC;IAEvC,MAAML,OAAgC;QAAE,GAAGzC,QAAQyC,IAAI;IAAC;IACxD,sEAAsE;IACtE,8DAA8D;IAC9D,IAAI,CAACzC,QAAQ;QACXyC,KAAKC,MAAM,GAAGI,eAAeJ,UAAU5B;IACzC;IACA,IAAIgC,eAAeb,QAAQzD,QAAQ;QACjCiE,KAAKM,KAAK,GAAG;YACX,GAAIN,KAAKM,KAAK;YACd,qBAAqBD,cAAcb,OAAO;QAC5C;IACF;IACA,OAAO;QACL,GAAGjC,MAAM;QACT,GAAI,OAAO8C,eAAeR,eAAe,WACrC;YAAE,eAAeQ,cAAcR,UAAU;QAAC,IAC1C,CAAC,CAAC;QACN,GAAIQ,eAAeP,gBACf;YAAE,kBAAkBO,cAAcP,aAAa;QAAC,IAChD,CAAC,CAAC;QACNE;IACF;AACF"}
|
|
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":"AAAA;;;CAGC,GAED,SAASA,KAAK,QAAQ,yBAAyB;AAC/C,SAASC,WAAW,QAAmB,aAAa;AACpD,SAASC,aAAa,QAAQ,SAAS;AACvC,OAAOC,UAAU,OAAO;AACxB,SAA2BC,gBAAgB,QAAQ,YAAY;AAC/D,SAASC,WAAW,QAAQ,YAAY;AACxC,SAASC,WAAW,QAAQ,gBAAgB;AAE5C;;;CAGC,GACD,OAAO,MAAMC,qBAA6BL,cAAc,YAAYM,GAAG,EACrE,qCACAC,OAAO,CAAC;AAEV;;;CAGC,GACD,OAAO,MAAMC,4BAA4B,kBAAkB;AAE3D;;;;;;;;;;;;CAYC,GACD,OAAO,MAAMC,8BAA8B,2BAA2B;AAEtE,4EAA4E,GAC5E,OAAO,MAAMC,uCAAuC,CAAC,CAAC,EAAED,6BAA6B,CAAC;AAEtF;;;;;CAKC,GACD,OAAO,MAAME,wBAAwB,CAACC,OAAgB,CAAA;QACpDC,SAAS,CAAC,4BAA4B,EAAET,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC;QACnFU,MAAM;QACNC,WAAW;YACTC,SAAS;YACTC,aAAa;YACbC,aAAa;YACbC,WAAW;QACb;QACAC,YAAY;YACVL,WAAW;gBACTM,YAAY;gBACZC,gBAAgB;YAClB;YACA,+EAA+E;YAC/E,GAAIV,KAAKW,MAAM,CAAC,yBACZ;gBAAEC,UAAU;oBAAEC,0BAA0B;gBAAK;YAAE,IAC/C,CAAC,CAAC;QACR;QACAC,KAAK;YACHX,WAAW;gBACTM,YAAY;YACd;YACAM,QAAQ;gBACNX,SAAS;YACX;QACF;QACAW,QAAQ;YACNX,SAAS;YACTY,OAAO;gBACLC,QAAQ;gBACRC,aAAa;oBACX,qEAAqE;oBACrE,wCAAwC;oBACxCC,0BAA0B;gBAC5B;YACF;QACF;QACAC,QAAQ;YACNC,SAAS;gBACPC,QAAQ;oBACNC,iBAAiB;gBACnB;YACF;QACF;QACAC,OAAO;YACLC,UAAU;gBACR;gBACA;gBACA;gBACA7B;gBACAE;gBACA;gBACA;gBACA;gBACA,kEAAkE;gBAClE,8DAA8D;gBAC9D;gBACA;gBACA;gBACA;gBACA;aACD;QACH;QACA,qEAAqE;QACrE,+EAA+E;QAC/E4B,WAAW;YACT;gBACED,UAAU;oBACR;oBACA;oBACA;iBACD;gBACDV,QAAQ;oBACNC,OAAO;wBACLE,aAAa;4BACXC,0BAA0B;wBAC5B;oBACF;gBACF;YACF;SACD;IACH,CAAA,EAAG;AAEH,MAAMQ,+BAA+B,IAAIC,IAAI;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,mEAAmE,GACnE,MAAMC,aAAa,CAACC,WAClB,6BAA6BC,IAAI,CAACD;AAapC;;;;;;;;CAQC,GACD,MAAME,mBAAmB,IAAIC;AAE7B;;;CAGC,GACD,MAAMC,oBAAoB,CAACJ,WACzBA,SAASK,KAAK,CAAC9C,KAAK+C,GAAG,EAAEC,IAAI,CAAC,KAAKC,OAAO,CAAC,SAAS;AAEtD;;;;CAIC,GACD,OAAO,eAAeC,qBACpBvC,IAAU,EACVwC,GAAY,EACZC,OAAqC;IAErC,IAAIC,UAAUV,iBAAiBW,GAAG,CAAC3C;IACnC,IAAIyC,SAASG,QAAQC,QAAQ;QAC3B,IAAI,CAACH,SAAS;YACZA,UAAU,IAAId;YACdI,iBAAiBc,GAAG,CAAC9C,MAAM0C;QAC7B;QACA,KAAK,MAAMZ,YAAYW,QAAQG,MAAM,CAAE;YACrCF,QAAQK,GAAG,CAACb,kBAAkBJ;QAChC;IACF;IACA,MAAMkB,eAAehD,KAClBiD,WAAW,GACXC,MAAM,CAAC,CAACC,OAASA,KAAKC,IAAI,KAAK,UAC/BF,MAAM,CAAC,CAACC,OAAUX,MAAMW,KAAK9D,IAAI,CAACgE,UAAU,CAACb,OAAO,MACpDU,MAAM,CAAC,CAACC,OAAS,CAACT,SAASY,IAAIpB,kBAAkBiB,KAAK9D,IAAI;IAE7D,MAAMkE,UAAUP,aAAaE,MAAM,CAAC,CAACC,OAASA,KAAK9D,IAAI,CAACmE,QAAQ,CAAC;IACjE,MAAMC,aAAaT,aAAaE,MAAM,CACpC,CAACC,OACCxB,6BAA6B2B,GAAG,CAACjE,KAAKqE,OAAO,CAACP,KAAK9D,IAAI,MACvD,oEAAoE;QACpE,yEAAyE;QACzE,oEAAoE;QACpE,yEAAyE;QACzE,wCAAwC;QACxC,CAACwC,WAAWsB,KAAK9D,IAAI;IAGzB,4EAA4E;IAC5E,8EAA8E;IAC9E,MAAMsE,uBAAuBJ,QAAQV,MAAM,GACvCe,4BAA4B5D,QAC5B,EAAE;IAEN,0DAA0D;IAC1D,KAAK,MAAMmD,QAAQI,QAAS;QAC1B,IAAI;YACF,MAAMM,UAAUvE,iBACd6D,KAAKU,OAAO,CAACC,QAAQ,CAAC,UACtBX,KAAK9D,IAAI,EACT0E,mBACEC,eAAehE,MAAMmD,KAAK9D,IAAI,GAC9B4E,2BAA2Bd,KAAK9D,IAAI,EAAEsE;YAG1C3D,KAAKkE,KAAK,CAACf,KAAK9D,IAAI,EAAEwE;QACxB,EAAE,OAAM;QACN,yCAAyC;QAC3C;IACF;IAEA,IAAIJ,WAAWZ,MAAM,KAAK,GAAG;IAE7BsB,gBAAgBnE,MAAMyD;AACxB;AAEA;;;;;;;;CAQC,GACD,SAASW,gBAAgBpE,IAAU;IACjC,MAAMqE,SAASrE,KAAKsE,IAAI,CAAC,cAAc;IACvC,IAAID,QAAQ;QACV,IAAI;YACF,OAAOE,KAAKC,KAAK,CAACH;QACpB,EAAE,OAAM;QACN,wDAAwD;QAC1D;IACF;IACA,OAAOtE,sBAAsBC;AAC/B;AAEA;;;;;;;;;;CAUC,GACD,SAASmE,gBACPnE,IAAU,EACVwB,KAAiD;IAEjD,IAAI;QACF,MAAMiD,QAAQ,IAAIvF;QAClB,MAAM,EAAEwF,UAAU,EAAE,GAAGD,MAAME,WAAW;QACxCF,MAAMG,kBAAkB,CAACF,YAAYN,gBAAgBpE;QAErD,KAAK,MAAMmD,QAAQ3B,MAAO;YACxB,IAAI;gBACF,MAAM,EAAEqC,OAAO,EAAE,GAAGY,MAAMI,aAAa,CACrCH,YACAvB,KAAKU,OAAO,EAAEC,SAAS,YAAY,IACnC;oBAAEhC,UAAUqB,KAAK9D,IAAI;gBAAC;gBAExBW,KAAKkE,KAAK,CAACf,KAAK9D,IAAI,EAAEwE;YACxB,EAAE,OAAM;YACN,uDAAuD;YACzD;QACF;IACF,EAAE,OAAM;IACN,oCAAoC;IACtC;AACF;AAEA;;;;;;;;;;;;;;;CAeC,GACD,SAASG,eAAehE,IAAU,EAAE8B,QAAgB;IAClD,IAAIU,MAAMnD,KAAKyF,OAAO,CAAChD;IACvB,MAAO,KAAM;QACX,KAAK,MAAMiD,QAAQ;YAAC;YAAc;SAAY,CAAE;YAC9C,MAAMV,SAAS9E,YAAYS,MAAMX,KAAKgD,IAAI,CAACG,KAAKuC;YAChD,IAAIV,QAAQ;gBACV,OAAOA;YACT;QACF;QACA,MAAMW,OAAQzF,YAAYS,MAAMX,KAAKgD,IAAI,CAACG,KAAK,oBAC3CyC,MAAMD;QACV,IAAIA,MAAM;YACR,OAAOA;QACT;QACA,uDAAuD;QACvD,IAAIxC,QAAQ,OAAOA,QAAQ,MAAMA,QAAQnD,KAAKyF,OAAO,CAACtC,MAAM;YAC1D,OAAO0C;QACT;QACA1C,MAAMnD,KAAKyF,OAAO,CAACtC;IACrB;AACF;AAEA;;;;;CAKC,GACD,MAAM2C,sBAAsB;IAAC;IAAK;IAAK;IAAM;IAAK;IAAO;CAAI;AAmB7D;;;;CAIC,GACD,OAAO,MAAMC,6BAA6B,CACxCC;IAEA,IAAI,OAAOA,mBAAmB,UAAU;QACtC,OAAOH;IACT;IACA,IAAII;IACJ,KAAK,MAAMC,SAASF,eAAeG,QAAQ,CAAC,iBAAkB;QAC5D,MAAMC,QAAQC,OAAOH,KAAK,CAAC,EAAE;QAC7B,MAAMI,QAAQD,OAAOH,KAAK,CAAC,EAAE;QAC7B,IACE,CAACD,OACDG,QAAQH,IAAIG,KAAK,IAChBA,UAAUH,IAAIG,KAAK,IAAIE,QAAQL,IAAIK,KAAK,EACzC;YACAL,MAAM;gBAAEG;gBAAOE;YAAM;QACvB;IACF;IACA,OAAOL,MAAM,CAAC,EAAE,EAAEA,IAAIG,KAAK,GAAGH,IAAIK,KAAK,EAAE,GAAGT;AAC9C,EAAE;AAEF;;;;;CAKC,GACD,SAAStB,4BAA4B5D,IAAU;IAC7C,MAAM4F,UAAqC,EAAE;IAE7C,KAAK,MAAMC,WAAW1G,YAAYa,MAAM8F,MAAM,GAAI;QAChD,4EAA4E;QAC5E,+BAA+B;QAC/B,MAAMC,YAAYxG,YAChBS,MACAX,KAAKgD,IAAI,CAACwD,QAAQ3F,IAAI,EAAE;QAE1B,IAAI,CAAC6F,WAAW;YACd;QACF;QACA,MAAMC,gBACJD,WAAWd,MAAMgB,OAAOC,OAAOC,SAASC,OAAOC;QACjD,qEAAqE;QACrE,oCAAoC;QACpC,MAAMC,UAAUC,MAAMC,OAAO,CAACR,iBAC1BA,cACG9C,MAAM,CAAC,CAACuD,MAAuB,OAAOA,QAAQ,YAAY,CAAC,CAACA,KAC5DC,GAAG,CAAC,CAACD,MAAQA,IAAItE,KAAK,CAAC,IAAI,CAAC,EAAE,IACjC,EAAE;QACN,MAAMwE,aAAsBZ,WAAWd,MAAMD,MAAM,CAAC,cAAc;QAClE,MAAM4B,gBAAgBxB,2BACpBW,WAAWF,SAAS,CAAC,kBAAkB;QAEzC,MAAMgB,WAAoBd,WAAWd,MAAMD,MAAM8B,MAAMC;QACvD,MAAMA,SAASR,MAAMC,OAAO,CAACK,YACzBA,SAAS3D,MAAM,CACb,CAAC8D,OAAyB,OAAOA,SAAS,YAAY,CAAC,CAACA,QAE1D9B;QACJ,IACEoB,QAAQzD,MAAM,IACd,OAAO8D,eAAe,YACtBC,iBACAG,QAAQlE,QACR;YACA+C,QAAQqB,IAAI,CAAC;gBACX/G,MAAM2F,QAAQ3F,IAAI,CAACiC,KAAK,CAAC9C,KAAK+C,GAAG,EAAEC,IAAI,CAAC;gBACxCiE;gBACAK,YAAY,OAAOA,eAAe,WAAWA,aAAazB;gBAC1D0B;gBACAG,QAAQA,QAAQlE,SAASkE,SAAS7B;YACpC;QACF;IACF;IAEA,OAAOU;AACT;AAEA;;;;;;;CAOC,GACD,SAAS3B,2BACPnC,QAAgB,EAChB8D,OAAkC;IAElC,IAAIsB;IACJ,KAAK,MAAM7C,UAAUuB,QAAS;QAC5B,IACE,AAAC9D,CAAAA,aAAauC,OAAOnE,IAAI,IAAI4B,SAASuB,UAAU,CAAC,GAAGgB,OAAOnE,IAAI,CAAC,CAAC,CAAC,CAAA,KACjE,CAAA,CAACgH,SAAS7C,OAAOnE,IAAI,CAAC2C,MAAM,GAAGqE,MAAMhH,IAAI,CAAC2C,MAAM,AAAD,GAChD;YACAqE,QAAQ7C;QACV;IACF;IACA,OAAO6C;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,SAASnD,mBACPM,MAA+B,EAC/B8C,aAAuC;IAEvC,MAAML,OAAgC;QAAE,GAAGzC,QAAQyC,IAAI;IAAC;IACxD,sEAAsE;IACtE,8DAA8D;IAC9D,IAAI,CAACzC,QAAQ;QACXyC,KAAKC,MAAM,GAAGI,eAAeJ,UAAU5B;IACzC;IACA,IAAIgC,eAAeb,QAAQzD,QAAQ;QACjCiE,KAAKM,KAAK,GAAG;YACX,GAAIN,KAAKM,KAAK;YACd,qBAAqBD,cAAcb,OAAO;QAC5C;IACF;IACA,OAAO;QACL,GAAGjC,MAAM;QACT,GAAI,OAAO8C,eAAeR,eAAe,WACrC;YAAE,eAAeQ,cAAcR,UAAU;QAAC,IAC1C,CAAC,CAAC;QACN,GAAIQ,eAAeP,gBACf;YAAE,kBAAkBO,cAAcP,aAAa;QAAC,IAChD,CAAC,CAAC;QACNE;IACF;AACF"}
|
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
|
|
45
|
-
// pnpm 11
|
|
46
|
-
// have its install scripts skipped with a warning — matching
|
|
47
|
-
// default behaviour. The user can opt-in later via
|
|
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": [...] })
|
package/src/utils/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/init.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n readNxJson,\n type Tree,\n updateJson,\n updateNxJson,\n} from '@nx/devkit';\nimport { initGenerator } from '@nx/js';\nimport { readFileSync } from 'fs';\nimport yaml from 'js-yaml';\nimport { SYNC_GENERATOR_NAME as TS_SYNC_GENERATOR_NAME } from '../ts/sync/generator.js';\nimport { BASE_TSCONFIG_COMPILER_OPTIONS } from './base-tsconfig.js';\nimport {\n ensureAwsNxPluginConfig,\n updateAwsNxPluginConfig,\n} from './config/utils.js';\nimport { type Containers, inferContainers } from './containers.js';\nimport {\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from './declared-dependencies.js';\nimport {\n addDependenciesToPackageJson,\n detectWorkspacePackageManager,\n} from './dependencies.js';\nimport { getDefaultBiomeConfig } from './format.js';\nimport {\n describeGeneratorForCatalogue,\n generatorsJsonEntries,\n} from './generators.js';\nimport type { Iac } from './iac.js';\nimport { configureMcpServers } from './mcp.js';\nimport { getNpmScope } from './npm-scope.js';\nimport {\n mergeTargetDefault,\n nxPluginMcpDependency,\n nxPluginSelfDependency,\n} from './nx.js';\nimport { getPackageManagerDisplayCommands } from './pkg-manager.js';\nimport { workspaceGlobs } from './project-package-json.js';\nimport { type ITsDepVersion, withVersions } from './versions.js';\n\nconst WORKSPACES = ['packages/*'];\nconst NX_TYPESCRIPT_SYNC_GENERATOR = '@nx/js:typescript-sync';\n\nexport const DEFAULT_PARALLEL = 8;\n\n/** Dependencies a caller must declare to apply the workspace init. */\nexport const INIT_DEPENDENCIES = [\n { name: 'nx' },\n { name: '@nx/js' },\n { name: '@nx/workspace' },\n { name: 'typescript' },\n { name: '@biomejs/biome' },\n] as const satisfies readonly { name: ITsDepVersion }[];\n\n// Built dependencies whose install scripts the generated workspace trusts.\n// `onlyBuiltDependencies` is the pnpm 10 key (silently ignored by pnpm 11);\n// pnpm 11 reads `allowBuilds` instead. Any dep NOT in this allowlist will\n// have its install scripts skipped with a warning — matching pnpm 10's\n// default behaviour. The user can opt-in later via `pnpm approve-builds`.\nexport const PNPM_BUILT_DEPENDENCIES = ['@swc/core', 'esbuild', 'nx', 'sharp'];\n\n/**\n * Options controlling how the workspace is initialised. These mirror the\n * preset schema so a workspace created via the preset and one initialised via\n * the `init` generator end up in the same shape.\n */\nexport interface ApplyWorkspaceInitOptions {\n /** The IaC provider to record in the plugin config. */\n readonly iac: Iac;\n /**\n * The container engine to record. `undefined`/`'infer'` picks docker when\n * installed, else finch.\n */\n readonly containers?: Containers | 'infer';\n /** Whether to configure MCP servers for coding agents. Defaults to true. */\n readonly mcp?: boolean;\n /**\n * How to treat the generated workspace README. The preset owns the README of\n * a greenfield workspace (`Overwrite`); the `init` generator must not clobber\n * an existing workspace's README (`KeepExisting`, the default).\n */\n readonly readmeOverwriteStrategy?: OverwriteStrategy;\n /**\n * Whether to overwrite root package.json scripts that already exist. The\n * preset owns a greenfield workspace's scripts (`true`); the `init`\n * generator must not clobber an existing workspace's scripts (`false`,\n * the default) — it only adds the convenience scripts that are absent.\n */\n readonly overwriteScripts?: boolean;\n /**\n * Whether generators use the package manager's dependency catalog. On pnpm\n * this also sets `catalogMode: strict` so `pnpm add` records new deps in the\n * catalog. Defaults to true.\n */\n readonly catalogs?: boolean;\n}\n\n/**\n * Add or repair the pnpm `allowBuilds` / `onlyBuiltDependencies` allowlist for\n * the workspace's `packages` globs, without clobbering any packages the user\n * has already declared.\n *\n * A workspace not created by the preset commonly has either no\n * `pnpm-workspace.yaml`, one missing the `packages` globs, or one carrying the\n * broken `set this to true or false` placeholder pnpm writes when it skips a\n * build script. This makes the file self-consistent so the first generator's\n * install doesn't fail with `ERR_PNPM_IGNORED_BUILDS`.\n */\nconst setUpPnpmWorkspace = (tree: Tree, catalogs: boolean) => {\n const existing = tree.exists('pnpm-workspace.yaml')\n ? ((yaml.load(tree.read('pnpm-workspace.yaml', 'utf-8') ?? '') as Record<\n string,\n unknown\n >) ?? {})\n : {};\n\n // Preserve any packages globs the user already has, ensuring ours are present.\n const packages = Array.from(\n new Set([...((existing.packages as string[]) ?? []), ...WORKSPACES]),\n );\n\n const allowBuilds = {\n ...(typeof existing.allowBuilds === 'object' && existing.allowBuilds\n ? (existing.allowBuilds as Record<string, unknown>)\n : {}),\n // Overwrite any non-boolean (e.g. the \"set this to true or false\"\n // placeholder) with an explicit true for the deps we trust.\n ...Object.fromEntries(PNPM_BUILT_DEPENDENCIES.map((dep) => [dep, true])),\n };\n\n // `strict` makes `pnpm add` record new deps in the catalog; it only gates\n // that flow, so pre-declared direct ranges (e.g. tslib) still install.\n // Preserve an explicit user choice.\n const catalogMode = catalogs\n ? (existing.catalogMode ?? 'strict')\n : existing.catalogMode;\n\n tree.write(\n 'pnpm-workspace.yaml',\n yaml.dump(\n {\n ...existing,\n packages,\n allowBuilds,\n onlyBuiltDependencies: PNPM_BUILT_DEPENDENCIES,\n ...(catalogMode ? { catalogMode } : {}),\n },\n { quotingType: \"'\" },\n ),\n );\n};\n\n/**\n * Configure the workspace's package manager for a monorepo layout.\n *\n * pnpm workspaces are declared in `pnpm-workspace.yaml`; every other package\n * manager reads the `workspaces` field of the root `package.json`.\n */\nconst setUpWorkspaces = (tree: Tree, catalogs: boolean) => {\n if (detectWorkspacePackageManager(tree) === 'pnpm') {\n setUpPnpmWorkspace(tree, catalogs);\n } else {\n updateJson(tree, 'package.json', (json) => {\n // The `workspaces` field may be the object form ({ \"packages\": [...] })\n // accepted by yarn and bun — extend the globs while preserving the form.\n const globs = Array.from(\n new Set([...workspaceGlobs(json.workspaces), ...WORKSPACES]),\n );\n return {\n ...json,\n workspaces:\n json.workspaces !== undefined && !Array.isArray(json.workspaces)\n ? { ...json.workspaces, packages: globs }\n : globs,\n };\n });\n }\n};\n\n/**\n * Ensure the workspace has a `tsconfig.base.json`.\n *\n * `@nx/js` `initGenerator` (with `addTsPlugin`) normally creates this, but it\n * short-circuits when the workspace already has a root `tsconfig.json` — in\n * which case no base file is written and the next project generator fails with\n * `Cannot find tsconfig.base.json`. So we create a compatible one when it's\n * absent. An existing base is left untouched: the user may have tuned it, and\n * rewriting shared compiler options can break other projects (see the\n * \"add to an existing workspace\" guide).\n */\nconst ensureBaseTsConfig = (tree: Tree) => {\n if (tree.exists('tsconfig.base.json')) {\n return;\n }\n tree.write(\n 'tsconfig.base.json',\n JSON.stringify(\n {\n compilerOptions: {\n ...BASE_TSCONFIG_COMPILER_OPTIONS,\n customConditions: [getNpmScope(tree)],\n },\n },\n null,\n 2,\n ),\n );\n};\n\n/**\n * Ensure the workspace has a root `tsconfig.json`.\n *\n * Nx's `@nx/js:typescript-sync` generator hard-fails with\n * `Missing root \"tsconfig.json\"` when it's absent. The plugin's TypeScript\n * projects reference each other via this file, so we guarantee a minimal one\n * exists (sync populates its `references`).\n */\nconst ensureRootTsConfig = (tree: Tree) => {\n if (tree.exists('tsconfig.json')) {\n return;\n }\n tree.write(\n 'tsconfig.json',\n JSON.stringify(\n {\n extends: './tsconfig.base.json',\n files: [],\n references: [],\n },\n null,\n 2,\n ),\n );\n};\n\n/**\n * Transform an Nx workspace into one ready to run `@aws/nx-plugin` generators.\n *\n * This is the deterministic core shared by the workspace preset and the `init`\n * generator. It is safe to re-run: every step is idempotent (config merges,\n * keyed nx.json / package.json entries, create-if-missing files), so running\n * it against an already-initialised workspace is a no-op.\n *\n * It preserves the workspace's module format: the root package.json `type`\n * field is owned by the preset (written from its `--module` option) and left\n * untouched here. It does NOT rewrite an existing `tsconfig.base.json`'s\n * compiler options, migrate a workspace's package manager, or restructure\n * existing projects — those are decisions for the user (see the \"add to an\n * existing workspace\" guide).\n */\nexport const applyWorkspaceInit = async <const D extends DependencyDeclaration>(\n tree: Tree,\n {\n iac,\n containers,\n mcp,\n readmeOverwriteStrategy = OverwriteStrategy.KeepExisting,\n overwriteScripts = false,\n catalogs = true,\n }: ApplyWorkspaceInitOptions,\n declaration: D & MustDeclare<typeof INIT_DEPENDENCIES, D>,\n) => {\n const resolvedContainers =\n !containers || containers === 'infer' ? inferContainers() : containers;\n\n // The catalogs flag is written explicitly (even when true) so the workspace\n // records its dependency-management choice.\n await ensureAwsNxPluginConfig(tree);\n await updateAwsNxPluginConfig(tree, {\n iac: { provider: iac },\n containers: { engine: resolvedContainers },\n packageManager: { catalogs },\n });\n\n // Set up the TypeScript plugin, base tsconfig, formatter etc. `@nx/js`\n // creates `tsconfig.base.json` when absent, but skips it when a root\n // `tsconfig.json` already exists — so we ensure both explicitly below.\n await initGenerator(tree, {\n formatter: 'none',\n addTsPlugin: true,\n });\n\n ensureBaseTsConfig(tree);\n ensureRootTsConfig(tree);\n\n setUpWorkspaces(tree, catalogs);\n\n const nxJson = readNxJson(tree);\n updateNxJson(tree, {\n ...nxJson,\n // Preserve an explicit analytics choice in an existing workspace.\n analytics: (nxJson as { analytics?: boolean }).analytics ?? false,\n parallel: nxJson.parallel ?? DEFAULT_PARALLEL,\n targetDefaults: {\n ...nxJson.targetDefaults,\n compile: mergeTargetDefault(nxJson.targetDefaults?.compile, (base) => ({\n ...base,\n syncGenerators: [\n ...(base.syncGenerators ?? []).filter(\n (g) =>\n ![TS_SYNC_GENERATOR_NAME, NX_TYPESCRIPT_SYNC_GENERATOR].includes(\n g,\n ),\n ),\n NX_TYPESCRIPT_SYNC_GENERATOR,\n TS_SYNC_GENERATOR_NAME,\n ],\n })),\n },\n });\n\n const CONVENIENCE_SCRIPTS = {\n dev: 'nx run-many --target dev',\n build: 'nx run-many --target build',\n lint: 'nx run-many --target lint --configuration=fix',\n test: 'nx run-many --target test --all',\n // Trivy container image scanning is not part of `build` (its result\n // depends on the ever-changing vulnerability database); run it explicitly,\n // e.g. in CI.\n trivy: 'nx run-many --target trivy --all',\n 'build:skip-lint': 'nx run-many --target build --configuration=skip-lint',\n 'build:all': 'nx run-many --target build --all',\n 'affected:all': 'nx affected --target build',\n };\n updateJson(tree, 'package.json', (packageJson) => ({\n ...packageJson,\n // The root `type` field is owned by the preset (written explicitly from\n // its `--module` option). `init` preserves an existing workspace's field\n // as-is: an ESM workspace already carries `type: \"module\"` (that is how\n // the format is inferred), and introducing a `type` into a CommonJS\n // workspace that lacks one changes behaviour for frameworks that parse it\n // (e.g. Next.js starts treating the app's ESM source as CJS).\n scripts: overwriteScripts\n ? { ...packageJson.scripts, ...CONVENIENCE_SCRIPTS }\n : { ...CONVENIENCE_SCRIPTS, ...packageJson.scripts },\n }));\n\n // Pin the workspace's `nx` to the version the plugin's @nx/* packages are\n // built against. A mismatched workspace nx (even a patch apart) hoists a\n // second nested nx under @nx/js, and the two instances deadlock `nx sync`.\n // `@nx/js` must be a root dependency for the `@nx/js:typescript-sync`\n // generator registered in nx.json to resolve (npm doesn't hoist the\n // plugin's own copy reliably).\n addDependenciesToPackageJson(\n tree,\n {},\n {\n ...withVersions(forDependencies<typeof INIT_DEPENDENCIES>(declaration), [\n 'nx',\n '@nx/js',\n '@nx/workspace',\n ]),\n ...withVersions(forDependencies<typeof INIT_DEPENDENCIES>(declaration), [\n 'typescript',\n '@biomejs/biome',\n ]),\n // Declare the plugin the generators are running from, plus the MCP server\n // package the vended config runs, so both are pinned in the workspace's\n // lockfile and upgrading them upgrades what the agents use.\n ...nxPluginSelfDependency(tree),\n ...nxPluginMcpDependency(tree),\n },\n );\n\n // Write biome.json for formatting and linting\n if (!tree.exists('biome.json')) {\n tree.write(\n 'biome.json',\n JSON.stringify(getDefaultBiomeConfig(tree), null, 2),\n );\n }\n\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, '..', 'preset', 'files'),\n '.',\n {\n projectName: getNpmScope(tree),\n generators: Object.entries(generatorsJsonEntries)\n .filter(([, info]) => !info.hidden)\n .map(([id, info]) => ({\n name: id,\n description: describeGeneratorForCatalogue(info),\n })),\n ...(() => {\n const cmds = getPackageManagerDisplayCommands();\n return {\n pkgMgrCmd: cmds.exec,\n buildCmd: `${cmds.run} build`,\n lintCmd: `${cmds.run} lint`,\n };\n })(),\n },\n {\n overwriteStrategy: readmeOverwriteStrategy,\n },\n );\n\n if (mcp !== false) {\n configureMcpServers(tree);\n }\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","readNxJson","updateJson","updateNxJson","initGenerator","yaml","SYNC_GENERATOR_NAME","TS_SYNC_GENERATOR_NAME","BASE_TSCONFIG_COMPILER_OPTIONS","ensureAwsNxPluginConfig","updateAwsNxPluginConfig","inferContainers","forDependencies","addDependenciesToPackageJson","detectWorkspacePackageManager","getDefaultBiomeConfig","describeGeneratorForCatalogue","generatorsJsonEntries","configureMcpServers","getNpmScope","mergeTargetDefault","nxPluginMcpDependency","nxPluginSelfDependency","getPackageManagerDisplayCommands","workspaceGlobs","withVersions","WORKSPACES","NX_TYPESCRIPT_SYNC_GENERATOR","DEFAULT_PARALLEL","INIT_DEPENDENCIES","name","PNPM_BUILT_DEPENDENCIES","setUpPnpmWorkspace","tree","catalogs","existing","exists","load","read","packages","Array","from","Set","allowBuilds","Object","fromEntries","map","dep","catalogMode","write","dump","onlyBuiltDependencies","quotingType","setUpWorkspaces","json","globs","workspaces","undefined","isArray","ensureBaseTsConfig","JSON","stringify","compilerOptions","customConditions","ensureRootTsConfig","extends","files","references","applyWorkspaceInit","iac","containers","mcp","readmeOverwriteStrategy","KeepExisting","overwriteScripts","declaration","resolvedContainers","provider","engine","packageManager","formatter","addTsPlugin","nxJson","analytics","parallel","targetDefaults","compile","base","syncGenerators","filter","g","includes","CONVENIENCE_SCRIPTS","dev","build","lint","test","trivy","packageJson","scripts","dirname","projectName","generators","entries","info","hidden","id","description","cmds","pkgMgrCmd","exec","buildCmd","run","lintCmd","overwriteStrategy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/utils/init.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n readNxJson,\n type Tree,\n updateJson,\n updateNxJson,\n} from '@nx/devkit';\nimport { initGenerator } from '@nx/js';\nimport { readFileSync } from 'fs';\nimport yaml from 'js-yaml';\nimport { SYNC_GENERATOR_NAME as TS_SYNC_GENERATOR_NAME } from '../ts/sync/generator.js';\nimport { BASE_TSCONFIG_COMPILER_OPTIONS } from './base-tsconfig.js';\nimport {\n ensureAwsNxPluginConfig,\n updateAwsNxPluginConfig,\n} from './config/utils.js';\nimport { type Containers, inferContainers } from './containers.js';\nimport {\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from './declared-dependencies.js';\nimport {\n addDependenciesToPackageJson,\n detectWorkspacePackageManager,\n} from './dependencies.js';\nimport { getDefaultBiomeConfig } from './format.js';\nimport {\n describeGeneratorForCatalogue,\n generatorsJsonEntries,\n} from './generators.js';\nimport { updateGitIgnore } from './git.js';\nimport type { Iac } from './iac.js';\nimport { configureMcpServers } from './mcp.js';\nimport { getNpmScope } from './npm-scope.js';\nimport {\n mergeTargetDefault,\n nxPluginMcpDependency,\n nxPluginSelfDependency,\n} from './nx.js';\nimport { getPackageManagerDisplayCommands } from './pkg-manager.js';\nimport { workspaceGlobs } from './project-package-json.js';\nimport { type ITsDepVersion, withVersions } from './versions.js';\n\nconst WORKSPACES = ['packages/*'];\nconst NX_TYPESCRIPT_SYNC_GENERATOR = '@nx/js:typescript-sync';\n\nexport const DEFAULT_PARALLEL = 8;\n\n/** Dependencies a caller must declare to apply the workspace init. */\nexport const INIT_DEPENDENCIES = [\n { name: 'nx' },\n { name: '@nx/js' },\n { name: '@nx/workspace' },\n { name: 'typescript' },\n { name: '@biomejs/biome' },\n] as const satisfies readonly { name: ITsDepVersion }[];\n\n// Built dependencies whose install scripts the generated workspace trusts.\n// `onlyBuiltDependencies` is the pnpm 10 key (silently ignored from pnpm 11\n// onwards); pnpm 11 and above read `allowBuilds` instead. Any dep NOT in this\n// allowlist will have its install scripts skipped with a warning — matching\n// pnpm 10's default behaviour. The user can opt-in later via\n// `pnpm approve-builds`.\nexport const PNPM_BUILT_DEPENDENCIES = ['@swc/core', 'esbuild', 'nx', 'sharp'];\n\n/**\n * Options controlling how the workspace is initialised. These mirror the\n * preset schema so a workspace created via the preset and one initialised via\n * the `init` generator end up in the same shape.\n */\nexport interface ApplyWorkspaceInitOptions {\n /** The IaC provider to record in the plugin config. */\n readonly iac: Iac;\n /**\n * The container engine to record. `undefined`/`'infer'` picks docker when\n * installed, else finch.\n */\n readonly containers?: Containers | 'infer';\n /** Whether to configure MCP servers for coding agents. Defaults to true. */\n readonly mcp?: boolean;\n /**\n * How to treat the generated workspace README. The preset owns the README of\n * a greenfield workspace (`Overwrite`); the `init` generator must not clobber\n * an existing workspace's README (`KeepExisting`, the default).\n */\n readonly readmeOverwriteStrategy?: OverwriteStrategy;\n /**\n * Whether to overwrite root package.json scripts that already exist. The\n * preset owns a greenfield workspace's scripts (`true`); the `init`\n * generator must not clobber an existing workspace's scripts (`false`,\n * the default) — it only adds the convenience scripts that are absent.\n */\n readonly overwriteScripts?: boolean;\n /**\n * Whether generators use the package manager's dependency catalog. On pnpm\n * this also sets `catalogMode: strict` so `pnpm add` records new deps in the\n * catalog. Defaults to true.\n */\n readonly catalogs?: boolean;\n}\n\n/**\n * Add or repair the pnpm `allowBuilds` / `onlyBuiltDependencies` allowlist for\n * the workspace's `packages` globs, without clobbering any packages the user\n * has already declared.\n *\n * A workspace not created by the preset commonly has either no\n * `pnpm-workspace.yaml`, one missing the `packages` globs, or one carrying the\n * broken `set this to true or false` placeholder pnpm writes when it skips a\n * build script. This makes the file self-consistent so the first generator's\n * install doesn't fail with `ERR_PNPM_IGNORED_BUILDS`.\n */\nconst setUpPnpmWorkspace = (tree: Tree, catalogs: boolean) => {\n const existing = tree.exists('pnpm-workspace.yaml')\n ? ((yaml.load(tree.read('pnpm-workspace.yaml', 'utf-8') ?? '') as Record<\n string,\n unknown\n >) ?? {})\n : {};\n\n // Preserve any packages globs the user already has, ensuring ours are present.\n const packages = Array.from(\n new Set([...((existing.packages as string[]) ?? []), ...WORKSPACES]),\n );\n\n const allowBuilds = {\n ...(typeof existing.allowBuilds === 'object' && existing.allowBuilds\n ? (existing.allowBuilds as Record<string, unknown>)\n : {}),\n // Overwrite any non-boolean (e.g. the \"set this to true or false\"\n // placeholder) with an explicit true for the deps we trust.\n ...Object.fromEntries(PNPM_BUILT_DEPENDENCIES.map((dep) => [dep, true])),\n };\n\n // `strict` makes `pnpm add` record new deps in the catalog; it only gates\n // that flow, so pre-declared direct ranges (e.g. tslib) still install.\n // Preserve an explicit user choice.\n const catalogMode = catalogs\n ? (existing.catalogMode ?? 'strict')\n : existing.catalogMode;\n\n tree.write(\n 'pnpm-workspace.yaml',\n yaml.dump(\n {\n ...existing,\n packages,\n allowBuilds,\n onlyBuiltDependencies: PNPM_BUILT_DEPENDENCIES,\n ...(catalogMode ? { catalogMode } : {}),\n },\n { quotingType: \"'\" },\n ),\n );\n};\n\n/**\n * Configure the workspace's package manager for a monorepo layout.\n *\n * pnpm workspaces are declared in `pnpm-workspace.yaml`; every other package\n * manager reads the `workspaces` field of the root `package.json`.\n */\nconst setUpWorkspaces = (tree: Tree, catalogs: boolean) => {\n if (detectWorkspacePackageManager(tree) === 'pnpm') {\n setUpPnpmWorkspace(tree, catalogs);\n // pnpm creates these at the workspace root while it materialises packages.\n updateGitIgnore(tree, '.', (patterns) => [...patterns, '_tmp_*']);\n } else {\n updateJson(tree, 'package.json', (json) => {\n // The `workspaces` field may be the object form ({ \"packages\": [...] })\n // accepted by yarn and bun — extend the globs while preserving the form.\n const globs = Array.from(\n new Set([...workspaceGlobs(json.workspaces), ...WORKSPACES]),\n );\n return {\n ...json,\n workspaces:\n json.workspaces !== undefined && !Array.isArray(json.workspaces)\n ? { ...json.workspaces, packages: globs }\n : globs,\n };\n });\n }\n};\n\n/**\n * Ensure the workspace has a `tsconfig.base.json`.\n *\n * `@nx/js` `initGenerator` (with `addTsPlugin`) normally creates this, but it\n * short-circuits when the workspace already has a root `tsconfig.json` — in\n * which case no base file is written and the next project generator fails with\n * `Cannot find tsconfig.base.json`. So we create a compatible one when it's\n * absent. An existing base is left untouched: the user may have tuned it, and\n * rewriting shared compiler options can break other projects (see the\n * \"add to an existing workspace\" guide).\n */\nconst ensureBaseTsConfig = (tree: Tree) => {\n if (tree.exists('tsconfig.base.json')) {\n return;\n }\n tree.write(\n 'tsconfig.base.json',\n JSON.stringify(\n {\n compilerOptions: {\n ...BASE_TSCONFIG_COMPILER_OPTIONS,\n customConditions: [getNpmScope(tree)],\n },\n },\n null,\n 2,\n ),\n );\n};\n\n/**\n * Ensure the workspace has a root `tsconfig.json`.\n *\n * Nx's `@nx/js:typescript-sync` generator hard-fails with\n * `Missing root \"tsconfig.json\"` when it's absent. The plugin's TypeScript\n * projects reference each other via this file, so we guarantee a minimal one\n * exists (sync populates its `references`).\n */\nconst ensureRootTsConfig = (tree: Tree) => {\n if (tree.exists('tsconfig.json')) {\n return;\n }\n tree.write(\n 'tsconfig.json',\n JSON.stringify(\n {\n extends: './tsconfig.base.json',\n files: [],\n references: [],\n },\n null,\n 2,\n ),\n );\n};\n\n/**\n * Transform an Nx workspace into one ready to run `@aws/nx-plugin` generators.\n *\n * This is the deterministic core shared by the workspace preset and the `init`\n * generator. It is safe to re-run: every step is idempotent (config merges,\n * keyed nx.json / package.json entries, create-if-missing files), so running\n * it against an already-initialised workspace is a no-op.\n *\n * It preserves the workspace's module format: the root package.json `type`\n * field is owned by the preset (written from its `--module` option) and left\n * untouched here. It does NOT rewrite an existing `tsconfig.base.json`'s\n * compiler options, migrate a workspace's package manager, or restructure\n * existing projects — those are decisions for the user (see the \"add to an\n * existing workspace\" guide).\n */\nexport const applyWorkspaceInit = async <const D extends DependencyDeclaration>(\n tree: Tree,\n {\n iac,\n containers,\n mcp,\n readmeOverwriteStrategy = OverwriteStrategy.KeepExisting,\n overwriteScripts = false,\n catalogs = true,\n }: ApplyWorkspaceInitOptions,\n declaration: D & MustDeclare<typeof INIT_DEPENDENCIES, D>,\n) => {\n const resolvedContainers =\n !containers || containers === 'infer' ? inferContainers() : containers;\n\n // The catalogs flag is written explicitly (even when true) so the workspace\n // records its dependency-management choice.\n await ensureAwsNxPluginConfig(tree);\n await updateAwsNxPluginConfig(tree, {\n iac: { provider: iac },\n containers: { engine: resolvedContainers },\n packageManager: { catalogs },\n });\n\n // Set up the TypeScript plugin, base tsconfig, formatter etc. `@nx/js`\n // creates `tsconfig.base.json` when absent, but skips it when a root\n // `tsconfig.json` already exists — so we ensure both explicitly below.\n await initGenerator(tree, {\n formatter: 'none',\n addTsPlugin: true,\n });\n\n ensureBaseTsConfig(tree);\n ensureRootTsConfig(tree);\n\n setUpWorkspaces(tree, catalogs);\n\n const nxJson = readNxJson(tree);\n updateNxJson(tree, {\n ...nxJson,\n // Preserve an explicit analytics choice in an existing workspace.\n analytics: (nxJson as { analytics?: boolean }).analytics ?? false,\n parallel: nxJson.parallel ?? DEFAULT_PARALLEL,\n targetDefaults: {\n ...nxJson.targetDefaults,\n compile: mergeTargetDefault(nxJson.targetDefaults?.compile, (base) => ({\n ...base,\n syncGenerators: [\n ...(base.syncGenerators ?? []).filter(\n (g) =>\n ![TS_SYNC_GENERATOR_NAME, NX_TYPESCRIPT_SYNC_GENERATOR].includes(\n g,\n ),\n ),\n NX_TYPESCRIPT_SYNC_GENERATOR,\n TS_SYNC_GENERATOR_NAME,\n ],\n })),\n },\n });\n\n const CONVENIENCE_SCRIPTS = {\n dev: 'nx run-many --target dev',\n build: 'nx run-many --target build',\n lint: 'nx run-many --target lint --configuration=fix',\n test: 'nx run-many --target test --all',\n // Trivy container image scanning is not part of `build` (its result\n // depends on the ever-changing vulnerability database); run it explicitly,\n // e.g. in CI.\n trivy: 'nx run-many --target trivy --all',\n 'build:skip-lint': 'nx run-many --target build --configuration=skip-lint',\n 'build:all': 'nx run-many --target build --all',\n 'affected:all': 'nx affected --target build',\n };\n updateJson(tree, 'package.json', (packageJson) => ({\n ...packageJson,\n // The root `type` field is owned by the preset (written explicitly from\n // its `--module` option). `init` preserves an existing workspace's field\n // as-is: an ESM workspace already carries `type: \"module\"` (that is how\n // the format is inferred), and introducing a `type` into a CommonJS\n // workspace that lacks one changes behaviour for frameworks that parse it\n // (e.g. Next.js starts treating the app's ESM source as CJS).\n scripts: overwriteScripts\n ? { ...packageJson.scripts, ...CONVENIENCE_SCRIPTS }\n : { ...CONVENIENCE_SCRIPTS, ...packageJson.scripts },\n }));\n\n // Pin the workspace's `nx` to the version the plugin's @nx/* packages are\n // built against. A mismatched workspace nx (even a patch apart) hoists a\n // second nested nx under @nx/js, and the two instances deadlock `nx sync`.\n // `@nx/js` must be a root dependency for the `@nx/js:typescript-sync`\n // generator registered in nx.json to resolve (npm doesn't hoist the\n // plugin's own copy reliably).\n addDependenciesToPackageJson(\n tree,\n {},\n {\n ...withVersions(forDependencies<typeof INIT_DEPENDENCIES>(declaration), [\n 'nx',\n '@nx/js',\n '@nx/workspace',\n ]),\n ...withVersions(forDependencies<typeof INIT_DEPENDENCIES>(declaration), [\n 'typescript',\n '@biomejs/biome',\n ]),\n // Declare the plugin the generators are running from, plus the MCP server\n // package the vended config runs, so both are pinned in the workspace's\n // lockfile and upgrading them upgrades what the agents use.\n ...nxPluginSelfDependency(tree),\n ...nxPluginMcpDependency(tree),\n },\n );\n\n // Write biome.json for formatting and linting\n if (!tree.exists('biome.json')) {\n tree.write(\n 'biome.json',\n JSON.stringify(getDefaultBiomeConfig(tree), null, 2),\n );\n }\n\n generateFiles(\n tree, // the virtual file system\n joinPathFragments(import.meta.dirname, '..', 'preset', 'files'),\n '.',\n {\n projectName: getNpmScope(tree),\n generators: Object.entries(generatorsJsonEntries)\n .filter(([, info]) => !info.hidden)\n .map(([id, info]) => ({\n name: id,\n description: describeGeneratorForCatalogue(info),\n })),\n ...(() => {\n const cmds = getPackageManagerDisplayCommands();\n return {\n pkgMgrCmd: cmds.exec,\n buildCmd: `${cmds.run} build`,\n lintCmd: `${cmds.run} lint`,\n };\n })(),\n },\n {\n overwriteStrategy: readmeOverwriteStrategy,\n },\n );\n\n if (mcp !== false) {\n configureMcpServers(tree);\n }\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","readNxJson","updateJson","updateNxJson","initGenerator","yaml","SYNC_GENERATOR_NAME","TS_SYNC_GENERATOR_NAME","BASE_TSCONFIG_COMPILER_OPTIONS","ensureAwsNxPluginConfig","updateAwsNxPluginConfig","inferContainers","forDependencies","addDependenciesToPackageJson","detectWorkspacePackageManager","getDefaultBiomeConfig","describeGeneratorForCatalogue","generatorsJsonEntries","updateGitIgnore","configureMcpServers","getNpmScope","mergeTargetDefault","nxPluginMcpDependency","nxPluginSelfDependency","getPackageManagerDisplayCommands","workspaceGlobs","withVersions","WORKSPACES","NX_TYPESCRIPT_SYNC_GENERATOR","DEFAULT_PARALLEL","INIT_DEPENDENCIES","name","PNPM_BUILT_DEPENDENCIES","setUpPnpmWorkspace","tree","catalogs","existing","exists","load","read","packages","Array","from","Set","allowBuilds","Object","fromEntries","map","dep","catalogMode","write","dump","onlyBuiltDependencies","quotingType","setUpWorkspaces","patterns","json","globs","workspaces","undefined","isArray","ensureBaseTsConfig","JSON","stringify","compilerOptions","customConditions","ensureRootTsConfig","extends","files","references","applyWorkspaceInit","iac","containers","mcp","readmeOverwriteStrategy","KeepExisting","overwriteScripts","declaration","resolvedContainers","provider","engine","packageManager","formatter","addTsPlugin","nxJson","analytics","parallel","targetDefaults","compile","base","syncGenerators","filter","g","includes","CONVENIENCE_SCRIPTS","dev","build","lint","test","trivy","packageJson","scripts","dirname","projectName","generators","entries","info","hidden","id","description","cmds","pkgMgrCmd","exec","buildCmd","run","lintCmd","overwriteStrategy"],"mappings":"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"}
|