@aws/nx-plugin 1.0.0-rc.85 → 1.0.0-rc.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/migrations.json +11 -1
  2. package/package.json +1 -1
  3. package/src/infra/app/__snapshots__/generator.spec.ts.snap +34 -8
  4. package/src/infra/app/files/app/README.md.template +14 -0
  5. package/src/infra/app/generator.js +15 -2
  6. package/src/infra/app/generator.js.map +1 -1
  7. package/src/mcp-server/tools/general-guidance.js +1 -1
  8. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  9. package/src/migrations/latest/add-destroy-sandbox-target/metadata.json +3 -0
  10. package/src/migrations/latest/add-destroy-sandbox-target/migration.d.ts +6 -0
  11. package/src/migrations/latest/add-destroy-sandbox-target/migration.js +150 -0
  12. package/src/migrations/latest/add-destroy-sandbox-target/migration.js.map +1 -0
  13. package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/__snapshots__/migration.spec.ts.snap +23 -0
  14. package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/metadata.json +3 -0
  15. package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.d.ts +6 -0
  16. package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.js +88 -0
  17. package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.js.map +1 -0
  18. package/src/open-api/ts-client/generator.js.map +1 -1
  19. package/src/open-api/ts-hooks/generator.spec.tsx +1 -1
  20. package/src/py/project/generator.js +5 -5
  21. package/src/py/project/generator.js.map +1 -1
  22. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +21 -9
  23. package/src/py/rdb/files/__name__/utils.py.template +17 -1
  24. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +8 -8
  25. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +16 -16
  26. package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +3 -3
  27. package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +3 -3
  28. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +132 -261
  29. package/src/ts/rdb/files/src/utils.ts.template +28 -1
  30. package/src/ts/react-website/cognito-auth/generator.js +1 -1
  31. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  32. package/src/ts/react-website/runtime-config/generator.js +1 -1
  33. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  34. package/src/utils/agent-core-constructs/agent-core-constructs.js +3 -2
  35. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  36. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +1 -1
  37. package/src/utils/api-constructs/api-constructs.js +7 -4
  38. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  39. package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +4 -4
  40. package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +4 -4
  41. package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account.ts.template +1 -1
  42. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +4 -4
  43. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +4 -4
  44. package/src/utils/ast.d.ts +13 -0
  45. package/src/utils/ast.js +36 -0
  46. package/src/utils/ast.js.map +1 -1
  47. package/src/utils/bundle/bundle.js +5 -2
  48. package/src/utils/bundle/bundle.js.map +1 -1
  49. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js +5 -3
  50. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -1
  51. package/src/utils/dcr-proxy-constructs/files/cdk/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.ts.template +1 -1
  52. package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +2 -2
  53. package/src/utils/files/common/scripts/src/infra/stage-credentials/cdk-command.ts.template +7 -3
  54. package/src/utils/function-constructs/function-constructs.js +3 -3
  55. package/src/utils/function-constructs/function-constructs.js.map +1 -1
  56. package/src/utils/lambda-runtime-resolution.d.ts +74 -0
  57. package/src/utils/lambda-runtime-resolution.js +97 -0
  58. package/src/utils/lambda-runtime-resolution.js.map +1 -0
  59. package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +3 -3
  60. package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +10 -29
  61. package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +28 -116
  62. package/src/utils/rdb-constructs/rdb-constructs.js +5 -3
  63. package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
  64. package/src/utils/version-upgrade-migration/sync-lambda-runtimes.d.ts +28 -0
  65. package/src/utils/version-upgrade-migration/sync-lambda-runtimes.js +148 -0
  66. package/src/utils/version-upgrade-migration/sync-lambda-runtimes.js.map +1 -0
  67. package/src/utils/version-upgrade-migration/sync-python-language-version.d.ts +31 -0
  68. package/src/utils/version-upgrade-migration/sync-python-language-version.js +110 -0
  69. package/src/utils/version-upgrade-migration/sync-python-language-version.js.map +1 -0
  70. package/src/utils/version-upgrade-migration/sync-vended-versions.js +36 -7
  71. package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
  72. package/src/utils/versions.d.ts +60 -0
  73. package/src/utils/versions.js +51 -0
  74. package/src/utils/versions.js.map +1 -1
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { visitNotIgnoredFiles } from "@nx/devkit";
5
+ import { applyGritQL, captureAllGritQLVariable } from "../ast.js";
6
+ import { cdkLambdaRuntime, LAMBDA_RUNTIME_VERSIONS, terraformLambdaRuntime } from "../versions.js";
7
+ import { isVendedUpgrade } from "./vended-upgrade.js";
8
+ /**
9
+ * GritQL binding the value of a `runtime` assignment.
10
+ *
11
+ * Structure is matched here and nowhere else: the binding is the runtime alone, so
12
+ * no caller re-derives the assignment around it, and a `runtime` that isn't a real
13
+ * property or attribute — inside a comment, say — never matches.
14
+ */ const RUNTIME_ASSIGNMENT = {
15
+ cdk: '`runtime: $value`',
16
+ terraform: 'language hcl\n`runtime = $value`'
17
+ };
18
+ /** `NODEJS_22_X` -> `22`, `PYTHON_3_14` -> `3.14`; undefined for an alias. */ const cdkMemberVersion = (member)=>/^NODEJS_(\d+)_X$/.exec(member)?.[1] ?? /^PYTHON_(\d+)_(\d+)$/.exec(member)?.slice(1).join('.');
19
+ /**
20
+ * Read a bound CDK runtime, or undefined when the value is not a versioned managed
21
+ * runtime.
22
+ *
23
+ * GritQL has already established this is a `runtime` property and isolated its
24
+ * value, so the regex only reads that scalar.
25
+ */ const readCdkRuntime = (value)=>{
26
+ const member = /^(?:lambda\.)?Runtime\.((?:NODEJS|PYTHON)_[A-Z0-9_]+)$/.exec(value.trim())?.[1];
27
+ if (!member) {
28
+ return undefined;
29
+ }
30
+ return {
31
+ value: value.trim(),
32
+ language: member.startsWith('NODEJS') ? 'node' : 'python',
33
+ version: cdkMemberVersion(member)
34
+ };
35
+ };
36
+ /** Read a bound Terraform runtime, or undefined for a non-runtime value. */ const readTerraformRuntime = (value)=>{
37
+ const identifier = /^"((?:nodejs|python)[0-9][^"]*)"$/.exec(value.trim())?.[1];
38
+ if (!identifier) {
39
+ return undefined;
40
+ }
41
+ return {
42
+ value: value.trim(),
43
+ language: identifier.startsWith('nodejs') ? 'node' : 'python',
44
+ version: /^nodejs([\d.]+?)\.x$/.exec(identifier)?.[1] ?? /^python([\d.]+)$/.exec(identifier)?.[1]
45
+ };
46
+ };
47
+ /**
48
+ * Every runtime a vended file assigns, or undefined when the pattern could not be
49
+ * applied to it.
50
+ *
51
+ * The two are distinguished so a file the parser rejected is reported rather than
52
+ * mistaken for one with nothing to do, which would make this a silent no-op.
53
+ */ const declaredRuntimes = async (tree, path, iac)=>{
54
+ const values = await captureAllGritQLVariable(tree, path, RUNTIME_ASSIGNMENT[iac], 'value');
55
+ if (values === undefined) {
56
+ return undefined;
57
+ }
58
+ const read = iac === 'terraform' ? readTerraformRuntime : readCdkRuntime;
59
+ return values.flatMap((value)=>{
60
+ const runtime = read(value);
61
+ return runtime ? [
62
+ runtime
63
+ ] : [];
64
+ });
65
+ };
66
+ /**
67
+ * The runtime this release vends, written the way the declared one was.
68
+ *
69
+ * A namespace-imported construct writes `lambda.Runtime.X`, so the prefix on the
70
+ * declared value is carried over rather than dropped.
71
+ */ const vendedRuntime = (iac, declared)=>{
72
+ if (iac === 'terraform') {
73
+ return `"${terraformLambdaRuntime(declared.language)}"`;
74
+ }
75
+ const namespace = declared.value.startsWith('lambda.') ? 'lambda.' : '';
76
+ return `${namespace}${cdkLambdaRuntime(declared.language)}`;
77
+ };
78
+ /**
79
+ * Sync the Lambda runtimes in the directories this plugin owns.
80
+ *
81
+ * A runtime below the pin is ours to move, as is a `_LATEST` alias — its value is
82
+ * decided by `aws-cdk-lib`, which is the drift this closes. A runtime at or ahead
83
+ * of the pin is the user's and is left, as is any Lambda outside these
84
+ * directories. One the rewrite cannot reach is reported instead.
85
+ *
86
+ * @returns the files changed, and the owned files still holding an older runtime
87
+ */ export const syncLambdaRuntimes = async (tree, dirs)=>{
88
+ const updated = [];
89
+ const diverged = [];
90
+ for (const [iac, dir] of Object.entries(dirs)){
91
+ if (!tree.exists(dir)) {
92
+ continue;
93
+ }
94
+ const extension = iac === 'terraform' ? '.tf' : '.ts';
95
+ const files = [];
96
+ // Started at the owned directory, so the provider follows from where a file
97
+ // sits rather than being inferred from it.
98
+ visitNotIgnoredFiles(tree, dir, (path)=>{
99
+ if (path.endsWith(extension)) {
100
+ files.push(path);
101
+ }
102
+ });
103
+ for (const path of files){
104
+ const declared = await declaredRuntimes(tree, path, iac);
105
+ if (declared === undefined) {
106
+ diverged.push(path);
107
+ continue;
108
+ }
109
+ let changed = false;
110
+ let stale = false;
111
+ // Deduped: one rewrite covers every occurrence of the same value.
112
+ const seen = new Set();
113
+ for (const runtime of declared){
114
+ if (seen.has(runtime.value)) {
115
+ continue;
116
+ }
117
+ seen.add(runtime.value);
118
+ const vended = vendedRuntime(iac, runtime);
119
+ if (runtime.value === vended) {
120
+ continue;
121
+ }
122
+ // An alias carries no version to compare, and is always ours to pin.
123
+ if (runtime.version !== undefined && !isVendedUpgrade(LAMBDA_RUNTIME_VERSIONS[runtime.language], runtime.version)) {
124
+ continue;
125
+ }
126
+ const assignment = iac === 'terraform' ? 'runtime = ' : 'runtime: ';
127
+ const prefix = iac === 'terraform' ? 'language hcl\n' : '';
128
+ if (await applyGritQL(tree, path, `${prefix}\`${assignment}${runtime.value}\` => \`${assignment}${vended}\``)) {
129
+ changed = true;
130
+ } else {
131
+ stale = true;
132
+ }
133
+ }
134
+ if (changed) {
135
+ updated.push(path);
136
+ }
137
+ if (stale) {
138
+ diverged.push(path);
139
+ }
140
+ }
141
+ }
142
+ return {
143
+ updated,
144
+ diverged
145
+ };
146
+ };
147
+
148
+ //# sourceMappingURL=sync-lambda-runtimes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/version-upgrade-migration/sync-lambda-runtimes.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { type Tree, visitNotIgnoredFiles } from '@nx/devkit';\nimport { applyGritQL, captureAllGritQLVariable } from '../ast.js';\nimport {\n cdkLambdaRuntime,\n type ILambdaRuntime,\n LAMBDA_RUNTIME_VERSIONS,\n terraformLambdaRuntime,\n} from '../versions.js';\nimport { isVendedUpgrade } from './vended-upgrade.js';\n\n/**\n * Sync the Lambda runtimes vended into the projects this plugin owns.\n *\n * The runtimes present are read from each file rather than compared against a\n * list of what past releases vended, which would need maintaining by hand for the\n * same reason the pin itself does.\n */\n\n/** The IaC provider a vended file belongs to, decided by the directory it sits in. */\nexport type VendedIac = 'cdk' | 'terraform';\n\n/** A Lambda runtime a vended file declares. */\ninterface DeclaredRuntime {\n /** The runtime as written, e.g. `lambda.Runtime.NODEJS_22_X` or `\"nodejs22.x\"`. */\n readonly value: string;\n readonly language: ILambdaRuntime;\n /**\n * Version the runtime names, or undefined for an alias like `NODEJS_LATEST`\n * whose value `aws-cdk-lib` decides rather than this repo.\n */\n readonly version?: string;\n}\n\n/**\n * GritQL binding the value of a `runtime` assignment.\n *\n * Structure is matched here and nowhere else: the binding is the runtime alone, so\n * no caller re-derives the assignment around it, and a `runtime` that isn't a real\n * property or attribute — inside a comment, say — never matches.\n */\nconst RUNTIME_ASSIGNMENT: Record<VendedIac, string> = {\n cdk: '`runtime: $value`',\n terraform: 'language hcl\\n`runtime = $value`',\n};\n\n/** `NODEJS_22_X` -> `22`, `PYTHON_3_14` -> `3.14`; undefined for an alias. */\nconst cdkMemberVersion = (member: string): string | undefined =>\n /^NODEJS_(\\d+)_X$/.exec(member)?.[1] ??\n /^PYTHON_(\\d+)_(\\d+)$/.exec(member)?.slice(1).join('.');\n\n/**\n * Read a bound CDK runtime, or undefined when the value is not a versioned managed\n * runtime.\n *\n * GritQL has already established this is a `runtime` property and isolated its\n * value, so the regex only reads that scalar.\n */\nconst readCdkRuntime = (value: string): DeclaredRuntime | undefined => {\n const member = /^(?:lambda\\.)?Runtime\\.((?:NODEJS|PYTHON)_[A-Z0-9_]+)$/.exec(\n value.trim(),\n )?.[1];\n if (!member) {\n return undefined;\n }\n return {\n value: value.trim(),\n language: member.startsWith('NODEJS') ? 'node' : 'python',\n version: cdkMemberVersion(member),\n };\n};\n\n/** Read a bound Terraform runtime, or undefined for a non-runtime value. */\nconst readTerraformRuntime = (value: string): DeclaredRuntime | undefined => {\n const identifier = /^\"((?:nodejs|python)[0-9][^\"]*)\"$/.exec(\n value.trim(),\n )?.[1];\n if (!identifier) {\n return undefined;\n }\n return {\n value: value.trim(),\n language: identifier.startsWith('nodejs') ? 'node' : 'python',\n version:\n /^nodejs([\\d.]+?)\\.x$/.exec(identifier)?.[1] ??\n /^python([\\d.]+)$/.exec(identifier)?.[1],\n };\n};\n\n/**\n * Every runtime a vended file assigns, or undefined when the pattern could not be\n * applied to it.\n *\n * The two are distinguished so a file the parser rejected is reported rather than\n * mistaken for one with nothing to do, which would make this a silent no-op.\n */\nconst declaredRuntimes = async (\n tree: Tree,\n path: string,\n iac: VendedIac,\n): Promise<DeclaredRuntime[] | undefined> => {\n const values = await captureAllGritQLVariable(\n tree,\n path,\n RUNTIME_ASSIGNMENT[iac],\n 'value',\n );\n if (values === undefined) {\n return undefined;\n }\n\n const read = iac === 'terraform' ? readTerraformRuntime : readCdkRuntime;\n return values.flatMap((value) => {\n const runtime = read(value);\n return runtime ? [runtime] : [];\n });\n};\n\n/**\n * The runtime this release vends, written the way the declared one was.\n *\n * A namespace-imported construct writes `lambda.Runtime.X`, so the prefix on the\n * declared value is carried over rather than dropped.\n */\nconst vendedRuntime = (iac: VendedIac, declared: DeclaredRuntime): string => {\n if (iac === 'terraform') {\n return `\"${terraformLambdaRuntime(declared.language)}\"`;\n }\n const namespace = declared.value.startsWith('lambda.') ? 'lambda.' : '';\n return `${namespace}${cdkLambdaRuntime(declared.language)}`;\n};\n\n/**\n * Sync the Lambda runtimes in the directories this plugin owns.\n *\n * A runtime below the pin is ours to move, as is a `_LATEST` alias — its value is\n * decided by `aws-cdk-lib`, which is the drift this closes. A runtime at or ahead\n * of the pin is the user's and is left, as is any Lambda outside these\n * directories. One the rewrite cannot reach is reported instead.\n *\n * @returns the files changed, and the owned files still holding an older runtime\n */\nexport const syncLambdaRuntimes = async (\n tree: Tree,\n dirs: Readonly<Record<VendedIac, string>>,\n): Promise<{ updated: string[]; diverged: string[] }> => {\n const updated: string[] = [];\n const diverged: string[] = [];\n\n for (const [iac, dir] of Object.entries(dirs) as [VendedIac, string][]) {\n if (!tree.exists(dir)) {\n continue;\n }\n const extension = iac === 'terraform' ? '.tf' : '.ts';\n const files: string[] = [];\n // Started at the owned directory, so the provider follows from where a file\n // sits rather than being inferred from it.\n visitNotIgnoredFiles(tree, dir, (path) => {\n if (path.endsWith(extension)) {\n files.push(path);\n }\n });\n\n for (const path of files) {\n const declared = await declaredRuntimes(tree, path, iac);\n if (declared === undefined) {\n diverged.push(path);\n continue;\n }\n\n let changed = false;\n let stale = false;\n\n // Deduped: one rewrite covers every occurrence of the same value.\n const seen = new Set<string>();\n for (const runtime of declared) {\n if (seen.has(runtime.value)) {\n continue;\n }\n seen.add(runtime.value);\n\n const vended = vendedRuntime(iac, runtime);\n if (runtime.value === vended) {\n continue;\n }\n // An alias carries no version to compare, and is always ours to pin.\n if (\n runtime.version !== undefined &&\n !isVendedUpgrade(\n LAMBDA_RUNTIME_VERSIONS[runtime.language],\n runtime.version,\n )\n ) {\n continue;\n }\n\n const assignment = iac === 'terraform' ? 'runtime = ' : 'runtime: ';\n const prefix = iac === 'terraform' ? 'language hcl\\n' : '';\n if (\n await applyGritQL(\n tree,\n path,\n `${prefix}\\`${assignment}${runtime.value}\\` => \\`${assignment}${vended}\\``,\n )\n ) {\n changed = true;\n } else {\n stale = true;\n }\n }\n\n if (changed) {\n updated.push(path);\n }\n if (stale) {\n diverged.push(path);\n }\n }\n }\n\n return { updated, diverged };\n};\n"],"names":["visitNotIgnoredFiles","applyGritQL","captureAllGritQLVariable","cdkLambdaRuntime","LAMBDA_RUNTIME_VERSIONS","terraformLambdaRuntime","isVendedUpgrade","RUNTIME_ASSIGNMENT","cdk","terraform","cdkMemberVersion","member","exec","slice","join","readCdkRuntime","value","trim","undefined","language","startsWith","version","readTerraformRuntime","identifier","declaredRuntimes","tree","path","iac","values","read","flatMap","runtime","vendedRuntime","declared","namespace","syncLambdaRuntimes","dirs","updated","diverged","dir","Object","entries","exists","extension","files","endsWith","push","changed","stale","seen","Set","has","add","vended","assignment","prefix"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { type Tree } from '@nx/devkit';
6
+ /**
7
+ * Sync the Python language version a generated workspace builds and lints against
8
+ * to the Lambda Python runtime it deploys onto.
9
+ *
10
+ * These are workspace-wide rather than scoped to the infrastructure projects: uv
11
+ * writes a `.python-version` per Python project wherever it sits, and a bundle
12
+ * target lives in the project it belongs to.
13
+ */
14
+ /**
15
+ * Sync the interpreter a uv project pins to the Lambda Python runtime.
16
+ *
17
+ * `.python-version` holds the exact interpreter and `[project].requires-python`
18
+ * its lower bound; Ruff's `target-version` is derived from the latter, so leaving
19
+ * these behind lints against a different version than the function runs on. Only
20
+ * moved forward, and only from a value this plugin vended.
21
+ */
22
+ export declare const syncProjectPythonVersion: (tree: Tree) => string[];
23
+ /**
24
+ * Sync the Python version a `bundle` target resolves wheels against.
25
+ *
26
+ * The target pins `--python-platform` but earlier releases pinned no
27
+ * `--python-version`, so wheels resolved against whichever interpreter the build
28
+ * machine had rather than the Lambda runtime. Both the missing flag and a stale
29
+ * one are corrected, keyed on the `uv pip install` the generators write.
30
+ */
31
+ export declare const syncPythonBundleVersion: (tree: Tree) => string[];
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { updateJson, visitNotIgnoredFiles } from "@nx/devkit";
5
+ import { updateToml } from "../toml.js";
6
+ import { LAMBDA_RUNTIME_VERSIONS, pyenvPythonVersion, pyprojectPythonDependency } from "../versions.js";
7
+ import { isVendedUpgrade } from "./vended-upgrade.js";
8
+ /**
9
+ * Sync the Python language version a generated workspace builds and lints against
10
+ * to the Lambda Python runtime it deploys onto.
11
+ *
12
+ * These are workspace-wide rather than scoped to the infrastructure projects: uv
13
+ * writes a `.python-version` per Python project wherever it sits, and a bundle
14
+ * target lives in the project it belongs to.
15
+ */ /**
16
+ * Sync the interpreter a uv project pins to the Lambda Python runtime.
17
+ *
18
+ * `.python-version` holds the exact interpreter and `[project].requires-python`
19
+ * its lower bound; Ruff's `target-version` is derived from the latter, so leaving
20
+ * these behind lints against a different version than the function runs on. Only
21
+ * moved forward, and only from a value this plugin vended.
22
+ */ export const syncProjectPythonVersion = (tree)=>{
23
+ const updated = [];
24
+ const vendedInterpreter = pyenvPythonVersion();
25
+ const vendedRequires = pyprojectPythonDependency();
26
+ // Every `.python-version`, not just the root: uv writes one per project too,
27
+ // and a project left behind resolves a different interpreter than it deploys on.
28
+ visitNotIgnoredFiles(tree, '.', (path)=>{
29
+ if (path !== '.python-version' && !path.endsWith('/.python-version')) {
30
+ return;
31
+ }
32
+ const declared = (tree.read(path, 'utf-8') ?? '').trim();
33
+ if (declared && isVendedUpgrade(vendedInterpreter, declared)) {
34
+ tree.write(path, `${vendedInterpreter}\n`);
35
+ updated.push(path);
36
+ }
37
+ });
38
+ visitNotIgnoredFiles(tree, '.', (path)=>{
39
+ if (!path.endsWith('pyproject.toml')) {
40
+ return;
41
+ }
42
+ let changed = false;
43
+ updateToml(tree, path, (toml)=>{
44
+ const project = toml.project;
45
+ const declared = project?.['requires-python'];
46
+ if (typeof declared !== 'string') {
47
+ return toml;
48
+ }
49
+ // Only the `>=<major>.<minor>` shape the generators write, so a specifier
50
+ // the user tightened or widened is theirs to keep.
51
+ const lower = /^>=\s*(\d+\.\d+)$/.exec(declared.trim());
52
+ if (lower && isVendedUpgrade(LAMBDA_RUNTIME_VERSIONS.python, lower[1])) {
53
+ project['requires-python'] = vendedRequires;
54
+ changed = true;
55
+ }
56
+ return toml;
57
+ });
58
+ if (changed) {
59
+ updated.push(path);
60
+ }
61
+ });
62
+ return updated;
63
+ };
64
+ /**
65
+ * Sync the Python version a `bundle` target resolves wheels against.
66
+ *
67
+ * The target pins `--python-platform` but earlier releases pinned no
68
+ * `--python-version`, so wheels resolved against whichever interpreter the build
69
+ * machine had rather than the Lambda runtime. Both the missing flag and a stale
70
+ * one are corrected, keyed on the `uv pip install` the generators write.
71
+ */ export const syncPythonBundleVersion = (tree)=>{
72
+ const updated = [];
73
+ const vended = LAMBDA_RUNTIME_VERSIONS.python;
74
+ visitNotIgnoredFiles(tree, '.', (path)=>{
75
+ if (!path.endsWith('project.json')) {
76
+ return;
77
+ }
78
+ let changed = false;
79
+ updateJson(tree, path, (json)=>{
80
+ for (const target of Object.values(json.targets ?? {})){
81
+ const options = target.options;
82
+ if (!Array.isArray(options?.commands)) {
83
+ continue;
84
+ }
85
+ options.commands = options.commands.map((command)=>{
86
+ if (typeof command !== 'string' || !command.includes('uv pip install') || !command.includes('--python-platform')) {
87
+ return command;
88
+ }
89
+ const declared = /--python-version (\S+)/.exec(command);
90
+ if (!declared) {
91
+ changed = true;
92
+ return command.replace(/(--python-platform \S+)/, `$1 --python-version ${vended}`);
93
+ }
94
+ if (isVendedUpgrade(vended, declared[1])) {
95
+ changed = true;
96
+ return command.replace(/--python-version \S+/, `--python-version ${vended}`);
97
+ }
98
+ return command;
99
+ });
100
+ }
101
+ return json;
102
+ });
103
+ if (changed) {
104
+ updated.push(path);
105
+ }
106
+ });
107
+ return updated;
108
+ };
109
+
110
+ //# sourceMappingURL=sync-python-language-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/version-upgrade-migration/sync-python-language-version.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { type Tree, updateJson, visitNotIgnoredFiles } from '@nx/devkit';\nimport { updateToml } from '../toml.js';\nimport {\n LAMBDA_RUNTIME_VERSIONS,\n pyenvPythonVersion,\n pyprojectPythonDependency,\n} from '../versions.js';\nimport { isVendedUpgrade } from './vended-upgrade.js';\n\n/**\n * Sync the Python language version a generated workspace builds and lints against\n * to the Lambda Python runtime it deploys onto.\n *\n * These are workspace-wide rather than scoped to the infrastructure projects: uv\n * writes a `.python-version` per Python project wherever it sits, and a bundle\n * target lives in the project it belongs to.\n */\n\n/**\n * Sync the interpreter a uv project pins to the Lambda Python runtime.\n *\n * `.python-version` holds the exact interpreter and `[project].requires-python`\n * its lower bound; Ruff's `target-version` is derived from the latter, so leaving\n * these behind lints against a different version than the function runs on. Only\n * moved forward, and only from a value this plugin vended.\n */\nexport const syncProjectPythonVersion = (tree: Tree): string[] => {\n const updated: string[] = [];\n const vendedInterpreter = pyenvPythonVersion();\n const vendedRequires = pyprojectPythonDependency();\n\n // Every `.python-version`, not just the root: uv writes one per project too,\n // and a project left behind resolves a different interpreter than it deploys on.\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (path !== '.python-version' && !path.endsWith('/.python-version')) {\n return;\n }\n const declared = (tree.read(path, 'utf-8') ?? '').trim();\n if (declared && isVendedUpgrade(vendedInterpreter, declared)) {\n tree.write(path, `${vendedInterpreter}\\n`);\n updated.push(path);\n }\n });\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('pyproject.toml')) {\n return;\n }\n let changed = false;\n updateToml(tree, path, (toml) => {\n const project = toml.project as Record<string, unknown> | undefined;\n const declared = project?.['requires-python'];\n if (typeof declared !== 'string') {\n return toml;\n }\n // Only the `>=<major>.<minor>` shape the generators write, so a specifier\n // the user tightened or widened is theirs to keep.\n const lower = /^>=\\s*(\\d+\\.\\d+)$/.exec(declared.trim());\n if (lower && isVendedUpgrade(LAMBDA_RUNTIME_VERSIONS.python, lower[1])) {\n project!['requires-python'] = vendedRequires;\n changed = true;\n }\n return toml;\n });\n if (changed) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n\n/**\n * Sync the Python version a `bundle` target resolves wheels against.\n *\n * The target pins `--python-platform` but earlier releases pinned no\n * `--python-version`, so wheels resolved against whichever interpreter the build\n * machine had rather than the Lambda runtime. Both the missing flag and a stale\n * one are corrected, keyed on the `uv pip install` the generators write.\n */\nexport const syncPythonBundleVersion = (tree: Tree): string[] => {\n const updated: string[] = [];\n const vended = LAMBDA_RUNTIME_VERSIONS.python;\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('project.json')) {\n return;\n }\n let changed = false;\n updateJson(tree, path, (json) => {\n for (const target of Object.values(\n (json.targets ?? {}) as Record<string, { options?: unknown }>,\n )) {\n const options = target.options as { commands?: unknown[] } | undefined;\n if (!Array.isArray(options?.commands)) {\n continue;\n }\n options.commands = options.commands.map((command) => {\n if (\n typeof command !== 'string' ||\n !command.includes('uv pip install') ||\n !command.includes('--python-platform')\n ) {\n return command;\n }\n const declared = /--python-version (\\S+)/.exec(command);\n if (!declared) {\n changed = true;\n return command.replace(\n /(--python-platform \\S+)/,\n `$1 --python-version ${vended}`,\n );\n }\n if (isVendedUpgrade(vended, declared[1])) {\n changed = true;\n return command.replace(\n /--python-version \\S+/,\n `--python-version ${vended}`,\n );\n }\n return command;\n });\n }\n return json;\n });\n if (changed) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n"],"names":["updateJson","visitNotIgnoredFiles","updateToml","LAMBDA_RUNTIME_VERSIONS","pyenvPythonVersion","pyprojectPythonDependency","isVendedUpgrade","syncProjectPythonVersion","tree","updated","vendedInterpreter","vendedRequires","path","endsWith","declared","read","trim","write","push","changed","toml","project","lower","exec","python","syncPythonBundleVersion","vended","json","target","Object","values","targets","options","Array","isArray","commands","map","command","includes","replace"],"mappings":"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"}
@@ -6,15 +6,18 @@ import yaml from "js-yaml";
6
6
  import { getCatalogManager } from "nx/src/utils/catalog";
