@aws/nx-plugin 1.0.0-rc.71 → 1.0.0-rc.73
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/LICENSE-THIRD-PARTY +210 -730
- package/migrations.json +34 -19
- package/package.json +4 -4
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/agentcore-harness/generator.d.ts +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/infra/app/generator.d.ts +1 -1
- package/src/init/generator.d.ts +1 -1
- package/src/license/config.d.ts +9 -0
- package/src/license/config.js +28 -0
- package/src/license/config.js.map +1 -1
- package/src/license/dependency-check/collectors/collector.js.map +1 -1
- package/src/license/dependency-check/evaluator.js +55 -10
- package/src/license/dependency-check/evaluator.js.map +1 -1
- package/src/license/generator.js +3 -17
- package/src/license/generator.js.map +1 -1
- package/src/license/known-exceptions.d.ts +0 -1
- package/src/license/known-exceptions.js +1 -23
- package/src/license/known-exceptions.js.map +1 -1
- package/src/migrations/latest/apt-security-updates-in-container-images/__snapshots__/migration.spec.ts.snap +90 -0
- package/src/migrations/latest/apt-security-updates-in-container-images/metadata.json +3 -0
- package/src/migrations/latest/apt-security-updates-in-container-images/migration.js +90 -0
- package/src/migrations/latest/apt-security-updates-in-container-images/migration.js.map +1 -0
- package/src/migrations/latest/remove-mcp-inspector-license-exceptions/metadata.json +3 -0
- package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.d.ts +6 -0
- package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js +38 -0
- package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.67/0001-smithy-server-package-rename/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.68/0001-translate-script-whole-file-writes/migration.js.map +1 -0
- package/src/migrations/{latest/py-agent-a2a-lifespan-construction → v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction}/migration.js +14 -2
- package/src/migrations/v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.d.ts +2 -0
- package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js +308 -0
- package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/preset/generator.d.ts +1 -1
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +626 -10
- package/src/py/agent/__snapshots__/generator.core.spec.ts.snap +186 -0
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +55 -11
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +669 -4
- package/src/py/agent/a2a-connection/generator.js +5 -11
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/files/deploy/Dockerfile.template +7 -0
- package/src/py/agent/files/langchain/common/__init__.py.template +0 -0
- package/src/py/agent/files/langchain/common/agent.py.template +3 -3
- package/src/py/agent/files/langchain/common/session.py.template +61 -0
- package/src/py/agent/files/strands/ag-ui/main.py.template +5 -1
- package/src/py/agent/files/strands/common/agent.py.template +9 -2
- package/src/py/agent/files/strands/common/session.py.template +36 -0
- package/src/py/agent/generator.d.ts +11 -1
- package/src/py/agent/generator.js +78 -28
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/py/agent/react-connection/generator.d.ts +1 -1
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +1 -1
- package/src/py/agent/schema.json +3 -3
- package/src/py/fast-api/react/generator.d.ts +1 -1
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +5 -5
- package/src/py/mcp-server/files/deploy/Dockerfile.template +7 -0
- package/src/py/mcp-server/generator.js +8 -3
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +7 -5
- package/src/py/rdb/generator.js +36 -2
- package/src/py/rdb/generator.js.map +1 -1
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +14 -14
- package/src/smithy/project/generator.d.ts +1 -1
- package/src/smithy/react-connection/generator.d.ts +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/terraform/project/generator.d.ts +1 -1
- package/src/trpc/react/generator.d.ts +1 -1
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +36 -8
- package/src/ts/agent/a2a-connection/generator.d.ts +1 -1
- package/src/ts/agent/a2a-connection/generator.js +4 -2
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/files/deploy/Dockerfile.template +7 -0
- package/src/ts/agent/gateway-connection/generator.d.ts +1 -1
- package/src/ts/agent/mcp-connection/generator.d.ts +1 -1
- package/src/ts/agent/react-connection/generator.d.ts +1 -1
- package/src/ts/astro-docs/generator.d.ts +1 -1
- package/src/ts/dcr-proxy/generator.d.ts +1 -1
- package/src/ts/dynamodb/generator.d.ts +1 -1
- package/src/ts/lambda-function/generator.d.ts +1 -1
- package/src/ts/lib/generator.d.ts +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/mcp-server/files/Dockerfile.template +7 -0
- package/src/ts/mcp-server/generator.js +8 -3
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/nx-generator/generator.d.ts +1 -1
- package/src/ts/nx-migration/generator.d.ts +1 -1
- package/src/ts/nx-plugin/generator.d.ts +1 -1
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +8 -6
- package/src/ts/rdb/generator.d.ts +1 -1
- package/src/ts/rdb/generator.js +29 -2
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/react-website/agui/generator.d.ts +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +15 -15
- package/src/ts/react-website/app/generator.js +4 -2
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +1 -1
- package/src/utils/agent-connection/agent-connection.d.ts +10 -0
- package/src/utils/agent-connection/agent-connection.js +20 -9
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +5 -3
- package/src/utils/agent-connection/files/py-core-langchain/s3/s3_checkpoint_saver_langchain.py.template +360 -0
- package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +2 -4
- package/src/utils/agent-connection/files/py-core-strands/base/tool_errors_strands.py.template +24 -0
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +113 -13
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +76 -7
- package/src/utils/ast.d.ts +29 -0
- package/src/utils/ast.js +31 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/metrics.js +2 -2
- package/src/utils/metrics.js.map +1 -1
- package/src/utils/versions.d.ts +75 -72
- package/src/utils/versions.js +72 -69
- package/src/utils/versions.js.map +1 -1
- package/src/migrations/latest/py-agent-a2a-httpx-client-per-call/migration.js.map +0 -1
- package/src/migrations/latest/py-agent-a2a-lifespan-construction/migration.js.map +0 -1
- package/src/migrations/latest/smithy-server-package-rename/migration.js.map +0 -1
- package/src/migrations/latest/translate-script-whole-file-writes/migration.js.map +0 -1
- package/src/py/rdb/files/__name__/__init__.py.template +0 -3
- package/src/py/rdb/files/config.json.template +0 -14
- package/src/ts/rdb/files/config.json.template +0 -14
- package/src/ts/rdb/files/src/index.ts.template +0 -1
- /package/src/migrations/latest/{py-agent-a2a-httpx-client-per-call → apt-security-updates-in-container-images}/migration.d.ts +0 -0
- /package/src/migrations/{latest/smithy-server-package-rename → v1.0.0-rc.67/0001-smithy-server-package-rename}/metadata.json +0 -0
- /package/src/migrations/{latest/py-agent-a2a-lifespan-construction → v1.0.0-rc.67/0001-smithy-server-package-rename}/migration.d.ts +0 -0
- /package/src/migrations/{latest/smithy-server-package-rename → v1.0.0-rc.67/0001-smithy-server-package-rename}/migration.js +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/build-system-prompt.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/build-user-prompt.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/config-path.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/file-to-translate.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/get-files-to-translate.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/header.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/log.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/main-call.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/main.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/project-root.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/run-with-concurrency.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/scripts-dir.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/translate-file-for-language.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/already-migrated.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/build-system-prompt.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/build-user-prompt.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/config-path.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/file-to-translate.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/get-files-to-translate.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/log.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/main-call.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/main.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/project-root.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/run-with-concurrency.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/translate-file-for-language.grit +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/metadata.json +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/migration.d.ts +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/migration.js +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/test-fixtures/released-script-first.ts.fixture +0 -0
- /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/test-fixtures/released-script.ts.fixture +0 -0
- /package/src/migrations/{latest/py-agent-a2a-lifespan-construction → v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction}/metadata.json +0 -0
- /package/src/migrations/{latest/smithy-server-package-rename → v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction}/migration.d.ts +0 -0
- /package/src/migrations/{latest/py-agent-a2a-httpx-client-per-call → v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call}/metadata.json +0 -0
- /package/src/migrations/{latest/py-agent-a2a-httpx-client-per-call → v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call}/migration.js +0 -0
package/migrations.json
CHANGED
|
@@ -2,25 +2,15 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/schema",
|
|
3
3
|
"name": "@aws/nx-plugin",
|
|
4
4
|
"generators": {
|
|
5
|
-
"latest-
|
|
6
|
-
"version": "1.0.0-rc.
|
|
7
|
-
"description": "
|
|
8
|
-
"implementation": "./src/migrations/latest/
|
|
9
|
-
},
|
|
10
|
-
"latest-translate-script-whole-file-writes": {
|
|
11
|
-
"version": "1.0.0-rc.68",
|
|
12
|
-
"description": "Update the docs translate script to write whole translated files rather than editing them in place",
|
|
13
|
-
"implementation": "./src/migrations/latest/translate-script-whole-file-writes/migration"
|
|
14
|
-
},
|
|
15
|
-
"latest-py-agent-a2a-lifespan-construction": {
|
|
16
|
-
"version": "1.0.0-rc.70",
|
|
17
|
-
"description": "Move py#agent A2A agent construction (Strands and LangChain) out of module import time and into a FastAPI lifespan handler, stored on app.state; also updates with_session_id/session_id_context to use Generator instead of the deprecated Iterator return type",
|
|
18
|
-
"implementation": "./src/migrations/latest/py-agent-a2a-lifespan-construction/migration"
|
|
5
|
+
"latest-remove-mcp-inspector-license-exceptions": {
|
|
6
|
+
"version": "1.0.0-rc.73",
|
|
7
|
+
"description": "Remove the obsolete MCP Inspector license exceptions",
|
|
8
|
+
"implementation": "./src/migrations/latest/remove-mcp-inspector-license-exceptions/migration"
|
|
19
9
|
},
|
|
20
|
-
"latest-
|
|
21
|
-
"version": "1.0.0-rc.
|
|
22
|
-
"description": "
|
|
23
|
-
"implementation": "./src/migrations/latest/
|
|
10
|
+
"latest-apt-security-updates-in-container-images": {
|
|
11
|
+
"version": "1.0.0-rc.73",
|
|
12
|
+
"description": "Apply the distribution's security updates in vended agent / MCP server container images",
|
|
13
|
+
"implementation": "./src/migrations/latest/apt-security-updates-in-container-images/migration"
|
|
24
14
|
},
|
|
25
15
|
"v1.0.0-rc.50-0001-modernize-function-props-cast": {
|
|
26
16
|
"version": "1.0.0-rc.50",
|
|
@@ -117,8 +107,33 @@
|
|
|
117
107
|
"description": "Replace the deprecated inlineDynamicImports rolldown output option with codeSplitting",
|
|
118
108
|
"implementation": "./src/migrations/v1.0.0-rc.65/0002-rolldown-code-splitting/migration"
|
|
119
109
|
},
|
|
120
|
-
"
|
|
110
|
+
"v1.0.0-rc.67-0001-smithy-server-package-rename": {
|
|
111
|
+
"version": "1.0.0-rc.67",
|
|
112
|
+
"description": "Move Smithy APIs onto the renamed @smithy/server-* packages",
|
|
113
|
+
"implementation": "./src/migrations/v1.0.0-rc.67/0001-smithy-server-package-rename/migration"
|
|
114
|
+
},
|
|
115
|
+
"v1.0.0-rc.68-0001-translate-script-whole-file-writes": {
|
|
116
|
+
"version": "1.0.0-rc.68",
|
|
117
|
+
"description": "Update the docs translate script to write whole translated files rather than editing them in place",
|
|
118
|
+
"implementation": "./src/migrations/v1.0.0-rc.68/0001-translate-script-whole-file-writes/migration"
|
|
119
|
+
},
|
|
120
|
+
"v1.0.0-rc.70-0001-py-agent-a2a-lifespan-construction": {
|
|
121
|
+
"version": "1.0.0-rc.70",
|
|
122
|
+
"description": "Move py#agent A2A agent construction (Strands and LangChain) out of module import time and into a FastAPI lifespan handler, stored on app.state; also updates with_session_id/session_id_context to use Generator instead of the deprecated Iterator return type",
|
|
123
|
+
"implementation": "./src/migrations/v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction/migration"
|
|
124
|
+
},
|
|
125
|
+
"v1.0.0-rc.71-0001-py-agent-a2a-httpx-client-per-call": {
|
|
121
126
|
"version": "1.0.0-rc.71",
|
|
127
|
+
"description": "Rebuild the httpx.AsyncClient (and Strands A2AAgent) per A2A delegate call instead of reusing one built at factory time, fixing a RuntimeError: Event loop is closed on the second call through a shared client",
|
|
128
|
+
"implementation": "./src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration"
|
|
129
|
+
},
|
|
130
|
+
"v1.0.0-rc.72-0001-py-agent-session-management-support": {
|
|
131
|
+
"version": "1.0.0-rc.72",
|
|
132
|
+
"description": "Add session management support to py#agent",
|
|
133
|
+
"implementation": "./src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration"
|
|
134
|
+
},
|
|
135
|
+
"sync-vended-versions": {
|
|
136
|
+
"version": "1.0.0-rc.73",
|
|
122
137
|
"description": "Sync vended dependency versions and the tracked plugin version to those vended by this release",
|
|
123
138
|
"implementation": "./src/utils/version-upgrade-migration/migration"
|
|
124
139
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/nx-plugin",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.73",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/awslabs/nx-plugin-for-aws.git",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@apidevtools/swagger-parser": "12.1.0",
|
|
43
|
-
"@astral-sh/ruff-wasm-nodejs": "0.16.
|
|
43
|
+
"@astral-sh/ruff-wasm-nodejs": "0.16.3",
|
|
44
44
|
"@biomejs/js-api": "6.0.0",
|
|
45
|
-
"@biomejs/wasm-nodejs": "2.5.
|
|
45
|
+
"@biomejs/wasm-nodejs": "2.5.8",
|
|
46
46
|
"@getgrit/gritql": "0.0.3",
|
|
47
47
|
"@iarna/toml": "2.2.5",
|
|
48
48
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@nx/js": "23.1.1",
|
|
51
51
|
"@nx/react": "23.1.1",
|
|
52
52
|
"@nx/vite": "23.1.1",
|
|
53
|
-
"@nxlv/python": "
|
|
53
|
+
"@nxlv/python": "23.0.0",
|
|
54
54
|
"@phenomnomnominal/tsquery": "6.2.0",
|
|
55
55
|
"@types/estree": "1.0.9",
|
|
56
56
|
"@types/js-yaml": "4.0.9",
|
|
@@ -40,7 +40,7 @@ export declare const DEPENDENCIES: import("../utils/declared-dependencies").Depe
|
|
|
40
40
|
readonly name: "@types/node";
|
|
41
41
|
} & {
|
|
42
42
|
versionOnly: true;
|
|
43
|
-
}], readonly import("../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", AgentCoreHarnessMetadata>[]>;
|
|
43
|
+
}], readonly import("../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aiosqlite" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "langgraph-checkpoint-aws" | "langgraph-checkpoint-sqlite" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", AgentCoreHarnessMetadata>[]>;
|
|
44
44
|
export declare const AGENTCORE_HARNESS_GENERATOR_INFO: NxGeneratorInfo;
|
|
45
45
|
export declare const agentcoreHarnessGenerator: (tree: Tree, options: AgentcoreHarnessGeneratorSchema) => Promise<GeneratorCallback>;
|
|
46
46
|
/**
|
|
@@ -56,7 +56,7 @@ exports[`infra generator > should configure Checkov target correctly > checkov-t
|
|
|
56
56
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
57
57
|
],
|
|
58
58
|
"options": {
|
|
59
|
-
"command": "uvx --from checkov==3.3.
|
|
59
|
+
"command": "uvx --from checkov==3.3.11 checkov --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
60
60
|
},
|
|
61
61
|
"outputs": [
|
|
62
62
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -150,7 +150,7 @@ exports[`infra generator > should configure project.json with correct targets >
|
|
|
150
150
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
151
151
|
],
|
|
152
152
|
"options": {
|
|
153
|
-
"command": "uvx --from checkov==3.3.
|
|
153
|
+
"command": "uvx --from checkov==3.3.11 checkov --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
154
154
|
},
|
|
155
155
|
"outputs": [
|
|
156
156
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -745,7 +745,7 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
745
745
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
746
746
|
],
|
|
747
747
|
"options": {
|
|
748
|
-
"command": "uvx --from checkov==3.3.
|
|
748
|
+
"command": "uvx --from checkov==3.3.11 checkov --config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation",
|
|
749
749
|
},
|
|
750
750
|
"outputs": [
|
|
751
751
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -47,7 +47,7 @@ export declare const DEPENDENCIES: import("../../utils/declared-dependencies").D
|
|
|
47
47
|
readonly when: (m: import("../../utils/shared-constructs-constants").IacMetadata) => boolean;
|
|
48
48
|
} & {
|
|
49
49
|
versionOnly: true;
|
|
50
|
-
}], readonly import("../../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", Record<string, never>>[]>;
|
|
50
|
+
}], readonly import("../../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aiosqlite" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "langgraph-checkpoint-aws" | "langgraph-checkpoint-sqlite" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", Record<string, never>>[]>;
|
|
51
51
|
export declare const INFRA_APP_GENERATOR_INFO: NxGeneratorInfo;
|
|
52
52
|
export declare function tsInfraGenerator(tree: Tree, schema: TsInfraGeneratorSchema): Promise<GeneratorCallback>;
|
|
53
53
|
export default tsInfraGenerator;
|
package/src/init/generator.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare const DEPENDENCIES: import("../utils/declared-dependencies").Depe
|
|
|
17
17
|
readonly name: "typescript";
|
|
18
18
|
}, {
|
|
19
19
|
readonly name: "@biomejs/biome";
|
|
20
|
-
}], readonly import("../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", Record<string, never>>[]>;
|
|
20
|
+
}], readonly import("../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aiosqlite" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "langgraph-checkpoint-aws" | "langgraph-checkpoint-sqlite" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", Record<string, never>>[]>;
|
|
21
21
|
export declare const INIT_GENERATOR_INFO: NxGeneratorInfo;
|
|
22
22
|
/**
|
|
23
23
|
* Configure an existing Nx workspace to use the @aws/nx-plugin.
|
package/src/license/config.d.ts
CHANGED
|
@@ -58,6 +58,15 @@ export declare const ensureDependencyCheckBlock: (tree: Tree, options?: EnsureDe
|
|
|
58
58
|
* block, so an `exceptions` array elsewhere in the file isn't matched.
|
|
59
59
|
*/
|
|
60
60
|
export declare const ensureLicenseExceptions: (tree: Tree, exceptions: DependencyCheckException[]) => Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Remove the exceptions for the named packages from
|
|
63
|
+
* `license.dependencies.exceptions`, whatever reason or spdx each carries.
|
|
64
|
+
* Packages that aren't listed are left alone, as are all other exceptions.
|
|
65
|
+
*
|
|
66
|
+
* Scoped to `dependencies: { $scope }` like {@link ensureLicenseExceptions}, so
|
|
67
|
+
* an `exceptions` array elsewhere in the file isn't matched.
|
|
68
|
+
*/
|
|
69
|
+
export declare const removeLicenseExceptions: (tree: Tree, packages: string[]) => Promise<void>;
|
|
61
70
|
/**
|
|
62
71
|
* Add `pythonCollector()` to `license.dependencies.collectors`, unless one is
|
|
63
72
|
* already configured.
|
package/src/license/config.js
CHANGED
|
@@ -380,6 +380,34 @@ import { addDependencyToTargetIfNotPresent } from "../utils/nx.js";
|
|
|
380
380
|
await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);
|
|
381
381
|
}
|
|
382
382
|
};
|
|
383
|
+
/**
|
|
384
|
+
* Remove the exceptions for the named packages from
|
|
385
|
+
* `license.dependencies.exceptions`, whatever reason or spdx each carries.
|
|
386
|
+
* Packages that aren't listed are left alone, as are all other exceptions.
|
|
387
|
+
*
|
|
388
|
+
* Scoped to `dependencies: { $scope }` like {@link ensureLicenseExceptions}, so
|
|
389
|
+
* an `exceptions` array elsewhere in the file isn't matched.
|
|
390
|
+
*/ export const removeLicenseExceptions = async (tree, packages)=>{
|
|
391
|
+
if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;
|
|
392
|
+
const { applyGritQL } = await import("../utils/ast.js");
|
|
393
|
+
let modified = false;
|
|
394
|
+
for (const pkg of packages){
|
|
395
|
+
const removed = await applyGritQL(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME, `\`dependencies: { $scope }\` where {
|
|
396
|
+
$scope <: contains bubble or {
|
|
397
|
+
\`[$items]\` where {
|
|
398
|
+
$items <: some bubble \`{ $props }\` as $entry where {
|
|
399
|
+
$props <: contains \`package: ${JSON.stringify(pkg)}\`,
|
|
400
|
+
$entry => .
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}`);
|
|
405
|
+
modified ||= removed;
|
|
406
|
+
}
|
|
407
|
+
if (modified) {
|
|
408
|
+
await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
383
411
|
/**
|
|
384
412
|
* Add `pythonCollector()` to `license.dependencies.collectors`, unless one is
|
|
385
413
|
* already configured.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/license/config.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type ProjectConfiguration,\n readProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n readAwsNxPluginConfig,\n updateAwsNxPluginConfig,\n} from '../utils/config/utils';\nimport { formatFilesInSubtree } from '../utils/format';\nimport { addDependencyToTargetIfNotPresent } from '../utils/nx';\nimport type {\n CommentSyntax,\n LicenseConfig,\n LicenseSourceConfig,\n} from './config-types';\nimport type { DependencyCheckException } from './dependency-check/types';\nimport type { SPDXLicenseIdentifier } from './schema';\n\n/**\n * Licenses containing a placeholder for the copyright year.\n */\nconst LICENSES_WITH_YEAR: Set<SPDXLicenseIdentifier> = new Set(['MIT']);\n\n/**\n * Defines the comment syntax for popular programming languages\n */\nexport const LANGUAGE_COMMENT_SYNTAX: { [ext: string]: CommentSyntax } = {\n // C++ style comments\n ...Object.fromEntries(\n [\n // Node\n 'js',\n 'ts',\n 'cjs',\n 'mjs',\n 'cts',\n 'mts',\n // React\n 'jsx',\n 'tsx',\n // Web\n 'sass',\n 'scss',\n 'php',\n // Java\n 'java',\n // TypeSpec\n 'tsp',\n // Golang\n 'go',\n // Rust\n 'rs',\n // C and C++\n 'c',\n 'cpp',\n 'cxx',\n 'cc',\n 'h',\n 'hpp',\n // C#\n 'cs',\n // Scala\n 'scala',\n 'sc',\n 'sbt',\n // Kotlin\n 'kt',\n // Swift\n 'swift',\n ].map((ext) => [ext, { line: '//', block: { start: '/*', end: '*/' } }]),\n ),\n // Bash style comments\n ...Object.fromEntries(\n [\n // Bash\n 'sh',\n // Perl\n 'pl',\n // YAML\n 'yaml',\n 'yml',\n // R\n 'r',\n ].map((ext) => [ext, { line: '#' }]),\n ),\n // Docker\n Dockerfile: { line: '#' },\n // Python\n py: { line: '#', block: { start: '\"\"\"', end: '\"\"\"' } },\n // Web\n html: { block: { start: '<!--', end: '-->' } },\n css: { block: { start: '/*', end: '*/' } },\n // Ruby\n rb: { line: '#', block: { start: '=begin', end: '=end' } },\n // F#\n ...Object.fromEntries(\n ['fs', 'fsx'].map((ext) => [\n ext,\n { line: '//', block: { start: '(*', end: '*)' } },\n ]),\n ),\n // Visual Basic\n vb: { line: \"' \" },\n // Lua\n lua: { line: '--', block: { start: '--[[', end: ']]' } },\n // PowerShell\n ps1: { line: '#', block: { start: '<#', end: '#>' } },\n psm1: { line: '#', block: { start: '<#', end: '#>' } },\n // Markdown\n md: { block: { start: '<!--', end: '-->' } },\n // Terraform\n tf: { line: '#', block: { start: '/*', end: '*/' } },\n // Smithy\n smithy: { line: '//' },\n};\n\n/**\n * Module specifier for the license helpers exported by this package, used by\n * imports written into the user's config file.\n */\nconst LICENSE_SDK_MODULE = '@aws/nx-plugin/sdk/license';\n\n/**\n * Build the object literal source for a dependency check exception.\n * `JSON.stringify` produces valid string literals for arbitrary text (quotes,\n * backslashes, newlines all escaped); prettier later normalises quote style.\n */\nconst exceptionLiteral = (exception: DependencyCheckException): string => {\n const parts = [`package: ${JSON.stringify(exception.package)}`];\n if (exception.version !== undefined) {\n parts.push(`version: ${JSON.stringify(exception.version)}`);\n }\n parts.push(`reason: ${JSON.stringify(exception.reason)}`);\n if (exception.spdx !== undefined) {\n parts.push(`spdx: ${JSON.stringify(exception.spdx)}`);\n }\n return `{ ${parts.join(', ')} }`;\n};\n\n/**\n * GritQL `or` block that appends `$ins` (the insert placeholder) to the named\n * array inside the matched `$scope`, without ever producing an array hole:\n * - empty `key: []` → `key: [$ins]` (a list-append `+=` does not match an\n * empty array, so the empty case is rewritten directly)\n * - otherwise → list-append `+=` of `, $ins`; the leading comma is the\n * element separator and `+=` places it correctly for single inline,\n * single-with-trailing-comma and multi-element arrays alike\n */\nconst appendToArray = (key: string, ins: string) =>\n `or {\n $scope <: contains \\`${key}: []\\` => \\`${key}: [${ins}]\\`,\n $scope <: contains \\`${key}: [$items]\\` where { $items += \\`, ${ins}\\` }\n }`;\n\n/**\n * Insert `property` (TypeScript source like `dependencies: { ... }`) as the\n * first property of the `license` object literal.\n *\n * Prepending is comma-safe for every shape — empty `{}`, single- or multi-line.\n * `+=` appending is not: it omits the separator when the last property's value\n * is an object/array literal (e.g. `source: { ... }`), corrupting the file. The\n * property text is routed through a placeholder so its content never enters the\n * GritQL pattern. Returns true if the file changed (a `license` object existed).\n */\nconst prependLicenseProperty = async (\n tree: Tree,\n property: string,\n): Promise<boolean> => {\n const { insertViaGritQL, GRIT_INSERT_PLACEHOLDER } = await import(\n '../utils/ast'\n );\n\n // Non-empty license object: insert before the first existing property.\n const intoNonEmpty = await insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`license: { $props }\\` where { $props => \\`${GRIT_INSERT_PLACEHOLDER}, $props\\` }`,\n property,\n );\n if (intoNonEmpty) return true;\n\n // Empty license object: `{ $props }` doesn't match `{}`, so fill it directly.\n return insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`license: {}\\` => \\`license: { ${GRIT_INSERT_PLACEHOLDER} }\\``,\n property,\n );\n};\n\n/**\n * Whether `license.dependencies` (the dependency-check block) is configured.\n * Scoped within `license` so a `dependencies`-shaped object elsewhere in the\n * file isn't mistaken for it.\n */\nconst hasDependenciesBlock = async (tree: Tree): Promise<boolean> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return false;\n const { matchGritQL } = await import('../utils/ast');\n return matchGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n '`license: { $l }` where { $l <: contains `dependencies: $_` }',\n );\n};\n\n/**\n * Workspace-root npm-ecosystem lockfiles. Each is added to the license-check\n * cache inputs only when present, so the cache invalidates on dependency\n * changes without listing lockfiles for package managers the workspace doesn't\n * use.\n */\nconst NPM_LOCKFILES = [\n 'pnpm-lock.yaml',\n 'yarn.lock',\n 'package-lock.json',\n 'bun.lockb',\n];\n\n/**\n * Recompute the `inputs` of the root `license-check` target from what's\n * currently in the workspace: the present npm lockfiles, the config file, and\n * a recursive uv.lock glob when the dependency check uses a Python collector.\n *\n * The uv lockfile is keyed off the collector (not file presence) because it is\n * created by `uv` *after* the generator runs, and may live in a subdirectory of\n * a uv workspace. Callers run this whenever they change the relevant state, so\n * the inputs stay correct regardless of generator order. No-op if the\n * license-check target doesn't exist yet.\n */\nexport const updateLicenseCheckTargetInputs = async (\n tree: Tree,\n): Promise<void> => {\n const rootProjectJsonPath = 'project.json';\n if (!tree.exists(rootProjectJsonPath)) return;\n\n const rootProject = JSON.parse(tree.read(rootProjectJsonPath, 'utf-8')!);\n const target = rootProject.targets?.['license-check'];\n if (!target) return;\n\n const inputs = NPM_LOCKFILES.filter((f) => tree.exists(f)).map(\n (f) => `{workspaceRoot}/${f}`,\n );\n\n if (await hasPythonCollector(tree)) {\n inputs.push('{workspaceRoot}/**/uv.lock');\n }\n\n inputs.push('{workspaceRoot}/aws-nx-plugin.config.mts');\n\n target.inputs = inputs;\n tree.write(rootProjectJsonPath, JSON.stringify(rootProject, null, 2));\n};\n\n/**\n * Whether the dependency check config has a `pythonCollector` configured.\n */\nconst hasPythonCollector = async (tree: Tree): Promise<boolean> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return false;\n const { matchGritQL } = await import('../utils/ast');\n return matchGritQL(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME, '`pythonCollector`');\n};\n\n/**\n * The name of the project that owns the root `license-check` target, or\n * undefined if no project defines it.\n */\nconst findLicenseCheckProjectName = (tree: Tree): string | undefined => {\n for (const [name, config] of getProjects(tree)) {\n if (config.targets?.['license-check']) return name;\n }\n return undefined;\n};\n\n/**\n * Make a project's `lint` target depend on the root `license-check` target, so\n * license checking runs as part of lint/build. No-op when the project has no\n * `lint` target or there's no license-check target to depend on. Idempotent.\n *\n * Callers format afterwards (generators call `formatFilesInSubtree` at the end),\n * so the rewritten project.json matches prettier.\n */\nexport const addLicenseCheckToLintTarget = (\n tree: Tree,\n projectName: string,\n): void => {\n const licenseCheckProject = findLicenseCheckProjectName(tree);\n if (!licenseCheckProject) return;\n\n let project: ProjectConfiguration;\n try {\n project = readProjectConfiguration(tree, projectName);\n } catch {\n return;\n }\n\n // Only wire projects that actually lint, and never the license-check project\n // itself (a target can't depend on its own project's target).\n if (!project.targets?.lint || projectName === licenseCheckProject) return;\n\n addDependencyToTargetIfNotPresent(project, 'lint', {\n projects: [licenseCheckProject],\n target: 'license-check',\n });\n updateProjectConfiguration(tree, projectName, project);\n};\n\n/**\n * Wire every project's `lint` target to the root `license-check` target.\n * Called by the license generator so existing projects pick up the dependency\n * regardless of the order generators ran in.\n */\nexport const addLicenseCheckToAllLintTargets = (tree: Tree): void => {\n for (const [name] of getProjects(tree)) {\n addLicenseCheckToLintTarget(tree, name);\n }\n};\n\nexport interface EnsureDependencyCheckBlockOptions {\n includeCollectors?: 'npm' | 'npm+python';\n}\n\n/**\n * Ensure the `dependencies` block (dependency license checking) exists within\n * the `license` config. If one already exists it is left untouched, so user\n * customizations survive.\n */\nexport const ensureDependencyCheckBlock = async (\n tree: Tree,\n options?: EnsureDependencyCheckBlockOptions,\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { addDestructuredImport } = await import('../utils/ast');\n\n if (await hasDependenciesBlock(tree)) {\n return;\n }\n\n const withPython = options?.includeCollectors === 'npm+python';\n const collectors = withPython\n ? 'collectors: [npmCollector(), pythonCollector()]'\n : 'collectors: [npmCollector()]';\n\n const block = `dependencies: { allow: DEFAULT_LICENSE_ALLOWLIST, ${collectors}, exceptions: [] }`;\n\n // Prepend the block as the first property of the license object. Prepending\n // (rather than `+=` appending) is comma-safe for every shape: GritQL's `+=`\n // omits the separator when the last existing property's value is an object\n // literal (e.g. `source: { ... }`), which would corrupt the file.\n const added = await prependLicenseProperty(tree, block);\n\n // Only add the imports if the block was actually written (i.e. a license\n // object literal existed to attach it to).\n if (added) {\n await addDestructuredImport(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n withPython\n ? ['DEFAULT_LICENSE_ALLOWLIST', 'npmCollector', 'pythonCollector']\n : ['DEFAULT_LICENSE_ALLOWLIST', 'npmCollector'],\n LICENSE_SDK_MODULE,\n );\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Ensure license exceptions are present in `license.dependencies.exceptions`.\n * An exception whose package is already listed is skipped (so existing reasons\n * are never overwritten). Other exceptions, collectors and the allowlist are\n * left untouched.\n *\n * The `dependencies: { $scope }` scope keeps edits within the dependency-check\n * block, so an `exceptions` array elsewhere in the file isn't matched.\n */\nexport const ensureLicenseExceptions = async (\n tree: Tree,\n exceptions: DependencyCheckException[],\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { insertViaGritQL, GRIT_INSERT_PLACEHOLDER } = await import(\n '../utils/ast'\n );\n\n if (!(await hasDependenciesBlock(tree))) {\n return;\n }\n\n let modified = false;\n for (const exception of exceptions) {\n const pkg = JSON.stringify(exception.package);\n const inserted = await insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`dependencies: { $scope }\\` where {\n $scope <: not contains \\`package: ${pkg}\\`,\n ${appendToArray('exceptions', GRIT_INSERT_PLACEHOLDER)}\n }`,\n exceptionLiteral(exception),\n );\n modified ||= inserted;\n }\n\n if (modified) {\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Add `pythonCollector()` to `license.dependencies.collectors`, unless one is\n * already configured.\n */\nexport const ensurePythonLicenseCollector = async (\n tree: Tree,\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { addDestructuredImport, insertViaGritQL, GRIT_INSERT_PLACEHOLDER } =\n await import('../utils/ast');\n\n if (!(await hasDependenciesBlock(tree))) {\n return;\n }\n\n const added = await insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`dependencies: { $scope }\\` where {\n $scope <: not contains \\`pythonCollector\\`,\n ${appendToArray('collectors', GRIT_INSERT_PLACEHOLDER)}\n }`,\n 'pythonCollector()',\n );\n\n if (added) {\n await addDestructuredImport(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n ['pythonCollector'],\n LICENSE_SDK_MODULE,\n );\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n // Now that a Python collector is configured, ensure uv.lock is a cache\n // input. Runs here (not only in the license generator) so it's added\n // whenever the collector is — e.g. when py#project runs after license.\n await updateLicenseCheckTargetInputs(tree);\n }\n};\n\n/**\n * Build the default `license.source` config for a given license\n */\nexport const defaultLicenseConfig = (\n spdx: SPDXLicenseIdentifier,\n copyrightHolder: string,\n): LicenseSourceConfig => {\n switch (spdx) {\n case 'ASL': {\n // For ASL, we use a \"box\" style license header\n const rawContent = [\n `Copyright ${copyrightHolder}. All Rights Reserved.`,\n '',\n 'Licensed under the Amazon Software License (the \"License\"). You may not use this file except in compliance',\n 'with the License. A copy of the License is located at',\n '',\n ' https://aws.amazon.com/asl/',\n '',\n 'or in the \"license\" file accompanying this file. This file is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES',\n 'OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions',\n 'and limitations under the License.',\n ];\n const maxLen = Math.max(...rawContent.map((line) => line.length));\n const lines = rawContent.map(\n (line) => `${line}${' '.repeat(maxLen - line.length)}`,\n );\n return {\n spdx,\n copyrightHolder,\n header: {\n content: { lines },\n format: {\n '**/*.{js,ts,jsx,tsx,mjs,mts}': {\n blockStart: `/***${'*'.repeat(maxLen)}**`,\n lineStart: ' * ',\n lineEnd: ' *',\n blockEnd: ` ***${'*'.repeat(maxLen)}**/`,\n },\n '**/*.{py,sh,tf}': {\n blockStart: `###${'#'.repeat(maxLen)}##`,\n lineStart: '# ',\n lineEnd: ' #',\n blockEnd: `###${'#'.repeat(maxLen)}##`,\n },\n },\n exclude: ['**/*.gen.*'],\n },\n };\n }\n default: {\n return {\n spdx,\n copyrightHolder,\n ...(LICENSES_WITH_YEAR.has(spdx)\n ? {\n copyrightYear: new Date().getFullYear(),\n }\n : {}),\n header: {\n content: {\n lines: [\n `Copyright ${copyrightHolder}. All Rights Reserved.`,\n `SPDX-License-Identifier: ${spdx}`,\n ],\n },\n format: {\n '**/*.{js,ts,jsx,tsx,mjs,mts}': {\n blockStart: '/**',\n lineStart: ' * ',\n blockEnd: ' */',\n },\n '**/*.{py,sh,tf}': {\n blockStart: '#',\n lineStart: '# ',\n blockEnd: '#',\n },\n },\n exclude: ['**/*.gen.*'],\n },\n };\n }\n }\n};\n\n/**\n * Write the `license.source` config (headers + LICENSE files) to the aws nx\n * plugin config.\n *\n * The `source` block is (re)written, but any existing `license.dependencies`\n * block — a user-customized allowlist, collectors and exceptions — is\n * preserved, so re-running the license generator (e.g. to change the copyright\n * holder) never clobbers dependency-check customizations.\n */\nexport const writeLicenseConfig = async (\n tree: Tree,\n source: LicenseSourceConfig,\n) => {\n const { captureGritQL } = await import('../utils/ast');\n\n // Capture the existing `dependencies: { ... }` block before overwriting the\n // license value, so we can re-attach it afterwards. It's managed by the\n // ensure* helpers, never written from here.\n const preserved = tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)\n ? await captureGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n '`dependencies: $_`',\n )\n : undefined;\n\n await updateAwsNxPluginConfig(tree, { license: { source } });\n\n // Re-attach the preserved block. The captured text may contain backticks,\n // `${...}` or quotes — prependLicenseProperty routes it through a placeholder\n // so it never enters the GritQL pattern.\n if (preserved) {\n await prependLicenseProperty(tree, preserved);\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Read license configuration\n */\nexport const readLicenseConfig = async (\n tree: Tree,\n): Promise<LicenseConfig | undefined> => {\n return readAwsNxPluginConfig(tree)?.license;\n};\n"],"names":["getProjects","readProjectConfiguration","updateProjectConfiguration","AWS_NX_PLUGIN_CONFIG_FILE_NAME","readAwsNxPluginConfig","updateAwsNxPluginConfig","formatFilesInSubtree","addDependencyToTargetIfNotPresent","LICENSES_WITH_YEAR","Set","LANGUAGE_COMMENT_SYNTAX","Object","fromEntries","map","ext","line","block","start","end","Dockerfile","py","html","css","rb","vb","lua","ps1","psm1","md","tf","smithy","LICENSE_SDK_MODULE","exceptionLiteral","exception","parts","JSON","stringify","package","version","undefined","push","reason","spdx","join","appendToArray","key","ins","prependLicenseProperty","tree","property","insertViaGritQL","GRIT_INSERT_PLACEHOLDER","intoNonEmpty","hasDependenciesBlock","exists","matchGritQL","NPM_LOCKFILES","updateLicenseCheckTargetInputs","rootProjectJsonPath","rootProject","parse","read","target","targets","inputs","filter","f","hasPythonCollector","write","findLicenseCheckProjectName","name","config","addLicenseCheckToLintTarget","projectName","licenseCheckProject","project","lint","projects","addLicenseCheckToAllLintTargets","ensureDependencyCheckBlock","options","addDestructuredImport","withPython","includeCollectors","collectors","added","ensureLicenseExceptions","exceptions","modified","pkg","inserted","ensurePythonLicenseCollector","defaultLicenseConfig","copyrightHolder","rawContent","maxLen","Math","max","length","lines","repeat","header","content","format","blockStart","lineStart","lineEnd","blockEnd","exclude","has","copyrightYear","Date","getFullYear","writeLicenseConfig","source","captureGritQL","preserved","license","readLicenseConfig"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/license/config.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type ProjectConfiguration,\n readProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n readAwsNxPluginConfig,\n updateAwsNxPluginConfig,\n} from '../utils/config/utils';\nimport { formatFilesInSubtree } from '../utils/format';\nimport { addDependencyToTargetIfNotPresent } from '../utils/nx';\nimport type {\n CommentSyntax,\n LicenseConfig,\n LicenseSourceConfig,\n} from './config-types';\nimport type { DependencyCheckException } from './dependency-check/types';\nimport type { SPDXLicenseIdentifier } from './schema';\n\n/**\n * Licenses containing a placeholder for the copyright year.\n */\nconst LICENSES_WITH_YEAR: Set<SPDXLicenseIdentifier> = new Set(['MIT']);\n\n/**\n * Defines the comment syntax for popular programming languages\n */\nexport const LANGUAGE_COMMENT_SYNTAX: { [ext: string]: CommentSyntax } = {\n // C++ style comments\n ...Object.fromEntries(\n [\n // Node\n 'js',\n 'ts',\n 'cjs',\n 'mjs',\n 'cts',\n 'mts',\n // React\n 'jsx',\n 'tsx',\n // Web\n 'sass',\n 'scss',\n 'php',\n // Java\n 'java',\n // TypeSpec\n 'tsp',\n // Golang\n 'go',\n // Rust\n 'rs',\n // C and C++\n 'c',\n 'cpp',\n 'cxx',\n 'cc',\n 'h',\n 'hpp',\n // C#\n 'cs',\n // Scala\n 'scala',\n 'sc',\n 'sbt',\n // Kotlin\n 'kt',\n // Swift\n 'swift',\n ].map((ext) => [ext, { line: '//', block: { start: '/*', end: '*/' } }]),\n ),\n // Bash style comments\n ...Object.fromEntries(\n [\n // Bash\n 'sh',\n // Perl\n 'pl',\n // YAML\n 'yaml',\n 'yml',\n // R\n 'r',\n ].map((ext) => [ext, { line: '#' }]),\n ),\n // Docker\n Dockerfile: { line: '#' },\n // Python\n py: { line: '#', block: { start: '\"\"\"', end: '\"\"\"' } },\n // Web\n html: { block: { start: '<!--', end: '-->' } },\n css: { block: { start: '/*', end: '*/' } },\n // Ruby\n rb: { line: '#', block: { start: '=begin', end: '=end' } },\n // F#\n ...Object.fromEntries(\n ['fs', 'fsx'].map((ext) => [\n ext,\n { line: '//', block: { start: '(*', end: '*)' } },\n ]),\n ),\n // Visual Basic\n vb: { line: \"' \" },\n // Lua\n lua: { line: '--', block: { start: '--[[', end: ']]' } },\n // PowerShell\n ps1: { line: '#', block: { start: '<#', end: '#>' } },\n psm1: { line: '#', block: { start: '<#', end: '#>' } },\n // Markdown\n md: { block: { start: '<!--', end: '-->' } },\n // Terraform\n tf: { line: '#', block: { start: '/*', end: '*/' } },\n // Smithy\n smithy: { line: '//' },\n};\n\n/**\n * Module specifier for the license helpers exported by this package, used by\n * imports written into the user's config file.\n */\nconst LICENSE_SDK_MODULE = '@aws/nx-plugin/sdk/license';\n\n/**\n * Build the object literal source for a dependency check exception.\n * `JSON.stringify` produces valid string literals for arbitrary text (quotes,\n * backslashes, newlines all escaped); prettier later normalises quote style.\n */\nconst exceptionLiteral = (exception: DependencyCheckException): string => {\n const parts = [`package: ${JSON.stringify(exception.package)}`];\n if (exception.version !== undefined) {\n parts.push(`version: ${JSON.stringify(exception.version)}`);\n }\n parts.push(`reason: ${JSON.stringify(exception.reason)}`);\n if (exception.spdx !== undefined) {\n parts.push(`spdx: ${JSON.stringify(exception.spdx)}`);\n }\n return `{ ${parts.join(', ')} }`;\n};\n\n/**\n * GritQL `or` block that appends `$ins` (the insert placeholder) to the named\n * array inside the matched `$scope`, without ever producing an array hole:\n * - empty `key: []` → `key: [$ins]` (a list-append `+=` does not match an\n * empty array, so the empty case is rewritten directly)\n * - otherwise → list-append `+=` of `, $ins`; the leading comma is the\n * element separator and `+=` places it correctly for single inline,\n * single-with-trailing-comma and multi-element arrays alike\n */\nconst appendToArray = (key: string, ins: string) =>\n `or {\n $scope <: contains \\`${key}: []\\` => \\`${key}: [${ins}]\\`,\n $scope <: contains \\`${key}: [$items]\\` where { $items += \\`, ${ins}\\` }\n }`;\n\n/**\n * Insert `property` (TypeScript source like `dependencies: { ... }`) as the\n * first property of the `license` object literal.\n *\n * Prepending is comma-safe for every shape — empty `{}`, single- or multi-line.\n * `+=` appending is not: it omits the separator when the last property's value\n * is an object/array literal (e.g. `source: { ... }`), corrupting the file. The\n * property text is routed through a placeholder so its content never enters the\n * GritQL pattern. Returns true if the file changed (a `license` object existed).\n */\nconst prependLicenseProperty = async (\n tree: Tree,\n property: string,\n): Promise<boolean> => {\n const { insertViaGritQL, GRIT_INSERT_PLACEHOLDER } = await import(\n '../utils/ast'\n );\n\n // Non-empty license object: insert before the first existing property.\n const intoNonEmpty = await insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`license: { $props }\\` where { $props => \\`${GRIT_INSERT_PLACEHOLDER}, $props\\` }`,\n property,\n );\n if (intoNonEmpty) return true;\n\n // Empty license object: `{ $props }` doesn't match `{}`, so fill it directly.\n return insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`license: {}\\` => \\`license: { ${GRIT_INSERT_PLACEHOLDER} }\\``,\n property,\n );\n};\n\n/**\n * Whether `license.dependencies` (the dependency-check block) is configured.\n * Scoped within `license` so a `dependencies`-shaped object elsewhere in the\n * file isn't mistaken for it.\n */\nconst hasDependenciesBlock = async (tree: Tree): Promise<boolean> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return false;\n const { matchGritQL } = await import('../utils/ast');\n return matchGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n '`license: { $l }` where { $l <: contains `dependencies: $_` }',\n );\n};\n\n/**\n * Workspace-root npm-ecosystem lockfiles. Each is added to the license-check\n * cache inputs only when present, so the cache invalidates on dependency\n * changes without listing lockfiles for package managers the workspace doesn't\n * use.\n */\nconst NPM_LOCKFILES = [\n 'pnpm-lock.yaml',\n 'yarn.lock',\n 'package-lock.json',\n 'bun.lockb',\n];\n\n/**\n * Recompute the `inputs` of the root `license-check` target from what's\n * currently in the workspace: the present npm lockfiles, the config file, and\n * a recursive uv.lock glob when the dependency check uses a Python collector.\n *\n * The uv lockfile is keyed off the collector (not file presence) because it is\n * created by `uv` *after* the generator runs, and may live in a subdirectory of\n * a uv workspace. Callers run this whenever they change the relevant state, so\n * the inputs stay correct regardless of generator order. No-op if the\n * license-check target doesn't exist yet.\n */\nexport const updateLicenseCheckTargetInputs = async (\n tree: Tree,\n): Promise<void> => {\n const rootProjectJsonPath = 'project.json';\n if (!tree.exists(rootProjectJsonPath)) return;\n\n const rootProject = JSON.parse(tree.read(rootProjectJsonPath, 'utf-8')!);\n const target = rootProject.targets?.['license-check'];\n if (!target) return;\n\n const inputs = NPM_LOCKFILES.filter((f) => tree.exists(f)).map(\n (f) => `{workspaceRoot}/${f}`,\n );\n\n if (await hasPythonCollector(tree)) {\n inputs.push('{workspaceRoot}/**/uv.lock');\n }\n\n inputs.push('{workspaceRoot}/aws-nx-plugin.config.mts');\n\n target.inputs = inputs;\n tree.write(rootProjectJsonPath, JSON.stringify(rootProject, null, 2));\n};\n\n/**\n * Whether the dependency check config has a `pythonCollector` configured.\n */\nconst hasPythonCollector = async (tree: Tree): Promise<boolean> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return false;\n const { matchGritQL } = await import('../utils/ast');\n return matchGritQL(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME, '`pythonCollector`');\n};\n\n/**\n * The name of the project that owns the root `license-check` target, or\n * undefined if no project defines it.\n */\nconst findLicenseCheckProjectName = (tree: Tree): string | undefined => {\n for (const [name, config] of getProjects(tree)) {\n if (config.targets?.['license-check']) return name;\n }\n return undefined;\n};\n\n/**\n * Make a project's `lint` target depend on the root `license-check` target, so\n * license checking runs as part of lint/build. No-op when the project has no\n * `lint` target or there's no license-check target to depend on. Idempotent.\n *\n * Callers format afterwards (generators call `formatFilesInSubtree` at the end),\n * so the rewritten project.json matches prettier.\n */\nexport const addLicenseCheckToLintTarget = (\n tree: Tree,\n projectName: string,\n): void => {\n const licenseCheckProject = findLicenseCheckProjectName(tree);\n if (!licenseCheckProject) return;\n\n let project: ProjectConfiguration;\n try {\n project = readProjectConfiguration(tree, projectName);\n } catch {\n return;\n }\n\n // Only wire projects that actually lint, and never the license-check project\n // itself (a target can't depend on its own project's target).\n if (!project.targets?.lint || projectName === licenseCheckProject) return;\n\n addDependencyToTargetIfNotPresent(project, 'lint', {\n projects: [licenseCheckProject],\n target: 'license-check',\n });\n updateProjectConfiguration(tree, projectName, project);\n};\n\n/**\n * Wire every project's `lint` target to the root `license-check` target.\n * Called by the license generator so existing projects pick up the dependency\n * regardless of the order generators ran in.\n */\nexport const addLicenseCheckToAllLintTargets = (tree: Tree): void => {\n for (const [name] of getProjects(tree)) {\n addLicenseCheckToLintTarget(tree, name);\n }\n};\n\nexport interface EnsureDependencyCheckBlockOptions {\n includeCollectors?: 'npm' | 'npm+python';\n}\n\n/**\n * Ensure the `dependencies` block (dependency license checking) exists within\n * the `license` config. If one already exists it is left untouched, so user\n * customizations survive.\n */\nexport const ensureDependencyCheckBlock = async (\n tree: Tree,\n options?: EnsureDependencyCheckBlockOptions,\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { addDestructuredImport } = await import('../utils/ast');\n\n if (await hasDependenciesBlock(tree)) {\n return;\n }\n\n const withPython = options?.includeCollectors === 'npm+python';\n const collectors = withPython\n ? 'collectors: [npmCollector(), pythonCollector()]'\n : 'collectors: [npmCollector()]';\n\n const block = `dependencies: { allow: DEFAULT_LICENSE_ALLOWLIST, ${collectors}, exceptions: [] }`;\n\n // Prepend the block as the first property of the license object. Prepending\n // (rather than `+=` appending) is comma-safe for every shape: GritQL's `+=`\n // omits the separator when the last existing property's value is an object\n // literal (e.g. `source: { ... }`), which would corrupt the file.\n const added = await prependLicenseProperty(tree, block);\n\n // Only add the imports if the block was actually written (i.e. a license\n // object literal existed to attach it to).\n if (added) {\n await addDestructuredImport(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n withPython\n ? ['DEFAULT_LICENSE_ALLOWLIST', 'npmCollector', 'pythonCollector']\n : ['DEFAULT_LICENSE_ALLOWLIST', 'npmCollector'],\n LICENSE_SDK_MODULE,\n );\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Ensure license exceptions are present in `license.dependencies.exceptions`.\n * An exception whose package is already listed is skipped (so existing reasons\n * are never overwritten). Other exceptions, collectors and the allowlist are\n * left untouched.\n *\n * The `dependencies: { $scope }` scope keeps edits within the dependency-check\n * block, so an `exceptions` array elsewhere in the file isn't matched.\n */\nexport const ensureLicenseExceptions = async (\n tree: Tree,\n exceptions: DependencyCheckException[],\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { insertViaGritQL, GRIT_INSERT_PLACEHOLDER } = await import(\n '../utils/ast'\n );\n\n if (!(await hasDependenciesBlock(tree))) {\n return;\n }\n\n let modified = false;\n for (const exception of exceptions) {\n const pkg = JSON.stringify(exception.package);\n const inserted = await insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`dependencies: { $scope }\\` where {\n $scope <: not contains \\`package: ${pkg}\\`,\n ${appendToArray('exceptions', GRIT_INSERT_PLACEHOLDER)}\n }`,\n exceptionLiteral(exception),\n );\n modified ||= inserted;\n }\n\n if (modified) {\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Remove the exceptions for the named packages from\n * `license.dependencies.exceptions`, whatever reason or spdx each carries.\n * Packages that aren't listed are left alone, as are all other exceptions.\n *\n * Scoped to `dependencies: { $scope }` like {@link ensureLicenseExceptions}, so\n * an `exceptions` array elsewhere in the file isn't matched.\n */\nexport const removeLicenseExceptions = async (\n tree: Tree,\n packages: string[],\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { applyGritQL } = await import('../utils/ast');\n\n let modified = false;\n for (const pkg of packages) {\n const removed = await applyGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`dependencies: { $scope }\\` where {\n $scope <: contains bubble or {\n \\`[$items]\\` where {\n $items <: some bubble \\`{ $props }\\` as $entry where {\n $props <: contains \\`package: ${JSON.stringify(pkg)}\\`,\n $entry => .\n }\n }\n }\n }`,\n );\n modified ||= removed;\n }\n\n if (modified) {\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Add `pythonCollector()` to `license.dependencies.collectors`, unless one is\n * already configured.\n */\nexport const ensurePythonLicenseCollector = async (\n tree: Tree,\n): Promise<void> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) return;\n\n const { addDestructuredImport, insertViaGritQL, GRIT_INSERT_PLACEHOLDER } =\n await import('../utils/ast');\n\n if (!(await hasDependenciesBlock(tree))) {\n return;\n }\n\n const added = await insertViaGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n `\\`dependencies: { $scope }\\` where {\n $scope <: not contains \\`pythonCollector\\`,\n ${appendToArray('collectors', GRIT_INSERT_PLACEHOLDER)}\n }`,\n 'pythonCollector()',\n );\n\n if (added) {\n await addDestructuredImport(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n ['pythonCollector'],\n LICENSE_SDK_MODULE,\n );\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n // Now that a Python collector is configured, ensure uv.lock is a cache\n // input. Runs here (not only in the license generator) so it's added\n // whenever the collector is — e.g. when py#project runs after license.\n await updateLicenseCheckTargetInputs(tree);\n }\n};\n\n/**\n * Build the default `license.source` config for a given license\n */\nexport const defaultLicenseConfig = (\n spdx: SPDXLicenseIdentifier,\n copyrightHolder: string,\n): LicenseSourceConfig => {\n switch (spdx) {\n case 'ASL': {\n // For ASL, we use a \"box\" style license header\n const rawContent = [\n `Copyright ${copyrightHolder}. All Rights Reserved.`,\n '',\n 'Licensed under the Amazon Software License (the \"License\"). You may not use this file except in compliance',\n 'with the License. A copy of the License is located at',\n '',\n ' https://aws.amazon.com/asl/',\n '',\n 'or in the \"license\" file accompanying this file. This file is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES',\n 'OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions',\n 'and limitations under the License.',\n ];\n const maxLen = Math.max(...rawContent.map((line) => line.length));\n const lines = rawContent.map(\n (line) => `${line}${' '.repeat(maxLen - line.length)}`,\n );\n return {\n spdx,\n copyrightHolder,\n header: {\n content: { lines },\n format: {\n '**/*.{js,ts,jsx,tsx,mjs,mts}': {\n blockStart: `/***${'*'.repeat(maxLen)}**`,\n lineStart: ' * ',\n lineEnd: ' *',\n blockEnd: ` ***${'*'.repeat(maxLen)}**/`,\n },\n '**/*.{py,sh,tf}': {\n blockStart: `###${'#'.repeat(maxLen)}##`,\n lineStart: '# ',\n lineEnd: ' #',\n blockEnd: `###${'#'.repeat(maxLen)}##`,\n },\n },\n exclude: ['**/*.gen.*'],\n },\n };\n }\n default: {\n return {\n spdx,\n copyrightHolder,\n ...(LICENSES_WITH_YEAR.has(spdx)\n ? {\n copyrightYear: new Date().getFullYear(),\n }\n : {}),\n header: {\n content: {\n lines: [\n `Copyright ${copyrightHolder}. All Rights Reserved.`,\n `SPDX-License-Identifier: ${spdx}`,\n ],\n },\n format: {\n '**/*.{js,ts,jsx,tsx,mjs,mts}': {\n blockStart: '/**',\n lineStart: ' * ',\n blockEnd: ' */',\n },\n '**/*.{py,sh,tf}': {\n blockStart: '#',\n lineStart: '# ',\n blockEnd: '#',\n },\n },\n exclude: ['**/*.gen.*'],\n },\n };\n }\n }\n};\n\n/**\n * Write the `license.source` config (headers + LICENSE files) to the aws nx\n * plugin config.\n *\n * The `source` block is (re)written, but any existing `license.dependencies`\n * block — a user-customized allowlist, collectors and exceptions — is\n * preserved, so re-running the license generator (e.g. to change the copyright\n * holder) never clobbers dependency-check customizations.\n */\nexport const writeLicenseConfig = async (\n tree: Tree,\n source: LicenseSourceConfig,\n) => {\n const { captureGritQL } = await import('../utils/ast');\n\n // Capture the existing `dependencies: { ... }` block before overwriting the\n // license value, so we can re-attach it afterwards. It's managed by the\n // ensure* helpers, never written from here.\n const preserved = tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)\n ? await captureGritQL(\n tree,\n AWS_NX_PLUGIN_CONFIG_FILE_NAME,\n '`dependencies: $_`',\n )\n : undefined;\n\n await updateAwsNxPluginConfig(tree, { license: { source } });\n\n // Re-attach the preserved block. The captured text may contain backticks,\n // `${...}` or quotes — prependLicenseProperty routes it through a placeholder\n // so it never enters the GritQL pattern.\n if (preserved) {\n await prependLicenseProperty(tree, preserved);\n await formatFilesInSubtree(tree, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n }\n};\n\n/**\n * Read license configuration\n */\nexport const readLicenseConfig = async (\n tree: Tree,\n): Promise<LicenseConfig | undefined> => {\n return readAwsNxPluginConfig(tree)?.license;\n};\n"],"names":["getProjects","readProjectConfiguration","updateProjectConfiguration","AWS_NX_PLUGIN_CONFIG_FILE_NAME","readAwsNxPluginConfig","updateAwsNxPluginConfig","formatFilesInSubtree","addDependencyToTargetIfNotPresent","LICENSES_WITH_YEAR","Set","LANGUAGE_COMMENT_SYNTAX","Object","fromEntries","map","ext","line","block","start","end","Dockerfile","py","html","css","rb","vb","lua","ps1","psm1","md","tf","smithy","LICENSE_SDK_MODULE","exceptionLiteral","exception","parts","JSON","stringify","package","version","undefined","push","reason","spdx","join","appendToArray","key","ins","prependLicenseProperty","tree","property","insertViaGritQL","GRIT_INSERT_PLACEHOLDER","intoNonEmpty","hasDependenciesBlock","exists","matchGritQL","NPM_LOCKFILES","updateLicenseCheckTargetInputs","rootProjectJsonPath","rootProject","parse","read","target","targets","inputs","filter","f","hasPythonCollector","write","findLicenseCheckProjectName","name","config","addLicenseCheckToLintTarget","projectName","licenseCheckProject","project","lint","projects","addLicenseCheckToAllLintTargets","ensureDependencyCheckBlock","options","addDestructuredImport","withPython","includeCollectors","collectors","added","ensureLicenseExceptions","exceptions","modified","pkg","inserted","removeLicenseExceptions","packages","applyGritQL","removed","ensurePythonLicenseCollector","defaultLicenseConfig","copyrightHolder","rawContent","maxLen","Math","max","length","lines","repeat","header","content","format","blockStart","lineStart","lineEnd","blockEnd","exclude","has","copyrightYear","Date","getFullYear","writeLicenseConfig","source","captureGritQL","preserved","license","readLicenseConfig"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/license/dependency-check/collectors/collector.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { workspaceRoot } from '@nx/devkit';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\n\nexport interface CollectedDependency {\n name: string;\n version: string;\n rawLicense: string;\n ecosystem: string;\n path?: string;\n}\n\nexport interface LicenseCollector {\n name: string;\n traceCommand?: string;\n collect(options: { workspaceRoot: string }): Promise<CollectedDependency[]>;\n}\n\nexport const npmCollector = (): LicenseCollector => ({\n name: 'npm',\n get traceCommand() {\n if (existsSync(join(workspaceRoot, 'yarn.lock')))\n return 'yarn why <package>';\n if (existsSync(join(workspaceRoot, 'bun.lockb')))\n return 'bun pm why <package>';\n if (existsSync(join(workspaceRoot, 'package-lock.json')))\n return 'npm why <package>';\n return 'pnpm why <package>';\n },\n async collect({ workspaceRoot }) {\n const { collectNpmDependencies } = await import('./npm-collector');\n return (await collectNpmDependencies({ start: workspaceRoot })).map(\n (d) => ({ ...d, ecosystem: 'npm' }),\n );\n },\n});\n\nexport const pythonCollector = (): LicenseCollector => ({\n name: 'python',\n traceCommand: 'uv tree --invert --package <package>',\n async collect({ workspaceRoot }) {\n const { collectPythonDependencies } = await import('./python-collector');\n const { findWorkspacePyProjectNames } = await import('./python-collector');\n const excludePackages = await findWorkspacePyProjectNames(workspaceRoot);\n return (\n await collectPythonDependencies({ start: workspaceRoot, excludePackages })\n ).map((d) => ({ ...d, ecosystem: 'pypi' }));\n },\n});\n\nexport const DEFAULT_COLLECTORS: LicenseCollector[] = [\n npmCollector(),\n pythonCollector(),\n];\n"],"names":["workspaceRoot","existsSync","join","npmCollector","name","traceCommand","collect","collectNpmDependencies","start","map","d","ecosystem","pythonCollector","collectPythonDependencies","findWorkspacePyProjectNames","excludePackages","DEFAULT_COLLECTORS"],"mappings":"AAAA;;;CAGC,GAED,SAASA,aAAa,QAAQ,aAAa;AAC3C,SAASC,UAAU,QAAQ,KAAK;AAChC,SAASC,IAAI,QAAQ,OAAO;AAgB5B,OAAO,MAAMC,eAAe,IAAyB,CAAA;QACnDC,MAAM;QACN,IAAIC
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/license/dependency-check/collectors/collector.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { workspaceRoot } from '@nx/devkit';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\n\nexport interface CollectedDependency {\n name: string;\n version: string;\n rawLicense: string;\n ecosystem: string;\n path?: string;\n}\n\nexport interface LicenseCollector {\n name: string;\n traceCommand?: string;\n collect(options: { workspaceRoot: string }): Promise<CollectedDependency[]>;\n}\n\nexport const npmCollector = (): LicenseCollector => ({\n name: 'npm',\n get traceCommand() {\n if (existsSync(join(workspaceRoot, 'yarn.lock')))\n return 'yarn why <package>';\n if (existsSync(join(workspaceRoot, 'bun.lockb')))\n return 'bun pm why <package>';\n if (existsSync(join(workspaceRoot, 'package-lock.json')))\n return 'npm why <package>';\n return 'pnpm why <package>';\n },\n async collect({ workspaceRoot }) {\n const { collectNpmDependencies } = await import('./npm-collector');\n return (await collectNpmDependencies({ start: workspaceRoot })).map(\n (d) => ({ ...d, ecosystem: 'npm' }),\n );\n },\n});\n\nexport const pythonCollector = (): LicenseCollector => ({\n name: 'python',\n traceCommand: 'uv tree --invert --package <package>',\n async collect({ workspaceRoot }) {\n const { collectPythonDependencies } = await import('./python-collector');\n const { findWorkspacePyProjectNames } = await import('./python-collector');\n const excludePackages = await findWorkspacePyProjectNames(workspaceRoot);\n return (\n await collectPythonDependencies({ start: workspaceRoot, excludePackages })\n ).map((d) => ({ ...d, ecosystem: 'pypi' }));\n },\n});\n\nexport const DEFAULT_COLLECTORS: LicenseCollector[] = [\n npmCollector(),\n pythonCollector(),\n];\n"],"names":["workspaceRoot","existsSync","join","npmCollector","name","traceCommand","collect","collectNpmDependencies","start","map","d","ecosystem","pythonCollector","collectPythonDependencies","findWorkspacePyProjectNames","excludePackages","DEFAULT_COLLECTORS"],"mappings":"AAAA;;;CAGC,GAED,SAASA,aAAa,QAAQ,aAAa;AAC3C,SAASC,UAAU,QAAQ,KAAK;AAChC,SAASC,IAAI,QAAQ,OAAO;AAgB5B,OAAO,MAAMC,eAAe,IAAyB,CAAA;QACnDC,MAAM;QACN,IAAIC;YACF,IAAIJ,WAAWC,KAAKF,eAAe,eACjC,OAAO;YACT,IAAIC,WAAWC,KAAKF,eAAe,eACjC,OAAO;YACT,IAAIC,WAAWC,KAAKF,eAAe,uBACjC,OAAO;YACT,OAAO;QACT;QACA,MAAMM,SAAQ,EAAEN,aAAa,EAAE;YAC7B,MAAM,EAAEO,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC;YAChD,OAAO,AAAC,CAAA,MAAMA,uBAAuB;gBAAEC,OAAOR;YAAc,EAAC,EAAGS,GAAG,CACjE,CAACC,IAAO,CAAA;oBAAE,GAAGA,CAAC;oBAAEC,WAAW;gBAAM,CAAA;QAErC;IACF,CAAA,EAAG;AAEH,OAAO,MAAMC,kBAAkB,IAAyB,CAAA;QACtDR,MAAM;QACNC,cAAc;QACd,MAAMC,SAAQ,EAAEN,aAAa,EAAE;YAC7B,MAAM,EAAEa,yBAAyB,EAAE,GAAG,MAAM,MAAM,CAAC;YACnD,MAAM,EAAEC,2BAA2B,EAAE,GAAG,MAAM,MAAM,CAAC;YACrD,MAAMC,kBAAkB,MAAMD,4BAA4Bd;YAC1D,OAAO,AACL,CAAA,MAAMa,0BAA0B;gBAAEL,OAAOR;gBAAee;YAAgB,EAAC,EACzEN,GAAG,CAAC,CAACC,IAAO,CAAA;oBAAE,GAAGA,CAAC;oBAAEC,WAAW;gBAAO,CAAA;QAC1C;IACF,CAAA,EAAG;AAEH,OAAO,MAAMK,qBAAyC;IACpDb;IACAS;CACD,CAAC"}
|
|
@@ -53,6 +53,45 @@ const isUnknownToken = (raw)=>{
|
|
|
53
53
|
}
|
|
54
54
|
return m;
|
|
55
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* Split a free-text license list on a separator, treating the operands as
|
|
58
|
+
* alternatives (OR).
|
|
59
|
+
*
|
|
60
|
+
* Commas need care: several allowed license names contain one themselves (e.g.
|
|
61
|
+
* "Apache License, Version 2.0"), so the string is left intact when it already
|
|
62
|
+
* resolves as a single license, and fragments are otherwise rejoined
|
|
63
|
+
* longest-match-first. That keeps "MIT License, Apache License, Version 2.0"
|
|
64
|
+
* parsing as MIT + Apache rather than three unresolvable fragments.
|
|
65
|
+
*
|
|
66
|
+
* Returns `undefined` when the value shouldn't be treated as a list.
|
|
67
|
+
*/ const splitAlternatives = (value, separator, isKnown)=>{
|
|
68
|
+
if (!value.includes(separator)) return undefined;
|
|
69
|
+
if (isKnown(value)) return undefined;
|
|
70
|
+
const parts = value.split(separator).map((p)=>p.trim()).filter((p)=>p.length > 0);
|
|
71
|
+
if (parts.length < 2) return undefined;
|
|
72
|
+
// Rejoin fragments that only make sense together, so a license name
|
|
73
|
+
// containing the separator survives the split. At each position take the
|
|
74
|
+
// longest run of fragments that forms a known license; failing that, emit the
|
|
75
|
+
// single fragment and let the caller report it.
|
|
76
|
+
const merged = [];
|
|
77
|
+
let i = 0;
|
|
78
|
+
while(i < parts.length){
|
|
79
|
+
let matchedTo = -1;
|
|
80
|
+
let candidate = parts[i];
|
|
81
|
+
for(let j = i; j < parts.length; j++){
|
|
82
|
+
if (j > i) candidate = `${candidate}${separator} ${parts[j]}`;
|
|
83
|
+
if (isKnown(candidate)) matchedTo = j;
|
|
84
|
+
}
|
|
85
|
+
if (matchedTo >= 0) {
|
|
86
|
+
merged.push(parts.slice(i, matchedTo + 1).join(`${separator} `));
|
|
87
|
+
i = matchedTo + 1;
|
|
88
|
+
} else {
|
|
89
|
+
merged.push(parts[i]);
|
|
90
|
+
i += 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return merged.length > 1 ? merged : undefined;
|
|
94
|
+
};
|
|
56
95
|
const evaluateToken = (token, spdxIds, aliasLookup)=>{
|
|
57
96
|
const cleaned = normalise(token);
|
|
58
97
|
if (isUnknownToken(cleaned)) return 'UNKNOWN';
|
|
@@ -74,17 +113,23 @@ export const createEvaluator = (options)=>{
|
|
|
74
113
|
if (!rawLicense || rawLicense.trim().length === 0) return 'UNKNOWN';
|
|
75
114
|
const normalised = normalise(rawLicense);
|
|
76
115
|
if (isUnknownToken(normalised)) return 'UNKNOWN';
|
|
77
|
-
// Python tooling emits
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
116
|
+
// Python tooling emits free-text license lists rather than an SPDX
|
|
117
|
+
// expression: "Apache Software License; BSD License" (setuptools
|
|
118
|
+
// classifiers) or "MIT License, Apache License, Version 2.0" (a dual
|
|
119
|
+
// license declared in one `License:` field). Both mean "any of these
|
|
120
|
+
// applies", so treat the operands as OR.
|
|
121
|
+
const isKnown = (token)=>evaluateToken(token, spdxIds, aliasLookup) === 'PRE_APPROVED';
|
|
122
|
+
for (const separator of [
|
|
123
|
+
';',
|
|
124
|
+
','
|
|
125
|
+
]){
|
|
126
|
+
const parts = splitAlternatives(normalised, separator, isKnown);
|
|
127
|
+
if (!parts) continue;
|
|
128
|
+
for (const part of parts){
|
|
129
|
+
if (evaluateToken(part, spdxIds, aliasLookup) === 'PRE_APPROVED') return 'PRE_APPROVED';
|
|
87
130
|
}
|
|
131
|
+
if (parts.every((p)=>isUnknownToken(normalise(p)))) return 'UNKNOWN';
|
|
132
|
+
return 'NOT_APPROVED';
|
|
88
133
|
}
|
|
89
134
|
return evaluateToken(normalised, spdxIds, aliasLookup);
|
|
90
135
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/license/dependency-check/evaluator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport spdxSatisfies from 'spdx-satisfies';\nimport type { AllowlistEntry, LicenseStatus } from './types';\n\nexport interface EvaluatorOptions {\n allow: AllowlistEntry[];\n}\n\ninterface Evaluator {\n evaluate(rawLicense: string | undefined | null): LicenseStatus;\n}\n\nconst isUnknownToken = (raw: string): boolean => {\n if (!raw) return true;\n const trimmed = raw.trim();\n if (!trimmed) return true;\n if (trimmed.toUpperCase() === 'UNKNOWN') return true;\n if (trimmed.toLowerCase().startsWith('custom:')) return true;\n if (trimmed.toLowerCase().startsWith('see license in')) return true;\n return false;\n};\n\n/**\n * Strip the trailing `*` that license-checker adds when a license is guessed\n * from file content rather than declared in package.json metadata.\n */\nconst normalise = (raw: string): string => {\n let s = raw.trim();\n if (s.endsWith('*')) s = s.slice(0, -1).trim();\n return s;\n};\n\n/**\n * Build a flat list of valid SPDX IDs from the allowlist for use with\n * spdx-satisfies. Entries that aren't parseable as SPDX identifiers are\n * excluded (they're still matched via the alias lookup).\n */\nconst buildSpdxIds = (allow: AllowlistEntry[]): string[] => {\n const ids: string[] = [];\n for (const entry of allow) {\n if (!entry.spdxId) continue;\n try {\n spdxSatisfies(entry.spdxId, [entry.spdxId]);\n ids.push(entry.spdxId);\n } catch {\n // Not a valid SPDX identifier — skip for spdx-satisfies, still\n // matched via alias lookup\n }\n }\n return ids;\n};\n\n/**\n * Build a case-insensitive lookup for matching by full name or alias\n * (for licenses that aren't valid SPDX but appear in package metadata).\n */\nconst buildAliasLookup = (allow: AllowlistEntry[]): Map<string, true> => {\n const m = new Map<string, true>();\n for (const e of allow) {\n if (e.spdxId) m.set(e.spdxId.toLowerCase(), true);\n if (e.fullName) m.set(e.fullName.toLowerCase(), true);\n for (const a of e.aliases ?? []) {\n if (a) m.set(a.toLowerCase(), true);\n }\n }\n return m;\n};\n\nconst evaluateToken = (\n token: string,\n spdxIds: string[],\n aliasLookup: Map<string, true>,\n): LicenseStatus => {\n const cleaned = normalise(token);\n if (isUnknownToken(cleaned)) return 'UNKNOWN';\n\n // Try spdx-satisfies for valid SPDX expressions\n try {\n if (spdxSatisfies(cleaned, spdxIds)) return 'PRE_APPROVED';\n } catch {\n // Not a valid SPDX expression — fall through to alias matching\n }\n\n // Fall back to alias/fullName matching for non-SPDX strings\n if (aliasLookup.has(cleaned.toLowerCase())) return 'PRE_APPROVED';\n\n return 'NOT_APPROVED';\n};\n\nexport const createEvaluator = (options: EvaluatorOptions): Evaluator => {\n const spdxIds = buildSpdxIds(options.allow);\n const aliasLookup = buildAliasLookup(options.allow);\n\n return {\n evaluate(rawLicense) {\n if (!rawLicense || rawLicense.trim().length === 0) return 'UNKNOWN';\n\n const normalised = normalise(rawLicense);\n if (isUnknownToken(normalised)) return 'UNKNOWN';\n\n // Python tooling emits \"Apache Software License; BSD License\"
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/license/dependency-check/evaluator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport spdxSatisfies from 'spdx-satisfies';\nimport type { AllowlistEntry, LicenseStatus } from './types';\n\nexport interface EvaluatorOptions {\n allow: AllowlistEntry[];\n}\n\ninterface Evaluator {\n evaluate(rawLicense: string | undefined | null): LicenseStatus;\n}\n\nconst isUnknownToken = (raw: string): boolean => {\n if (!raw) return true;\n const trimmed = raw.trim();\n if (!trimmed) return true;\n if (trimmed.toUpperCase() === 'UNKNOWN') return true;\n if (trimmed.toLowerCase().startsWith('custom:')) return true;\n if (trimmed.toLowerCase().startsWith('see license in')) return true;\n return false;\n};\n\n/**\n * Strip the trailing `*` that license-checker adds when a license is guessed\n * from file content rather than declared in package.json metadata.\n */\nconst normalise = (raw: string): string => {\n let s = raw.trim();\n if (s.endsWith('*')) s = s.slice(0, -1).trim();\n return s;\n};\n\n/**\n * Build a flat list of valid SPDX IDs from the allowlist for use with\n * spdx-satisfies. Entries that aren't parseable as SPDX identifiers are\n * excluded (they're still matched via the alias lookup).\n */\nconst buildSpdxIds = (allow: AllowlistEntry[]): string[] => {\n const ids: string[] = [];\n for (const entry of allow) {\n if (!entry.spdxId) continue;\n try {\n spdxSatisfies(entry.spdxId, [entry.spdxId]);\n ids.push(entry.spdxId);\n } catch {\n // Not a valid SPDX identifier — skip for spdx-satisfies, still\n // matched via alias lookup\n }\n }\n return ids;\n};\n\n/**\n * Build a case-insensitive lookup for matching by full name or alias\n * (for licenses that aren't valid SPDX but appear in package metadata).\n */\nconst buildAliasLookup = (allow: AllowlistEntry[]): Map<string, true> => {\n const m = new Map<string, true>();\n for (const e of allow) {\n if (e.spdxId) m.set(e.spdxId.toLowerCase(), true);\n if (e.fullName) m.set(e.fullName.toLowerCase(), true);\n for (const a of e.aliases ?? []) {\n if (a) m.set(a.toLowerCase(), true);\n }\n }\n return m;\n};\n\n/**\n * Split a free-text license list on a separator, treating the operands as\n * alternatives (OR).\n *\n * Commas need care: several allowed license names contain one themselves (e.g.\n * \"Apache License, Version 2.0\"), so the string is left intact when it already\n * resolves as a single license, and fragments are otherwise rejoined\n * longest-match-first. That keeps \"MIT License, Apache License, Version 2.0\"\n * parsing as MIT + Apache rather than three unresolvable fragments.\n *\n * Returns `undefined` when the value shouldn't be treated as a list.\n */\nconst splitAlternatives = (\n value: string,\n separator: string,\n isKnown: (token: string) => boolean,\n): string[] | undefined => {\n if (!value.includes(separator)) return undefined;\n if (isKnown(value)) return undefined;\n\n const parts = value\n .split(separator)\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (parts.length < 2) return undefined;\n\n // Rejoin fragments that only make sense together, so a license name\n // containing the separator survives the split. At each position take the\n // longest run of fragments that forms a known license; failing that, emit the\n // single fragment and let the caller report it.\n const merged: string[] = [];\n let i = 0;\n while (i < parts.length) {\n let matchedTo = -1;\n let candidate = parts[i];\n for (let j = i; j < parts.length; j++) {\n if (j > i) candidate = `${candidate}${separator} ${parts[j]}`;\n if (isKnown(candidate)) matchedTo = j;\n }\n if (matchedTo >= 0) {\n merged.push(parts.slice(i, matchedTo + 1).join(`${separator} `));\n i = matchedTo + 1;\n } else {\n merged.push(parts[i]);\n i += 1;\n }\n }\n\n return merged.length > 1 ? merged : undefined;\n};\n\nconst evaluateToken = (\n token: string,\n spdxIds: string[],\n aliasLookup: Map<string, true>,\n): LicenseStatus => {\n const cleaned = normalise(token);\n if (isUnknownToken(cleaned)) return 'UNKNOWN';\n\n // Try spdx-satisfies for valid SPDX expressions\n try {\n if (spdxSatisfies(cleaned, spdxIds)) return 'PRE_APPROVED';\n } catch {\n // Not a valid SPDX expression — fall through to alias matching\n }\n\n // Fall back to alias/fullName matching for non-SPDX strings\n if (aliasLookup.has(cleaned.toLowerCase())) return 'PRE_APPROVED';\n\n return 'NOT_APPROVED';\n};\n\nexport const createEvaluator = (options: EvaluatorOptions): Evaluator => {\n const spdxIds = buildSpdxIds(options.allow);\n const aliasLookup = buildAliasLookup(options.allow);\n\n return {\n evaluate(rawLicense) {\n if (!rawLicense || rawLicense.trim().length === 0) return 'UNKNOWN';\n\n const normalised = normalise(rawLicense);\n if (isUnknownToken(normalised)) return 'UNKNOWN';\n\n // Python tooling emits free-text license lists rather than an SPDX\n // expression: \"Apache Software License; BSD License\" (setuptools\n // classifiers) or \"MIT License, Apache License, Version 2.0\" (a dual\n // license declared in one `License:` field). Both mean \"any of these\n // applies\", so treat the operands as OR.\n const isKnown = (token: string) =>\n evaluateToken(token, spdxIds, aliasLookup) === 'PRE_APPROVED';\n for (const separator of [';', ',']) {\n const parts = splitAlternatives(normalised, separator, isKnown);\n if (!parts) continue;\n for (const part of parts) {\n if (evaluateToken(part, spdxIds, aliasLookup) === 'PRE_APPROVED')\n return 'PRE_APPROVED';\n }\n if (parts.every((p) => isUnknownToken(normalise(p)))) return 'UNKNOWN';\n return 'NOT_APPROVED';\n }\n\n return evaluateToken(normalised, spdxIds, aliasLookup);\n },\n };\n};\n"],"names":["spdxSatisfies","isUnknownToken","raw","trimmed","trim","toUpperCase","toLowerCase","startsWith","normalise","s","endsWith","slice","buildSpdxIds","allow","ids","entry","spdxId","push","buildAliasLookup","m","Map","e","set","fullName","a","aliases","splitAlternatives","value","separator","isKnown","includes","undefined","parts","split","map","p","filter","length","merged","i","matchedTo","candidate","j","join","evaluateToken","token","spdxIds","aliasLookup","cleaned","has","createEvaluator","options","evaluate","rawLicense","normalised","part","every"],"mappings":"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"}
|
package/src/license/generator.js
CHANGED
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/ import { getProjects, readNxJson, updateNxJson } from "@nx/devkit";
|
|
5
5
|
import { PY_AGENT_GENERATOR_INFO } from "../py/agent/generator.js";
|
|
6
|
-
import { PY_MCP_SERVER_GENERATOR_INFO } from "../py/mcp-server/generator.js";
|
|
7
|
-
import { TS_MCP_SERVER_GENERATOR_INFO } from "../ts/mcp-server/generator.js";
|
|
8
6
|
import { ensureAwsNxPluginConfig } from "../utils/config/utils.js";
|
|
9
7
|
import { formatFilesInSubtree } from "../utils/format.js";
|
|
10
8
|
import { addGeneratorMetricsIfApplicable } from "../utils/metrics.js";
|
|
11
9
|
import { getGeneratorInfo, mergeTargetDefault } from "../utils/nx.js";
|
|
12
10
|
import { addLicenseCheckToAllLintTargets, defaultLicenseConfig, ensureDependencyCheckBlock, ensureLicenseExceptions, ensurePythonLicenseCollector, updateLicenseCheckTargetInputs, writeLicenseConfig } from "./config.js";
|
|
13
|
-
import { AG_UI_LANGGRAPH_EXCEPTIONS
|
|
11
|
+
import { AG_UI_LANGGRAPH_EXCEPTIONS } from "./known-exceptions.js";
|
|
14
12
|
import { SYNC_GENERATOR_NAME } from "./sync/generator.js";
|
|
15
13
|
export const LICENSE_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
16
14
|
export async function licenseGenerator(tree, options) {
|
|
@@ -92,35 +90,23 @@ export async function licenseGenerator(tree, options) {
|
|
|
92
90
|
};
|
|
93
91
|
const addExceptionsForExistingProjects = async (tree)=>{
|
|
94
92
|
const projects = getProjects(tree);
|
|
95
|
-
let needsMcp = false;
|
|
96
93
|
// A LangChain AG-UI agent pulls jsonpatch/jsonpointer (BSD-3-Clause but with
|
|
97
94
|
// only free-text metadata) via langchain-core. The py#agent generator adds
|
|
98
95
|
// these exceptions itself, but if the license generator runs afterwards (or
|
|
99
96
|
// the agent predates the dependency-check block) they may be missing, so
|
|
100
97
|
// re-assert them here when such an agent exists.
|
|
101
98
|
let needsLangchain = false;
|
|
102
|
-
const mcpIds = [
|
|
103
|
-
TS_MCP_SERVER_GENERATOR_INFO.id,
|
|
104
|
-
PY_MCP_SERVER_GENERATOR_INFO.id
|
|
105
|
-
];
|
|
106
99
|
for (const [, config] of projects){
|
|
107
100
|
const components = config.metadata?.components ?? config.metadata?.generators ?? [];
|
|
108
101
|
for (const comp of components){
|
|
109
102
|
const gen = comp.generator ?? comp;
|
|
110
|
-
if (typeof gen === 'string' && mcpIds.includes(gen)) {
|
|
111
|
-
needsMcp = true;
|
|
112
|
-
}
|
|
113
103
|
if (gen === PY_AGENT_GENERATOR_INFO.id && comp.framework === 'langchain') {
|
|
114
104
|
needsLangchain = true;
|
|
115
105
|
}
|
|
116
106
|
}
|
|
117
107
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
...needsLangchain ? AG_UI_LANGGRAPH_EXCEPTIONS : []
|
|
121
|
-
];
|
|
122
|
-
if (exceptions.length > 0) {
|
|
123
|
-
await ensureLicenseExceptions(tree, exceptions);
|
|
108
|
+
if (needsLangchain) {
|
|
109
|
+
await ensureLicenseExceptions(tree, AG_UI_LANGGRAPH_EXCEPTIONS);
|
|
124
110
|
}
|
|
125
111
|
};
|
|
126
112
|
const hasPythonProjects = (tree)=>{
|