7
7
  import { parsePipRequirementsLine } from "pip-requirements-js";
8
8
  import { coerce, parse, satisfies, validRange } from "semver";
9
- import { applyGritQL, captureAllGritQL } from "../ast.js";
9
+ import { applyGritQL, captureAllGritQLVariable } from "../ast.js";
10
10
  import { buildInstallCommand } from "../commands.js";
11
11
  import { formatFilesInSubtree } from "../format.js";
12
+ import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
12
13
  import { updateToml } from "../toml.js";
13
- import { PY_VERSIONS, TERRAFORM_VERSIONS, TS_VERSIONS } from "../versions.js";
14
+ import { cdkLambdaRuntime, PY_VERSIONS, TERRAFORM_VERSIONS, TS_VERSIONS, terraformLambdaRuntime } from "../versions.js";
14
15
  import { isNxPackage } from "./nx-package-updates.js";
15
16
  import { ownedDependencies } from "./owned-dependencies.js";
16
17
  import { syncEmbeddedVersions } from "./sync-embedded-versions.js";
18
+ import { syncLambdaRuntimes } from "./sync-lambda-runtimes.js";
17
19
  import { syncMetricsVersion } from "./sync-metrics-version.js";
20
+ import { syncProjectPythonVersion, syncPythonBundleVersion } from "./sync-python-language-version.js";
18
21
  import { isVendedUpgrade } from "./vended-upgrade.js";
19
22
  /**
20
23
  * Syncs the versions a generated workspace pins to those this release vends:
@@ -451,9 +454,9 @@ const syncOverrides = (tree, owned)=>{
451
454
  * `language hcl` is required — without it the pattern silently matches nothing.
452
455
  */ const providerVersionPattern = (provider, rewrite = '')=>`language hcl\n\`version = $version\`${rewrite} where {` + ` $version <: within \`{ source = "hashicorp/${provider}" $... }\` }`;
453
456
  /** Version a provider currently declares, if it declares one. */ const declaredProviderVersion = async (tree, path, provider)=>{
454
- const [captured] = await captureAllGritQL(tree, path, providerVersionPattern(provider));
455
- // The match is the whole attribute, e.g. `version = "6.40.0"`.
456
- return /"([^"]+)"/.exec(captured ?? '')?.[1];
457
+ const [bound] = await captureAllGritQLVariable(tree, path, providerVersionPattern(provider), 'version') ?? [];
458
+ // The binding is the quoted version, e.g. `"6.40.0"`.
459
+ return bound?.replace(/^"|"$/g, '');
457
460
  };
458
461
  /** Sync vended provider versions in every `.tf` file. */ const syncTerraformProviders = async (tree)=>{
459
462
  const updated = [];
@@ -478,6 +481,16 @@ const syncOverrides = (tree, owned)=>{
478
481
  }
479
482
  return updated;
480
483
  };
484
+ /**
485
+ * The projects this plugin generates infrastructure into, per provider.
486
+ *
487
+ * A runtime is not a dependency, so there is no per-package ownership to consult —
488
+ * these directories are the scope. A Lambda a user defined in their own project
489
+ * keeps whatever runtime they chose, even though it is the same shape.
490
+ */ const OWNED_INFRA_DIRS = {
491
+ cdk: `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}`,
492
+ terraform: `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}`
493
+ };
481
494
  /**
482
495
  * Sync the versions this release vends, for the dependencies the workspace's
483
496
  * generators own.
@@ -489,6 +502,9 @@ const syncOverrides = (tree, owned)=>{
489
502
  const overrides = syncOverrides(tree, owned);
490
503
  const pyProjects = syncPyProjects(tree, owned);
491
504
  const terraformFiles = await syncTerraformProviders(tree);
505
+ const lambdaRuntimes = await syncLambdaRuntimes(tree, OWNED_INFRA_DIRS);
506
+ const projectPython = syncProjectPythonVersion(tree);
507
+ const pythonBundles = syncPythonBundleVersion(tree);
492
508
  const skippedEmbedded = await syncEmbeddedVersions(tree, owned);
493
509
  await syncMetricsVersion(tree);
494
510
  // Lock files are left to the user: `nx migrate` only installs when the root
@@ -496,8 +512,21 @@ const syncOverrides = (tree, owned)=>{
496
512
  if (catalogs.length > 0 || packageJsons.length > 0 || overrides.length > 0) {
497
513
  nextSteps.push(`TypeScript dependency versions were updated. Run \`${buildInstallCommand(detectPackageManager(tree.root))}\` to update the lock file.`);
498
514
  }
499
- if (pyProjects.length > 0) {
500
- nextSteps.push(`Python dependency versions were updated in ${pyProjects.join(', ')}. Run \`uv sync\` to update uv.lock.`);
515
+ if (pyProjects.length > 0 || projectPython.length > 0 || pythonBundles.length > 0) {
516
+ nextSteps.push(`Python dependency versions were updated in ${[
517
+ ...new Set([
518
+ ...pyProjects,
519
+ ...projectPython,
520
+ ...pythonBundles
521
+ ])
522
+ ].join(', ')}. Run \`uv sync\` to update uv.lock.`);
523
+ }
524
+ // A runtime the sync recognised is simply moved; one it doesn't recognise is
525
+ // the user's choice, so it is reported rather than rewritten.
526
+ if (lambdaRuntimes.diverged.length > 0) {
527
+ nextSteps.push(`Lambda runtimes in ${[
528
+ ...new Set(lambdaRuntimes.diverged)
529
+ ].join(', ')} have diverged from the generated shape and were left untouched. Set them to \`${cdkLambdaRuntime('node')}\` (CDK) or \`"${terraformLambdaRuntime('node')}"\` (Terraform) if you want them on the runtime this release vends.`);
501
530
  }
502
531
  if (terraformFiles.length > 0) {
503
532
  nextSteps.push(`Terraform provider versions were updated in ${terraformFiles.length} file(s). Run \`terraform init -upgrade\` in each Terraform project to update its lock file.`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/version-upgrade-migration/sync-vended-versions.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n detectPackageManager,\n type MigrationReturnObject,\n readJson,\n type Tree,\n updateJson,\n visitNotIgnoredFiles,\n} from '@nx/devkit';\nimport yaml from 'js-yaml';\nimport { getCatalogManager } from 'nx/src/utils/catalog';\nimport { parsePipRequirementsLine } from 'pip-requirements-js';\nimport { coerce, parse, satisfies, validRange } from 'semver';\nimport { applyGritQL, captureAllGritQL } from '../ast.js';\nimport { buildInstallCommand } from '../commands.js';\nimport { formatFilesInSubtree } from '../format.js';\nimport { updateToml } from '../toml.js';\nimport { PY_VERSIONS, TERRAFORM_VERSIONS, TS_VERSIONS } from '../versions.js';\nimport { isNxPackage } from './nx-package-updates.js';\nimport {\n type OwnedDependencies,\n ownedDependencies,\n} from './owned-dependencies.js';\nimport { syncEmbeddedVersions } from './sync-embedded-versions.js';\nimport { syncMetricsVersion } from './sync-metrics-version.js';\nimport { isVendedUpgrade } from './vended-upgrade.js';\n\n/**\n * Syncs the versions a generated workspace pins to those this release vends:\n * TypeScript dependencies (including those pinned only by an override), Python\n * pins, Terraform providers, and the plugin version the metrics files report.\n *\n * nx and `@nx/*` are excluded — `packageJsonUpdates` owns them so `nx migrate`\n * collects Nx's own migrations (see `nx-package-updates.ts`).\n */\n\n/** Workspace files holding catalog definitions, and pnpm 11's overrides. */\nconst YAML_WORKSPACE_FILES = ['pnpm-workspace.yaml', '.yarnrc.yml'];\n\n/**\n * Vended version for a dependency this workspace's generators own, or undefined\n * for one the user added themselves.\n */\nconst vendedTsVersion = (\n owned: OwnedDependencies,\n name: string,\n): string | undefined =>\n isNxPackage(name) || !owned.ts.has(name)\n ? undefined\n : TS_VERSIONS[name as keyof typeof TS_VERSIONS];\n\n/** PY_VERSIONS records the `==` operator; the pin holds the bare version. */\nconst vendedPyVersion = (\n owned: OwnedDependencies,\n name: string,\n): string | undefined =>\n owned.py.has(name)\n ? PY_VERSIONS[name as keyof typeof PY_VERSIONS]?.replace(/^==/, '')\n : undefined;\n\n/** Protocols whose version lives elsewhere, and is synced there instead. */\nconst REFERENCE_PROTOCOL =\n /^(?:workspace|file|link|npm|git|git\\+|github|portal|patch|exec):/;\n\n/**\n * Whether devkit may be handed this specifier.\n *\n * `catalog:` is only safe where devkit has a catalog manager (pnpm, yarn).\n * It ships none for bun, and without one it rewrites the reference to a literal\n * version, severing the catalog — so bun's references are synced directly.\n */\nconst isSyncableSpecifier = (tree: Tree, declared: unknown): boolean => {\n // A manifest is the user's file and may hold anything. A version that isn't a\n // string is not one this can reason about, and throwing here would abort the\n // whole `nx migrate` over a file the sync only meant to skip.\n if (typeof declared !== 'string') {\n return false;\n }\n if (REFERENCE_PROTOCOL.test(declared)) {\n return false;\n }\n return (\n !declared.startsWith('catalog:') || getCatalogManager(tree.root) !== null\n );\n};\n\n/**\n * Whether the declared range already permits the vended version, following a\n * `catalog:` reference to the range it points at.\n *\n * Devkit would narrow such a range to an exact pin, discarding a user's widened\n * specifier without changing what resolves, so it is left alone.\n */\nconst alreadyPermitsVended = (\n tree: Tree,\n packageName: string,\n declared: string,\n vended: string,\n): boolean => {\n let range = declared;\n if (declared.startsWith('catalog:')) {\n const resolved = getCatalogManager(tree.root)?.resolveCatalogReference(\n tree,\n packageName,\n declared,\n );\n if (!resolved) {\n return false;\n }\n range = resolved;\n }\n range = range.trim();\n // An exact pin is the case to upgrade, not a range to preserve.\n if (parse(range) !== null || validRange(range) === null) {\n return false;\n }\n return satisfies(vended, range);\n};\n\n/**\n * Vended packages a manifest already declares, and the version to move each to.\n *\n * Only packages already present are named: devkit adds whatever it is given, so\n * passing the full vended list would inject all of it into every manifest.\n */\nconst declaredVendedPackages = (\n tree: Tree,\n owned: OwnedDependencies,\n packageJsonPath: string,\n): {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n} => {\n const json = readJson(tree, packageJsonPath);\n const pick = (field: 'dependencies' | 'devDependencies') =>\n Object.fromEntries(\n Object.entries((json[field] ?? {}) as Record<string, string>).flatMap(\n ([name, declared]) => {\n const vended = vendedTsVersion(owned, name);\n return vended &&\n isSyncableSpecifier(tree, declared) &&\n !alreadyPermitsVended(tree, name, declared, vended)\n ? [[name, vended] as const]\n : [];\n },\n ),\n );\n return {\n dependencies: pick('dependencies'),\n devDependencies: pick('devDependencies'),\n };\n};\n\n/**\n * Sync the TypeScript dependencies every `package.json` declares.\n *\n * Devkit does the writing: it moves a version wherever the workspace keeps it —\n * through a `catalog:` reference or directly — and refuses anything that isn't a\n * strict upgrade on what is installed.\n *\n * Called directly rather than through this plugin's wrapper, which *migrates*\n * declarations into the catalog; right when generating, wrong for a version bump.\n */\nconst syncPackageJsons = (tree: Tree, owned: OwnedDependencies): string[] => {\n const updated: string[] = [];\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('package.json')) {\n return;\n }\n const { dependencies, devDependencies } = declaredVendedPackages(\n tree,\n owned,\n path,\n );\n if (\n Object.keys(dependencies).length === 0 &&\n Object.keys(devDependencies).length === 0\n ) {\n return;\n }\n\n const before = tree.read(path, 'utf-8');\n const catalogsBefore = readCatalogFiles(tree);\n // Install callback dropped: `nx migrate` runs install itself.\n addDependenciesToPackageJson(tree, dependencies, devDependencies, path);\n if (\n tree.read(path, 'utf-8') !== before ||\n readCatalogFiles(tree) !== catalogsBefore\n ) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n\n/** Snapshot of every catalog definition file, for change detection. */\nconst readCatalogFiles = (tree: Tree): string =>\n [...YAML_WORKSPACE_FILES, 'package.json']\n .map((path) => (tree.exists(path) ? tree.read(path, 'utf-8') : ''))\n .join('\\0');\n\n/**\n * Upgrade vended catalog entries devkit cannot reach: those no manifest\n * references, and every bun entry (bun has no catalog manager).\n */\nconst syncOrphanCatalogEntries = (\n tree: Tree,\n owned: OwnedDependencies,\n): string[] => {\n const referenced = referencedCatalogPackages(tree);\n const updated: string[] = [];\n\n const syncCatalog = (\n catalog: Record<string, string> | undefined,\n ): boolean => {\n let changed = false;\n for (const [name, declared] of Object.entries(catalog ?? {})) {\n const vended = vendedTsVersion(owned, name);\n if (!vended || referenced.has(name)) {\n continue;\n }\n if (isVendedUpgrade(vended, String(declared))) {\n catalog![name] = vended;\n changed = true;\n }\n }\n return changed;\n };\n\n for (const path of YAML_WORKSPACE_FILES) {\n if (!tree.exists(path)) {\n continue;\n }\n const catalogFile = (yaml.load(tree.read(path, 'utf-8') ?? '') ?? {}) as {\n catalog?: Record<string, string>;\n catalogs?: Record<string, Record<string, string>>;\n };\n const changed = [\n syncCatalog(catalogFile.catalog),\n ...Object.values(catalogFile.catalogs ?? {}).map(syncCatalog),\n ].some(Boolean);\n if (changed) {\n tree.write(path, yaml.dump(catalogFile, { quotingType: \"'\" }));\n updated.push(path);\n }\n }\n\n // Bun keeps its catalogs in the root manifest.\n if (tree.exists('package.json')) {\n let changed = false;\n updateJson(tree, 'package.json', (json) => {\n changed = [\n syncCatalog(json.catalog),\n ...Object.values(\n (json.catalogs ?? {}) as Record<string, Record<string, string>>,\n ).map(syncCatalog),\n ].some(Boolean);\n return json;\n });\n if (changed) {\n updated.push('package.json');\n }\n }\n\n return updated;\n};\n\n/**\n * The package an override key pins, or undefined when the key names none.\n *\n * A key is a package name, optionally preceded by the path it is scoped to and\n * followed by the parent range it applies at:\n *\n * zod -> zod\n * zod@^3 -> zod\n * **&#47;@modelcontextprotocol/sdk/zod -> zod\n * @prisma/adapter-pg/@types/pg -> @types/pg\n *\n * The last segment is the package, since every earlier one is a parent it is\n * scoped under — except that a scope and the name after it are one segment.\n */\nconst overriddenPackage = (key: string): string | undefined => {\n const segments = key.split('/').reduce<string[]>((acc, part) => {\n // A bare `@scope` is only half a name; join it to what follows.\n const previous = acc[acc.length - 1];\n if (previous?.startsWith('@') && !previous.includes('/')) {\n acc[acc.length - 1] = `${previous}/${part}`;\n return acc;\n }\n acc.push(part);\n return acc;\n }, []);\n\n const name = segments[segments.length - 1];\n if (!name || name === '.') {\n return undefined;\n }\n // A trailing `@range` scopes the override to a parent version.\n const at = name.lastIndexOf('@');\n return at > 0 ? name.slice(0, at) : name;\n};\n\n/**\n * Sync the owned packages an override pins, wherever the workspace keeps them:\n * npm's `overrides`, yarn and bun's `resolutions`, and pnpm's `pnpm.overrides`\n * (10) or `pnpm-workspace.yaml` `overrides` (11).\n *\n * Devkit does not manage these fields, so an owned package pinned only here\n * would otherwise stay on the version it was generated with. Values are compared\n * with `isVendedUpgrade`, so a range the user widened is left alone.\n */\n/**\n * Where the workspace's package manager reads overrides from.\n *\n * Only the root manifest is considered: every package manager resolves overrides\n * from the workspace root, so a nested `overrides` block is inert and rewriting\n * it would imply an effect it doesn't have.\n *\n * pnpm moved the block between majors — 10 reads `pnpm.overrides` in the\n * manifest, 11 reads `overrides` in `pnpm-workspace.yaml` — so both are covered\n * rather than detecting the minor.\n */\nconst overrideLocations = (\n tree: Tree,\n): {\n manifestFields: readonly ('overrides' | 'resolutions' | 'pnpm.overrides')[];\n workspaceFile?: string;\n} => {\n switch (detectPackageManager(tree.root)) {\n case 'npm':\n return { manifestFields: ['overrides'] };\n case 'yarn':\n return { manifestFields: ['resolutions'] };\n case 'bun':\n // Bun reads npm's `overrides` and yarn's `resolutions` alike.\n return { manifestFields: ['overrides', 'resolutions'] };\n default:\n return {\n manifestFields: ['pnpm.overrides'],\n workspaceFile: 'pnpm-workspace.yaml',\n };\n }\n};\n\nconst syncOverrides = (tree: Tree, owned: OwnedDependencies): string[] => {\n const updated: string[] = [];\n\n // Nested npm overrides carry the pin under `.`, with sibling keys scoping\n // deeper, so a value may be a string or another override object.\n const syncOverrideTree = (overrides: unknown): boolean => {\n if (typeof overrides !== 'object' || overrides === null) {\n return false;\n }\n let changed = false;\n for (const [key, value] of Object.entries(\n overrides as Record<string, unknown>,\n )) {\n if (typeof value === 'object' && value !== null) {\n changed = syncOverrideTree(value) || changed;\n continue;\n }\n if (typeof value !== 'string') {\n continue;\n }\n // `.` pins the package its parent key names.\n const name =\n key === '.' ? undefined : (overriddenPackage(key) ?? undefined);\n const vended = name ? vendedTsVersion(owned, name) : undefined;\n if (vended && isVendedUpgrade(vended, value)) {\n (overrides as Record<string, unknown>)[key] = vended;\n changed = true;\n }\n }\n return changed;\n };\n\n const { manifestFields, workspaceFile } = overrideLocations(tree);\n\n if (manifestFields.length > 0) {\n let changed = false;\n updateJson(tree, 'package.json', (json) => {\n changed = manifestFields\n .map((field) =>\n syncOverrideTree(\n field === 'pnpm.overrides' ? json.pnpm?.overrides : json[field],\n ),\n )\n .some(Boolean);\n return json;\n });\n if (changed) {\n updated.push('package.json');\n }\n }\n\n if (workspaceFile && tree.exists(workspaceFile)) {\n const contents = (yaml.load(tree.read(workspaceFile, 'utf-8') ?? '') ??\n {}) as Record<string, unknown>;\n if (syncOverrideTree(contents.overrides)) {\n tree.write(workspaceFile, yaml.dump(contents, { quotingType: \"'\" }));\n updated.push(workspaceFile);\n }\n }\n\n return updated;\n};\n\n/**\n * Packages devkit already maintains through a `catalog:` reference. Empty\n * without a catalog manager, where no reference resolves.\n */\nconst referencedCatalogPackages = (tree: Tree): Set<string> => {\n const referenced = new Set<string>();\n if (getCatalogManager(tree.root) === null) {\n return referenced;\n }\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('package.json')) {\n return;\n }\n const json = readJson(tree, path);\n for (const field of ['dependencies', 'devDependencies'] as const) {\n for (const [name, declared] of Object.entries(\n (json[field] ?? {}) as Record<string, string>,\n )) {\n if (String(declared).startsWith('catalog:')) {\n referenced.add(name);\n }\n }\n }\n });\n return referenced;\n};\n\n/** Pip specifier as `pip-requirements-js` reports it. */\ninterface PyVersionSpec {\n readonly operator: string;\n readonly version: string;\n}\n\n/**\n * Whether the declared specifiers already permit the vended version, so\n * rewriting them would discard the user's range without changing what resolves.\n *\n * This mirrors the TypeScript side: an exact pin is the case to upgrade, a range\n * that already reaches the vended version is left alone, and a range that falls\n * short is moved up.\n *\n * A `*` wildcard or a specifier semver can't read counts as already permitting,\n * so anything not understood is left as the user wrote it.\n */\nconst pyRangePermitsVended = (\n specs: readonly PyVersionSpec[],\n vended: string,\n): boolean =>\n specs.every((spec) => {\n if (spec.version.includes('*')) {\n return true;\n }\n const bound = coerce(spec.version, { includePrerelease: true });\n if (!bound) {\n return true;\n }\n switch (spec.operator) {\n // An exact pin permits only itself, so a differing vended version is an\n // upgrade to apply.\n case '==':\n case '===':\n return satisfies(vended, `=${bound.version}`, {\n includePrerelease: true,\n });\n // `~=1.2.3` allows the patch series; `~=1.2` the minor series.\n case '~=':\n return satisfies(\n vended,\n spec.version.split('.').length > 2\n ? `~${bound.version}`\n : `^${bound.version}`,\n { includePrerelease: true },\n );\n case '>=':\n case '>':\n case '<=':\n case '<':\n return satisfies(vended, `${spec.operator}${bound.version}`, {\n includePrerelease: true,\n });\n // `!=` only excludes, so it never blocks the vended version by itself.\n case '!=':\n return true;\n default:\n return true;\n }\n });\n\n/**\n * Upgrade a pip requirement to the vended version, or return it unchanged.\n *\n * Parsed rather than pattern-matched so extras and operators are read the way\n * `uv` reads them. A requirement whose specifiers already permit the vended\n * version keeps them; one that falls short is replaced with an exact pin, which\n * is what the generators write.\n */\nconst syncPyRequirement = (\n owned: OwnedDependencies,\n requirement: string,\n): string => {\n const parsed = parsePipRequirementsLine(requirement);\n if (parsed?.type !== 'ProjectName' || !parsed.versionSpec?.length) {\n return requirement;\n }\n\n const name = parsed.extras?.length\n ? `${parsed.name}[${parsed.extras.join(',')}]`\n : parsed.name;\n const vended = vendedPyVersion(owned, name);\n if (!vended) {\n return requirement;\n }\n\n const specs = parsed.versionSpec as readonly PyVersionSpec[];\n // Never move a version backwards: a pin above what this release vends is the\n // user's, and a range already reaching it is theirs to keep.\n const [first] = specs;\n const isExactPin =\n specs.length === 1 && (first.operator === '==' || first.operator === '===');\n if (isExactPin && !isVendedUpgrade(vended, first.version)) {\n return requirement;\n }\n if (!isExactPin && pyRangePermitsVended(specs, vended)) {\n return requirement;\n }\n return `${name}==${vended}`;\n};\n\n/** Sync pins in every `pyproject.toml`, dependencies and groups alike. */\nconst syncPyProjects = (tree: Tree, owned: OwnedDependencies): string[] => {\n const updated: string[] = [];\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('pyproject.toml')) {\n return;\n }\n\n let changed = false;\n const syncRequirements = (requirements: unknown): unknown =>\n Array.isArray(requirements)\n ? requirements.map((requirement) => {\n if (typeof requirement !== 'string') {\n return requirement;\n }\n const synced = syncPyRequirement(owned, requirement);\n changed ||= synced !== requirement;\n return synced;\n })\n : requirements;\n\n updateToml(tree, path, (toml) => {\n const project = toml.project as Record<string, unknown> | undefined;\n if (project?.dependencies) {\n project.dependencies = syncRequirements(project.dependencies) as never;\n }\n const groups = toml['dependency-groups'] as\n | Record<string, unknown>\n | undefined;\n for (const group of Object.keys(groups ?? {})) {\n groups![group] = syncRequirements(groups![group]) as never;\n }\n return toml;\n });\n\n if (changed) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n\n/**\n * GritQL matching one provider's `version` in `required_providers`, scoped by\n * the sibling `source` so an alias or another provider's version can't match.\n *\n * `language hcl` is required — without it the pattern silently matches nothing.\n */\nconst providerVersionPattern = (provider: string, rewrite = ''): string =>\n `language hcl\\n\\`version = $version\\`${rewrite} where {` +\n ` $version <: within \\`{ source = \"hashicorp/${provider}\" $... }\\` }`;\n\n/** Version a provider currently declares, if it declares one. */\nconst declaredProviderVersion = async (\n tree: Tree,\n path: string,\n provider: string,\n): Promise<string | undefined> => {\n const [captured] = await captureAllGritQL(\n tree,\n path,\n providerVersionPattern(provider),\n );\n // The match is the whole attribute, e.g. `version = \"6.40.0\"`.\n return /\"([^\"]+)\"/.exec(captured ?? '')?.[1];\n};\n\n/** Sync vended provider versions in every `.tf` file. */\nconst syncTerraformProviders = async (tree: Tree): Promise<string[]> => {\n const updated: string[] = [];\n const terraformFiles: string[] = [];\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (path.endsWith('.tf')) {\n terraformFiles.push(path);\n }\n });\n\n for (const path of terraformFiles) {\n let changed = false;\n for (const [provider, vended] of Object.entries(TERRAFORM_VERSIONS)) {\n const declared = await declaredProviderVersion(tree, path, provider);\n if (!declared || !isVendedUpgrade(vended, declared)) {\n continue;\n }\n changed =\n (await applyGritQL(\n tree,\n path,\n providerVersionPattern(provider, ` => \\`version = \"${vended}\"\\``),\n )) || changed;\n }\n if (changed) {\n updated.push(path);\n }\n }\n\n return updated;\n};\n\n/**\n * Sync the versions this release vends, for the dependencies the workspace's\n * generators own.\n */\nexport const syncVendedVersions = async (\n tree: Tree,\n): Promise<MigrationReturnObject> => {\n const nextSteps: string[] = [];\n const owned = await ownedDependencies(tree);\n\n const packageJsons = syncPackageJsons(tree, owned);\n const catalogs = syncOrphanCatalogEntries(tree, owned);\n const overrides = syncOverrides(tree, owned);\n const pyProjects = syncPyProjects(tree, owned);\n const terraformFiles = await syncTerraformProviders(tree);\n const skippedEmbedded = await syncEmbeddedVersions(tree, owned);\n await syncMetricsVersion(tree);\n\n // Lock files are left to the user: `nx migrate` only installs when the root\n // manifest changes, and never runs `uv` or `terraform`.\n if (catalogs.length > 0 || packageJsons.length > 0 || overrides.length > 0) {\n nextSteps.push(\n `TypeScript dependency versions were updated. Run \\`${buildInstallCommand(\n detectPackageManager(tree.root),\n )}\\` to update the lock file.`,\n );\n }\n if (pyProjects.length > 0) {\n nextSteps.push(\n `Python dependency versions were updated in ${pyProjects.join(', ')}. Run \\`uv sync\\` to update uv.lock.`,\n );\n }\n if (terraformFiles.length > 0) {\n nextSteps.push(\n `Terraform provider versions were updated in ${terraformFiles.length} file(s). Run \\`terraform init -upgrade\\` in each Terraform project to update its lock file.`,\n );\n }\n // A synced embedded pin needs no next step — it is read the next time the thing\n // holding it runs. A file the sync left alone does: its versions are still the\n // old ones, and only the user can reconcile that.\n if (skippedEmbedded.length > 0) {\n nextSteps.push(\n `Version pins were left as they are in ${skippedEmbedded.join(', ')}, which repeat a pin more times than this migration rewrites at once. Update them by hand.`,\n );\n }\n\n // Without this the workspace's own format check fails on the migrated files.\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n};\n"],"names":["addDependenciesToPackageJson","detectPackageManager","readJson","updateJson","visitNotIgnoredFiles","yaml","getCatalogManager","parsePipRequirementsLine","coerce","parse","satisfies","validRange","applyGritQL","captureAllGritQL","buildInstallCommand","formatFilesInSubtree","updateToml","PY_VERSIONS","TERRAFORM_VERSIONS","TS_VERSIONS","isNxPackage","ownedDependencies","syncEmbeddedVersions","syncMetricsVersion","isVendedUpgrade","YAML_WORKSPACE_FILES","vendedTsVersion","owned","name","ts","has","undefined","vendedPyVersion","py","replace","REFERENCE_PROTOCOL","isSyncableSpecifier","tree","declared","test","startsWith","root","alreadyPermitsVended","packageName","vended","range","resolved","resolveCatalogReference","trim","declaredVendedPackages","packageJsonPath","json","pick","field","Object","fromEntries","entries","flatMap","dependencies","devDependencies","syncPackageJsons","updated","path","endsWith","keys","length","before","read","catalogsBefore","readCatalogFiles","push","map","exists","join","syncOrphanCatalogEntries","referenced","referencedCatalogPackages","syncCatalog","catalog","changed","String","catalogFile","load","values","catalogs","some","Boolean","write","dump","quotingType","overriddenPackage","key","segments","split","reduce","acc","part","previous","includes","at","lastIndexOf","slice","overrideLocations","manifestFields","workspaceFile","syncOverrides","syncOverrideTree","overrides","value","pnpm","contents","Set","add","pyRangePermitsVended","specs","every","spec","version","bound","includePrerelease","operator","syncPyRequirement","requirement","parsed","type","versionSpec","extras","first","isExactPin","syncPyProjects","syncRequirements","requirements","Array","isArray","synced","toml","project","groups","group","providerVersionPattern","provider","rewrite","declaredProviderVersion","captured","exec","syncTerraformProviders","terraformFiles","syncVendedVersions","nextSteps","packageJsons","pyProjects","skippedEmbedded"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/version-upgrade-migration/sync-vended-versions.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addDependenciesToPackageJson,\n detectPackageManager,\n type MigrationReturnObject,\n readJson,\n type Tree,\n updateJson,\n visitNotIgnoredFiles,\n} from '@nx/devkit';\nimport yaml from 'js-yaml';\nimport { getCatalogManager } from 'nx/src/utils/catalog';\nimport { parsePipRequirementsLine } from 'pip-requirements-js';\nimport { coerce, parse, satisfies, validRange } from 'semver';\nimport { applyGritQL, captureAllGritQLVariable } from '../ast.js';\nimport { buildInstallCommand } from '../commands.js';\nimport { formatFilesInSubtree } from '../format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants.js';\nimport { updateToml } from '../toml.js';\nimport {\n cdkLambdaRuntime,\n PY_VERSIONS,\n TERRAFORM_VERSIONS,\n TS_VERSIONS,\n terraformLambdaRuntime,\n} from '../versions.js';\nimport { isNxPackage } from './nx-package-updates.js';\nimport {\n type OwnedDependencies,\n ownedDependencies,\n} from './owned-dependencies.js';\nimport { syncEmbeddedVersions } from './sync-embedded-versions.js';\nimport { syncLambdaRuntimes, type VendedIac } from './sync-lambda-runtimes.js';\nimport { syncMetricsVersion } from './sync-metrics-version.js';\nimport {\n syncProjectPythonVersion,\n syncPythonBundleVersion,\n} from './sync-python-language-version.js';\nimport { isVendedUpgrade } from './vended-upgrade.js';\n\n/**\n * Syncs the versions a generated workspace pins to those this release vends:\n * TypeScript dependencies (including those pinned only by an override), Python\n * pins, Terraform providers, and the plugin version the metrics files report.\n *\n * nx and `@nx/*` are excluded — `packageJsonUpdates` owns them so `nx migrate`\n * collects Nx's own migrations (see `nx-package-updates.ts`).\n */\n\n/** Workspace files holding catalog definitions, and pnpm 11's overrides. */\nconst YAML_WORKSPACE_FILES = ['pnpm-workspace.yaml', '.yarnrc.yml'];\n\n/**\n * Vended version for a dependency this workspace's generators own, or undefined\n * for one the user added themselves.\n */\nconst vendedTsVersion = (\n owned: OwnedDependencies,\n name: string,\n): string | undefined =>\n isNxPackage(name) || !owned.ts.has(name)\n ? undefined\n : TS_VERSIONS[name as keyof typeof TS_VERSIONS];\n\n/** PY_VERSIONS records the `==` operator; the pin holds the bare version. */\nconst vendedPyVersion = (\n owned: OwnedDependencies,\n name: string,\n): string | undefined =>\n owned.py.has(name)\n ? PY_VERSIONS[name as keyof typeof PY_VERSIONS]?.replace(/^==/, '')\n : undefined;\n\n/** Protocols whose version lives elsewhere, and is synced there instead. */\nconst REFERENCE_PROTOCOL =\n /^(?:workspace|file|link|npm|git|git\\+|github|portal|patch|exec):/;\n\n/**\n * Whether devkit may be handed this specifier.\n *\n * `catalog:` is only safe where devkit has a catalog manager (pnpm, yarn).\n * It ships none for bun, and without one it rewrites the reference to a literal\n * version, severing the catalog — so bun's references are synced directly.\n */\nconst isSyncableSpecifier = (tree: Tree, declared: unknown): boolean => {\n // A manifest is the user's file and may hold anything. A version that isn't a\n // string is not one this can reason about, and throwing here would abort the\n // whole `nx migrate` over a file the sync only meant to skip.\n if (typeof declared !== 'string') {\n return false;\n }\n if (REFERENCE_PROTOCOL.test(declared)) {\n return false;\n }\n return (\n !declared.startsWith('catalog:') || getCatalogManager(tree.root) !== null\n );\n};\n\n/**\n * Whether the declared range already permits the vended version, following a\n * `catalog:` reference to the range it points at.\n *\n * Devkit would narrow such a range to an exact pin, discarding a user's widened\n * specifier without changing what resolves, so it is left alone.\n */\nconst alreadyPermitsVended = (\n tree: Tree,\n packageName: string,\n declared: string,\n vended: string,\n): boolean => {\n let range = declared;\n if (declared.startsWith('catalog:')) {\n const resolved = getCatalogManager(tree.root)?.resolveCatalogReference(\n tree,\n packageName,\n declared,\n );\n if (!resolved) {\n return false;\n }\n range = resolved;\n }\n range = range.trim();\n // An exact pin is the case to upgrade, not a range to preserve.\n if (parse(range) !== null || validRange(range) === null) {\n return false;\n }\n return satisfies(vended, range);\n};\n\n/**\n * Vended packages a manifest already declares, and the version to move each to.\n *\n * Only packages already present are named: devkit adds whatever it is given, so\n * passing the full vended list would inject all of it into every manifest.\n */\nconst declaredVendedPackages = (\n tree: Tree,\n owned: OwnedDependencies,\n packageJsonPath: string,\n): {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n} => {\n const json = readJson(tree, packageJsonPath);\n const pick = (field: 'dependencies' | 'devDependencies') =>\n Object.fromEntries(\n Object.entries((json[field] ?? {}) as Record<string, string>).flatMap(\n ([name, declared]) => {\n const vended = vendedTsVersion(owned, name);\n return vended &&\n isSyncableSpecifier(tree, declared) &&\n !alreadyPermitsVended(tree, name, declared, vended)\n ? [[name, vended] as const]\n : [];\n },\n ),\n );\n return {\n dependencies: pick('dependencies'),\n devDependencies: pick('devDependencies'),\n };\n};\n\n/**\n * Sync the TypeScript dependencies every `package.json` declares.\n *\n * Devkit does the writing: it moves a version wherever the workspace keeps it —\n * through a `catalog:` reference or directly — and refuses anything that isn't a\n * strict upgrade on what is installed.\n *\n * Called directly rather than through this plugin's wrapper, which *migrates*\n * declarations into the catalog; right when generating, wrong for a version bump.\n */\nconst syncPackageJsons = (tree: Tree, owned: OwnedDependencies): string[] => {\n const updated: string[] = [];\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('package.json')) {\n return;\n }\n const { dependencies, devDependencies } = declaredVendedPackages(\n tree,\n owned,\n path,\n );\n if (\n Object.keys(dependencies).length === 0 &&\n Object.keys(devDependencies).length === 0\n ) {\n return;\n }\n\n const before = tree.read(path, 'utf-8');\n const catalogsBefore = readCatalogFiles(tree);\n // Install callback dropped: `nx migrate` runs install itself.\n addDependenciesToPackageJson(tree, dependencies, devDependencies, path);\n if (\n tree.read(path, 'utf-8') !== before ||\n readCatalogFiles(tree) !== catalogsBefore\n ) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n\n/** Snapshot of every catalog definition file, for change detection. */\nconst readCatalogFiles = (tree: Tree): string =>\n [...YAML_WORKSPACE_FILES, 'package.json']\n .map((path) => (tree.exists(path) ? tree.read(path, 'utf-8') : ''))\n .join('\\0');\n\n/**\n * Upgrade vended catalog entries devkit cannot reach: those no manifest\n * references, and every bun entry (bun has no catalog manager).\n */\nconst syncOrphanCatalogEntries = (\n tree: Tree,\n owned: OwnedDependencies,\n): string[] => {\n const referenced = referencedCatalogPackages(tree);\n const updated: string[] = [];\n\n const syncCatalog = (\n catalog: Record<string, string> | undefined,\n ): boolean => {\n let changed = false;\n for (const [name, declared] of Object.entries(catalog ?? {})) {\n const vended = vendedTsVersion(owned, name);\n if (!vended || referenced.has(name)) {\n continue;\n }\n if (isVendedUpgrade(vended, String(declared))) {\n catalog![name] = vended;\n changed = true;\n }\n }\n return changed;\n };\n\n for (const path of YAML_WORKSPACE_FILES) {\n if (!tree.exists(path)) {\n continue;\n }\n const catalogFile = (yaml.load(tree.read(path, 'utf-8') ?? '') ?? {}) as {\n catalog?: Record<string, string>;\n catalogs?: Record<string, Record<string, string>>;\n };\n const changed = [\n syncCatalog(catalogFile.catalog),\n ...Object.values(catalogFile.catalogs ?? {}).map(syncCatalog),\n ].some(Boolean);\n if (changed) {\n tree.write(path, yaml.dump(catalogFile, { quotingType: \"'\" }));\n updated.push(path);\n }\n }\n\n // Bun keeps its catalogs in the root manifest.\n if (tree.exists('package.json')) {\n let changed = false;\n updateJson(tree, 'package.json', (json) => {\n changed = [\n syncCatalog(json.catalog),\n ...Object.values(\n (json.catalogs ?? {}) as Record<string, Record<string, string>>,\n ).map(syncCatalog),\n ].some(Boolean);\n return json;\n });\n if (changed) {\n updated.push('package.json');\n }\n }\n\n return updated;\n};\n\n/**\n * The package an override key pins, or undefined when the key names none.\n *\n * A key is a package name, optionally preceded by the path it is scoped to and\n * followed by the parent range it applies at:\n *\n * zod -> zod\n * zod@^3 -> zod\n * **&#47;@modelcontextprotocol/sdk/zod -> zod\n * @prisma/adapter-pg/@types/pg -> @types/pg\n *\n * The last segment is the package, since every earlier one is a parent it is\n * scoped under — except that a scope and the name after it are one segment.\n */\nconst overriddenPackage = (key: string): string | undefined => {\n const segments = key.split('/').reduce<string[]>((acc, part) => {\n // A bare `@scope` is only half a name; join it to what follows.\n const previous = acc[acc.length - 1];\n if (previous?.startsWith('@') && !previous.includes('/')) {\n acc[acc.length - 1] = `${previous}/${part}`;\n return acc;\n }\n acc.push(part);\n return acc;\n }, []);\n\n const name = segments[segments.length - 1];\n if (!name || name === '.') {\n return undefined;\n }\n // A trailing `@range` scopes the override to a parent version.\n const at = name.lastIndexOf('@');\n return at > 0 ? name.slice(0, at) : name;\n};\n\n/**\n * Sync the owned packages an override pins, wherever the workspace keeps them:\n * npm's `overrides`, yarn and bun's `resolutions`, and pnpm's `pnpm.overrides`\n * (10) or `pnpm-workspace.yaml` `overrides` (11).\n *\n * Devkit does not manage these fields, so an owned package pinned only here\n * would otherwise stay on the version it was generated with. Values are compared\n * with `isVendedUpgrade`, so a range the user widened is left alone.\n */\n/**\n * Where the workspace's package manager reads overrides from.\n *\n * Only the root manifest is considered: every package manager resolves overrides\n * from the workspace root, so a nested `overrides` block is inert and rewriting\n * it would imply an effect it doesn't have.\n *\n * pnpm moved the block between majors — 10 reads `pnpm.overrides` in the\n * manifest, 11 reads `overrides` in `pnpm-workspace.yaml` — so both are covered\n * rather than detecting the minor.\n */\nconst overrideLocations = (\n tree: Tree,\n): {\n manifestFields: readonly ('overrides' | 'resolutions' | 'pnpm.overrides')[];\n workspaceFile?: string;\n} => {\n switch (detectPackageManager(tree.root)) {\n case 'npm':\n return { manifestFields: ['overrides'] };\n case 'yarn':\n return { manifestFields: ['resolutions'] };\n case 'bun':\n // Bun reads npm's `overrides` and yarn's `resolutions` alike.\n return { manifestFields: ['overrides', 'resolutions'] };\n default:\n return {\n manifestFields: ['pnpm.overrides'],\n workspaceFile: 'pnpm-workspace.yaml',\n };\n }\n};\n\nconst syncOverrides = (tree: Tree, owned: OwnedDependencies): string[] => {\n const updated: string[] = [];\n\n // Nested npm overrides carry the pin under `.`, with sibling keys scoping\n // deeper, so a value may be a string or another override object.\n const syncOverrideTree = (overrides: unknown): boolean => {\n if (typeof overrides !== 'object' || overrides === null) {\n return false;\n }\n let changed = false;\n for (const [key, value] of Object.entries(\n overrides as Record<string, unknown>,\n )) {\n if (typeof value === 'object' && value !== null) {\n changed = syncOverrideTree(value) || changed;\n continue;\n }\n if (typeof value !== 'string') {\n continue;\n }\n // `.` pins the package its parent key names.\n const name =\n key === '.' ? undefined : (overriddenPackage(key) ?? undefined);\n const vended = name ? vendedTsVersion(owned, name) : undefined;\n if (vended && isVendedUpgrade(vended, value)) {\n (overrides as Record<string, unknown>)[key] = vended;\n changed = true;\n }\n }\n return changed;\n };\n\n const { manifestFields, workspaceFile } = overrideLocations(tree);\n\n if (manifestFields.length > 0) {\n let changed = false;\n updateJson(tree, 'package.json', (json) => {\n changed = manifestFields\n .map((field) =>\n syncOverrideTree(\n field === 'pnpm.overrides' ? json.pnpm?.overrides : json[field],\n ),\n )\n .some(Boolean);\n return json;\n });\n if (changed) {\n updated.push('package.json');\n }\n }\n\n if (workspaceFile && tree.exists(workspaceFile)) {\n const contents = (yaml.load(tree.read(workspaceFile, 'utf-8') ?? '') ??\n {}) as Record<string, unknown>;\n if (syncOverrideTree(contents.overrides)) {\n tree.write(workspaceFile, yaml.dump(contents, { quotingType: \"'\" }));\n updated.push(workspaceFile);\n }\n }\n\n return updated;\n};\n\n/**\n * Packages devkit already maintains through a `catalog:` reference. Empty\n * without a catalog manager, where no reference resolves.\n */\nconst referencedCatalogPackages = (tree: Tree): Set<string> => {\n const referenced = new Set<string>();\n if (getCatalogManager(tree.root) === null) {\n return referenced;\n }\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('package.json')) {\n return;\n }\n const json = readJson(tree, path);\n for (const field of ['dependencies', 'devDependencies'] as const) {\n for (const [name, declared] of Object.entries(\n (json[field] ?? {}) as Record<string, string>,\n )) {\n if (String(declared).startsWith('catalog:')) {\n referenced.add(name);\n }\n }\n }\n });\n return referenced;\n};\n\n/** Pip specifier as `pip-requirements-js` reports it. */\ninterface PyVersionSpec {\n readonly operator: string;\n readonly version: string;\n}\n\n/**\n * Whether the declared specifiers already permit the vended version, so\n * rewriting them would discard the user's range without changing what resolves.\n *\n * This mirrors the TypeScript side: an exact pin is the case to upgrade, a range\n * that already reaches the vended version is left alone, and a range that falls\n * short is moved up.\n *\n * A `*` wildcard or a specifier semver can't read counts as already permitting,\n * so anything not understood is left as the user wrote it.\n */\nconst pyRangePermitsVended = (\n specs: readonly PyVersionSpec[],\n vended: string,\n): boolean =>\n specs.every((spec) => {\n if (spec.version.includes('*')) {\n return true;\n }\n const bound = coerce(spec.version, { includePrerelease: true });\n if (!bound) {\n return true;\n }\n switch (spec.operator) {\n // An exact pin permits only itself, so a differing vended version is an\n // upgrade to apply.\n case '==':\n case '===':\n return satisfies(vended, `=${bound.version}`, {\n includePrerelease: true,\n });\n // `~=1.2.3` allows the patch series; `~=1.2` the minor series.\n case '~=':\n return satisfies(\n vended,\n spec.version.split('.').length > 2\n ? `~${bound.version}`\n : `^${bound.version}`,\n { includePrerelease: true },\n );\n case '>=':\n case '>':\n case '<=':\n case '<':\n return satisfies(vended, `${spec.operator}${bound.version}`, {\n includePrerelease: true,\n });\n // `!=` only excludes, so it never blocks the vended version by itself.\n case '!=':\n return true;\n default:\n return true;\n }\n });\n\n/**\n * Upgrade a pip requirement to the vended version, or return it unchanged.\n *\n * Parsed rather than pattern-matched so extras and operators are read the way\n * `uv` reads them. A requirement whose specifiers already permit the vended\n * version keeps them; one that falls short is replaced with an exact pin, which\n * is what the generators write.\n */\nconst syncPyRequirement = (\n owned: OwnedDependencies,\n requirement: string,\n): string => {\n const parsed = parsePipRequirementsLine(requirement);\n if (parsed?.type !== 'ProjectName' || !parsed.versionSpec?.length) {\n return requirement;\n }\n\n const name = parsed.extras?.length\n ? `${parsed.name}[${parsed.extras.join(',')}]`\n : parsed.name;\n const vended = vendedPyVersion(owned, name);\n if (!vended) {\n return requirement;\n }\n\n const specs = parsed.versionSpec as readonly PyVersionSpec[];\n // Never move a version backwards: a pin above what this release vends is the\n // user's, and a range already reaching it is theirs to keep.\n const [first] = specs;\n const isExactPin =\n specs.length === 1 && (first.operator === '==' || first.operator === '===');\n if (isExactPin && !isVendedUpgrade(vended, first.version)) {\n return requirement;\n }\n if (!isExactPin && pyRangePermitsVended(specs, vended)) {\n return requirement;\n }\n return `${name}==${vended}`;\n};\n\n/** Sync pins in every `pyproject.toml`, dependencies and groups alike. */\nconst syncPyProjects = (tree: Tree, owned: OwnedDependencies): string[] => {\n const updated: string[] = [];\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('pyproject.toml')) {\n return;\n }\n\n let changed = false;\n const syncRequirements = (requirements: unknown): unknown =>\n Array.isArray(requirements)\n ? requirements.map((requirement) => {\n if (typeof requirement !== 'string') {\n return requirement;\n }\n const synced = syncPyRequirement(owned, requirement);\n changed ||= synced !== requirement;\n return synced;\n })\n : requirements;\n\n updateToml(tree, path, (toml) => {\n const project = toml.project as Record<string, unknown> | undefined;\n if (project?.dependencies) {\n project.dependencies = syncRequirements(project.dependencies) as never;\n }\n const groups = toml['dependency-groups'] as\n | Record<string, unknown>\n | undefined;\n for (const group of Object.keys(groups ?? {})) {\n groups![group] = syncRequirements(groups![group]) as never;\n }\n return toml;\n });\n\n if (changed) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n\n/**\n * GritQL matching one provider's `version` in `required_providers`, scoped by\n * the sibling `source` so an alias or another provider's version can't match.\n *\n * `language hcl` is required — without it the pattern silently matches nothing.\n */\nconst providerVersionPattern = (provider: string, rewrite = ''): string =>\n `language hcl\\n\\`version = $version\\`${rewrite} where {` +\n ` $version <: within \\`{ source = \"hashicorp/${provider}\" $... }\\` }`;\n\n/** Version a provider currently declares, if it declares one. */\nconst declaredProviderVersion = async (\n tree: Tree,\n path: string,\n provider: string,\n): Promise<string | undefined> => {\n const [bound] =\n (await captureAllGritQLVariable(\n tree,\n path,\n providerVersionPattern(provider),\n 'version',\n )) ?? [];\n // The binding is the quoted version, e.g. `\"6.40.0\"`.\n return bound?.replace(/^\"|\"$/g, '');\n};\n\n/** Sync vended provider versions in every `.tf` file. */\nconst syncTerraformProviders = async (tree: Tree): Promise<string[]> => {\n const updated: string[] = [];\n const terraformFiles: string[] = [];\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (path.endsWith('.tf')) {\n terraformFiles.push(path);\n }\n });\n\n for (const path of terraformFiles) {\n let changed = false;\n for (const [provider, vended] of Object.entries(TERRAFORM_VERSIONS)) {\n const declared = await declaredProviderVersion(tree, path, provider);\n if (!declared || !isVendedUpgrade(vended, declared)) {\n continue;\n }\n changed =\n (await applyGritQL(\n tree,\n path,\n providerVersionPattern(provider, ` => \\`version = \"${vended}\"\\``),\n )) || changed;\n }\n if (changed) {\n updated.push(path);\n }\n }\n\n return updated;\n};\n\n/**\n * The projects this plugin generates infrastructure into, per provider.\n *\n * A runtime is not a dependency, so there is no per-package ownership to consult —\n * these directories are the scope. A Lambda a user defined in their own project\n * keeps whatever runtime they chose, even though it is the same shape.\n */\nconst OWNED_INFRA_DIRS: Readonly<Record<VendedIac, string>> = {\n cdk: `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}`,\n terraform: `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}`,\n};\n\n/**\n * Sync the versions this release vends, for the dependencies the workspace's\n * generators own.\n */\nexport const syncVendedVersions = async (\n tree: Tree,\n): Promise<MigrationReturnObject> => {\n const nextSteps: string[] = [];\n const owned = await ownedDependencies(tree);\n\n const packageJsons = syncPackageJsons(tree, owned);\n const catalogs = syncOrphanCatalogEntries(tree, owned);\n const overrides = syncOverrides(tree, owned);\n const pyProjects = syncPyProjects(tree, owned);\n const terraformFiles = await syncTerraformProviders(tree);\n const lambdaRuntimes = await syncLambdaRuntimes(tree, OWNED_INFRA_DIRS);\n const projectPython = syncProjectPythonVersion(tree);\n const pythonBundles = syncPythonBundleVersion(tree);\n const skippedEmbedded = await syncEmbeddedVersions(tree, owned);\n await syncMetricsVersion(tree);\n\n // Lock files are left to the user: `nx migrate` only installs when the root\n // manifest changes, and never runs `uv` or `terraform`.\n if (catalogs.length > 0 || packageJsons.length > 0 || overrides.length > 0) {\n nextSteps.push(\n `TypeScript dependency versions were updated. Run \\`${buildInstallCommand(\n detectPackageManager(tree.root),\n )}\\` to update the lock file.`,\n );\n }\n if (\n pyProjects.length > 0 ||\n projectPython.length > 0 ||\n pythonBundles.length > 0\n ) {\n nextSteps.push(\n `Python dependency versions were updated in ${[...new Set([...pyProjects, ...projectPython, ...pythonBundles])].join(', ')}. Run \\`uv sync\\` to update uv.lock.`,\n );\n }\n // A runtime the sync recognised is simply moved; one it doesn't recognise is\n // the user's choice, so it is reported rather than rewritten.\n if (lambdaRuntimes.diverged.length > 0) {\n nextSteps.push(\n `Lambda runtimes in ${[...new Set(lambdaRuntimes.diverged)].join(', ')} have diverged from the generated shape and were left untouched. Set them to \\`${cdkLambdaRuntime('node')}\\` (CDK) or \\`\"${terraformLambdaRuntime('node')}\"\\` (Terraform) if you want them on the runtime this release vends.`,\n );\n }\n if (terraformFiles.length > 0) {\n nextSteps.push(\n `Terraform provider versions were updated in ${terraformFiles.length} file(s). Run \\`terraform init -upgrade\\` in each Terraform project to update its lock file.`,\n );\n }\n // A synced embedded pin needs no next step — it is read the next time the thing\n // holding it runs. A file the sync left alone does: its versions are still the\n // old ones, and only the user can reconcile that.\n if (skippedEmbedded.length > 0) {\n nextSteps.push(\n `Version pins were left as they are in ${skippedEmbedded.join(', ')}, which repeat a pin more times than this migration rewrites at once. Update them by hand.`,\n );\n }\n\n // Without this the workspace's own format check fails on the migrated files.\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n};\n"],"names":["addDependenciesToPackageJson","detectPackageManager","readJson","updateJson","visitNotIgnoredFiles","yaml","getCatalogManager","parsePipRequirementsLine","coerce","parse","satisfies","validRange","applyGritQL","captureAllGritQLVariable","buildInstallCommand","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","updateToml","cdkLambdaRuntime","PY_VERSIONS","TERRAFORM_VERSIONS","TS_VERSIONS","terraformLambdaRuntime","isNxPackage","ownedDependencies","syncEmbeddedVersions","syncLambdaRuntimes","syncMetricsVersion","syncProjectPythonVersion","syncPythonBundleVersion","isVendedUpgrade","YAML_WORKSPACE_FILES","vendedTsVersion","owned","name","ts","has","undefined","vendedPyVersion","py","replace","REFERENCE_PROTOCOL","isSyncableSpecifier","tree","declared","test","startsWith","root","alreadyPermitsVended","packageName","vended","range","resolved","resolveCatalogReference","trim","declaredVendedPackages","packageJsonPath","json","pick","field","Object","fromEntries","entries","flatMap","dependencies","devDependencies","syncPackageJsons","updated","path","endsWith","keys","length","before","read","catalogsBefore","readCatalogFiles","push","map","exists","join","syncOrphanCatalogEntries","referenced","referencedCatalogPackages","syncCatalog","catalog","changed","String","catalogFile","load","values","catalogs","some","Boolean","write","dump","quotingType","overriddenPackage","key","segments","split","reduce","acc","part","previous","includes","at","lastIndexOf","slice","overrideLocations","manifestFields","workspaceFile","syncOverrides","syncOverrideTree","overrides","value","pnpm","contents","Set","add","pyRangePermitsVended","specs","every","spec","version","bound","includePrerelease","operator","syncPyRequirement","requirement","parsed","type","versionSpec","extras","first","isExactPin","syncPyProjects","syncRequirements","requirements","Array","isArray","synced","toml","project","groups","group","providerVersionPattern","provider","rewrite","declaredProviderVersion","syncTerraformProviders","terraformFiles","OWNED_INFRA_DIRS","cdk","terraform","syncVendedVersions","nextSteps","packageJsons","pyProjects","lambdaRuntimes","projectPython","pythonBundles","skippedEmbedded","diverged"],"mappings":"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"}