@aws/nx-plugin 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +31 -29
  2. package/generators.json +16 -0
  3. package/migrations.json +6 -1
  4. package/package.json +1 -1
  5. package/src/agentcore-harness/generator.d.ts +1 -1
  6. package/src/greengrass/component/common.d.ts +60 -0
  7. package/src/greengrass/component/common.js +191 -0
  8. package/src/greengrass/component/common.js.map +1 -0
  9. package/src/greengrass/component/dependencies.d.ts +101 -0
  10. package/src/greengrass/component/dependencies.js +37 -0
  11. package/src/greengrass/component/dependencies.js.map +1 -0
  12. package/src/greengrass/component/generator.d.ts +174 -0
  13. package/src/greengrass/component/generator.js +32 -0
  14. package/src/greengrass/component/generator.js.map +1 -0
  15. package/src/greengrass/component/metadata.d.ts +2 -0
  16. package/src/greengrass/component/metadata.js +14 -0
  17. package/src/greengrass/component/metadata.js.map +1 -0
  18. package/src/greengrass/component/python/__snapshots__/generator.spec.ts.snap +450 -0
  19. package/src/greengrass/component/python/files/component/main.py.template +60 -0
  20. package/src/greengrass/component/python/files/component/recipe.yaml.template +30 -0
  21. package/src/greengrass/component/python/files/gdk/gdk-config.json.template +13 -0
  22. package/src/greengrass/component/python/files/tests/test___componentSnakeCase__.py.template +37 -0
  23. package/src/greengrass/component/python/generator.d.ts +15 -0
  24. package/src/greengrass/component/python/generator.js +192 -0
  25. package/src/greengrass/component/python/generator.js.map +1 -0
  26. package/src/greengrass/component/schema.d.js +6 -0
  27. package/src/greengrass/component/schema.d.js.map +1 -0
  28. package/src/greengrass/component/schema.d.ts +18 -0
  29. package/src/greengrass/component/schema.json +82 -0
  30. package/src/greengrass/component/typescript/__snapshots__/generator.spec.ts.snap +275 -0
  31. package/src/greengrass/component/typescript/files/component/recipe.yaml.template +41 -0
  32. package/src/greengrass/component/typescript/files/entrypoint/main.ts.template +58 -0
  33. package/src/greengrass/component/typescript/files/gdk/gdk-config.json.template +13 -0
  34. package/src/greengrass/component/typescript/files/scripts/vendor-crt-addon.ts.template +115 -0
  35. package/src/greengrass/component/typescript/generator.d.ts +16 -0
  36. package/src/greengrass/component/typescript/generator.js +194 -0
  37. package/src/greengrass/component/typescript/generator.js.map +1 -0
  38. package/src/infra/app/generator.d.ts +1 -1
  39. package/src/init/generator.d.ts +1 -1
  40. package/src/internal/test-matrix/generator.js +48 -1
  41. package/src/internal/test-matrix/generator.js.map +1 -1
  42. package/src/license/dependency-check/pre-approved.js +2 -1
  43. package/src/license/dependency-check/pre-approved.js.map +1 -1
  44. package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/metadata.json +3 -0
  45. package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/migration.d.ts +6 -0
  46. package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/migration.js +118 -0
  47. package/src/migrations/latest/ts-agent-guardrails-terraform-version-retention/migration.js.map +1 -0
  48. package/src/open-api/py-client/generator.d.ts +1 -1
  49. package/src/preset/__snapshots__/generator.spec.ts.snap +4 -0
  50. package/src/preset/generator.d.ts +1 -1
  51. package/src/py/agent/a2a-connection/generator.d.ts +1 -1
  52. package/src/py/agent/gateway-connection/generator.d.ts +1 -1
  53. package/src/py/agent/guardrails/__snapshots__/generator.spec.ts.snap +3813 -0
  54. package/src/py/agent/guardrails/files/langchain/guardrail.py.template +135 -0
  55. package/src/py/agent/guardrails/files/strands/guardrail.py.template +93 -0
  56. package/src/py/agent/guardrails/generator.d.ts +10 -0
  57. package/src/py/agent/guardrails/generator.js +175 -0
  58. package/src/py/agent/guardrails/generator.js.map +1 -0
  59. package/src/py/agent/guardrails/runtime-check/run_checks.py +250 -0
  60. package/src/py/agent/guardrails/schema.d.js +6 -0
  61. package/src/py/agent/guardrails/schema.d.js.map +1 -0
  62. package/src/py/agent/guardrails/schema.d.ts +9 -0
  63. package/src/py/agent/guardrails/schema.json +25 -0
  64. package/src/py/agent/mcp-connection/generator.d.ts +1 -1
  65. package/src/py/agent/react-connection/generator.d.ts +1 -1
  66. package/src/py/fast-api/react/generator.d.ts +1 -1
  67. package/src/py/project/generator.js +2 -0
  68. package/src/py/project/generator.js.map +1 -1
  69. package/src/sdk/greengrass.d.ts +6 -0
  70. package/src/sdk/greengrass.js +6 -0
  71. package/src/sdk/greengrass.js.map +1 -0
  72. package/src/sdk/py.d.ts +2 -0
  73. package/src/sdk/py.js +1 -0
  74. package/src/sdk/py.js.map +1 -1
  75. package/src/smithy/project/generator.d.ts +1 -1
  76. package/src/smithy/react-connection/generator.d.ts +1 -1
  77. package/src/terraform/project/generator.d.ts +1 -1
  78. package/src/trpc/react/generator.d.ts +1 -1
  79. package/src/ts/agent/a2a-connection/generator.d.ts +1 -1
  80. package/src/ts/agent/gateway-connection/generator.d.ts +1 -1
  81. package/src/ts/agent/guardrails/__snapshots__/generator.spec.ts.snap +54 -3
  82. package/src/ts/agent/guardrails/generator.js +2 -1
  83. package/src/ts/agent/guardrails/generator.js.map +1 -1
  84. package/src/ts/agent/mcp-connection/generator.d.ts +1 -1
  85. package/src/ts/agent/react-connection/generator.d.ts +1 -1
  86. package/src/ts/astro-docs/generator.d.ts +1 -1
  87. package/src/ts/dcr-proxy/generator.d.ts +1 -1
  88. package/src/ts/dynamodb/generator.d.ts +1 -1
  89. package/src/ts/lambda-function/generator.d.ts +1 -1
  90. package/src/ts/lib/generator.d.ts +1 -1
  91. package/src/ts/nx-generator/generator.d.ts +1 -1
  92. package/src/ts/nx-migration/generator.d.ts +1 -1
  93. package/src/ts/nx-plugin/generator.d.ts +1 -1
  94. package/src/ts/rdb/generator.d.ts +1 -1
  95. package/src/ts/react-website/agui/generator.d.ts +1 -1
  96. package/src/utils/__snapshots__/shared-greengrass-scripts.spec.ts.snap +1279 -0
  97. package/src/utils/files/common/scripts/src/greengrass/build-artifact.ts.template +236 -0
  98. package/src/utils/files/common/scripts/src/greengrass/component-logs.ts.template +48 -0
  99. package/src/utils/files/common/scripts/src/greengrass/deploy-local.ts.template +497 -0
  100. package/src/utils/files/common/scripts/src/greengrass/recipe-utils.ts.template +356 -0
  101. package/src/utils/files/common/scripts/src/greengrass/zip-writer.ts.template +121 -0
  102. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +3 -3
  103. package/src/utils/files/terraform/src/metrics/metrics.tf.template +1 -1
  104. package/src/utils/greengrass/constants.d.ts +58 -0
  105. package/src/utils/greengrass/constants.js +63 -0
  106. package/src/utils/greengrass/constants.js.map +1 -0
  107. package/src/utils/greengrass/naming.d.ts +46 -0
  108. package/src/utils/greengrass/naming.js +67 -0
  109. package/src/utils/greengrass/naming.js.map +1 -0
  110. package/src/utils/greengrass/recipe.d.ts +143 -0
  111. package/src/utils/greengrass/recipe.js +119 -0
  112. package/src/utils/greengrass/recipe.js.map +1 -0
  113. package/src/utils/greengrass-constructs/files/cdk/app/greengrass-component/__componentDirName__.ts.template +42 -0
  114. package/src/utils/greengrass-constructs/files/cdk/core/greengrass/artifact-bucket.ts.template +82 -0
  115. package/src/utils/greengrass-constructs/files/cdk/core/greengrass/component-version.ts.template +370 -0
  116. package/src/utils/greengrass-constructs/files/cdk/core/greengrass/deployment.ts.template +276 -0
  117. package/src/utils/greengrass-constructs/files/cdk/core/greengrass/index.ts.template +5 -0
  118. package/src/utils/greengrass-constructs/files/cdk/core/greengrass/next-version.ts.template +119 -0
  119. package/src/utils/greengrass-constructs/files/cdk/core/greengrass/recipe.ts.template +90 -0
  120. package/src/utils/greengrass-constructs/files/next-version/__nextVersionFileName__.template +195 -0
  121. package/src/utils/greengrass-constructs/files/terraform/app/greengrass-component/__componentDirName__/__componentDirName__.tf.template +26 -0
  122. package/src/utils/greengrass-constructs/files/terraform/core/greengrass/artifact-bucket/main.tf.template +204 -0
  123. package/src/utils/greengrass-constructs/files/terraform/core/greengrass/component-version/main.tf.template +156 -0
  124. package/src/utils/greengrass-constructs/files/terraform/core/greengrass/deployment/main.tf.template +186 -0
  125. package/src/utils/greengrass-constructs/greengrass-constructs.d.ts +57 -0
  126. package/src/utils/greengrass-constructs/greengrass-constructs.js +154 -0
  127. package/src/utils/greengrass-constructs/greengrass-constructs.js.map +1 -0
  128. package/src/utils/guardrail-constructs/files/terraform/app/guardrails/__nameKebabCase__/__nameKebabCase__-guardrail.tf.template +18 -1
  129. package/src/utils/guardrail-constructs/guardrail-constructs.d.ts +5 -0
  130. package/src/utils/guardrail-constructs/guardrail-constructs.js +8 -0
  131. package/src/utils/guardrail-constructs/guardrail-constructs.js.map +1 -1
  132. package/src/utils/guardrail-constructs/guardrail-wiring.d.ts +7 -0
  133. package/src/utils/guardrail-constructs/guardrail-wiring.js +6 -5
  134. package/src/utils/guardrail-constructs/guardrail-wiring.js.map +1 -1
  135. package/src/utils/nx.d.ts +15 -0
  136. package/src/utils/nx.js +32 -0
  137. package/src/utils/nx.js.map +1 -1
  138. package/src/utils/shared-greengrass-scripts.d.ts +21 -0
  139. package/src/utils/shared-greengrass-scripts.js +43 -0
  140. package/src/utils/shared-greengrass-scripts.js.map +1 -0
  141. package/src/utils/test/fake-aws/fake_aws.py +205 -0
  142. package/src/utils/test/python-dependencies.d.ts +6 -0
  143. package/src/utils/test/python-dependencies.js +19 -0
  144. package/src/utils/test/python-dependencies.js.map +1 -1
  145. package/src/utils/test/warm-python-cache.js +5 -1
  146. package/src/utils/test/warm-python-cache.js.map +1 -1
  147. package/src/utils/versions.d.ts +7 -0
  148. package/src/utils/versions.js +7 -0
  149. package/src/utils/versions.js.map +1 -1
  150. /package/src/{ts/agent/guardrails/files/agent → utils/guardrail-constructs/files/policy}/guardrail.json.template +0 -0
@@ -0,0 +1,236 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+ import yaml from 'js-yaml';
4
+ import { loadRecipe, validateManifestArchitectures, validateRecipe } from './recipe-utils<% if (esm) { %>.js<% } %>';
5
+ import { writeZip, type ZipEntry } from './zip-writer<% if (esm) { %>.js<% } %>';
6
+
7
+ /*
8
+ * Usage: build-artifact.ts <project-root> <component-dir> <dist> [bundle-dir] [--platforms=<arch>,<arch>]
9
+ *
10
+ * <project-root> path to the host project (e.g. a Python project root)
11
+ * <component-dir> the component's directory name under <project-root>/greengrass/,
12
+ * which also becomes the artifact zip's base name
13
+ * <dist> the component's dist root: reads <dist>/vendor (produced by
14
+ * the "-vendor" target this target depends on) and writes
15
+ * <dist>/greengrass-build/{recipes,artifacts}
16
+ * <bundle-dir> optional: a directory of already-bundled deployable code
17
+ * (e.g. a TypeScript rolldown bundle output). When given and
18
+ * it exists, its contents are zipped at the archive root
19
+ * INSTEAD of <project-root>/greengrass/<component-dir>/ and
20
+ * <dist>/vendor - a compiled bundle is the deployable
21
+ * content, so the TypeScript source that produced it must
22
+ * not also ship. <project-root>/greengrass/<component-dir>/package.json,
23
+ * when present, is included too (the minimal manifest an
24
+ * Install lifecycle step's `npm install` needs for a native
25
+ * dependency the bundle marked external).
26
+ * --platforms optional: a comma-separated list of manifest architecture
27
+ * tokens (e.g. "amd64,aarch64"). When given, <dist>/vendor/<arch>
28
+ * is read per architecture and one <component-dir>-<arch>.zip
29
+ * is written per architecture, and every recipe manifest
30
+ * declaring one of these architectures must pair with that
31
+ * architecture's own zip. Cannot be combined with
32
+ * <bundle-dir>. Without it, behaviour is exactly as before:
33
+ * flat <dist>/vendor, one <component-dir>.zip.
34
+ *
35
+ * Without <bundle-dir>, everything under <project-root>/greengrass/<component-dir>/
36
+ * is packaged except recipe.yaml and gdk-config.json, which are framework
37
+ * metadata, not deployed code, and __pycache__ and .lock, which are tool
38
+ * staging output.
39
+ */
40
+
41
+ const log = (msg: string): void => console.error(`[build-artifact] ${msg}`);
42
+
43
+ function usage(): never {
44
+ log(
45
+ 'Usage: build-artifact.ts <project-root> <component-dir> <dist> [bundle-dir] [--platforms=<arch>,<arch>]',
46
+ );
47
+ process.exit(1);
48
+ }
49
+
50
+ /**
51
+ * Every file under `dir`, recursively, excluding top-level names in `exclude`
52
+ * and `__pycache__` directories at any depth.
53
+ */
54
+ function collectFiles(dir: string, exclude: ReadonlySet<string>): string[] {
55
+ const results: string[] = [];
56
+ const walk = (current: string, isRoot: boolean): void => {
57
+ for (const entry of readdirSync(current)) {
58
+ if (entry === '__pycache__' || (isRoot && exclude.has(entry))) continue;
59
+ const fullPath = join(current, entry);
60
+ if (statSync(fullPath).isDirectory()) {
61
+ walk(fullPath, false);
62
+ } else {
63
+ results.push(fullPath);
64
+ }
65
+ }
66
+ };
67
+ walk(dir, true);
68
+ return results;
69
+ }
70
+
71
+ /** Zip entries for every file under `dir`, named relative to `dir` with forward slashes. */
72
+ function entriesFrom(dir: string, exclude: ReadonlySet<string>): ZipEntry[] {
73
+ return collectFiles(dir, exclude).map((filePath) => ({
74
+ name: relative(dir, filePath).split('\\').join('/'),
75
+ data: readFileSync(filePath),
76
+ }));
77
+ }
78
+
79
+ function main(): void {
80
+ const argv = process.argv.slice(2);
81
+ const PLATFORMS_FLAG = '--platforms=';
82
+ const platforms = argv
83
+ .filter((a) => a.startsWith(PLATFORMS_FLAG))
84
+ .flatMap((a) => a.slice(PLATFORMS_FLAG.length).split(','))
85
+ .map((a) => a.trim())
86
+ .filter((a) => a.length > 0);
87
+ const [projectRoot, componentDirName, dist, bundleDir] = argv.filter(
88
+ (a) => !a.startsWith(PLATFORMS_FLAG),
89
+ );
90
+ if (!projectRoot || !componentDirName || !dist) {
91
+ usage();
92
+ }
93
+
94
+ if (platforms.length > 0 && bundleDir) {
95
+ log(
96
+ '--platforms cannot be combined with a bundle-dir: per-architecture copies of one bundle would all hold identical bytes. Drop --platforms and serve both architectures from a single artifact with two manifests.',
97
+ );
98
+ process.exit(1);
99
+ return;
100
+ }
101
+
102
+ const componentDir = join(projectRoot, 'greengrass', componentDirName);
103
+ const recipePath = join(componentDir, 'recipe.yaml');
104
+ const baseNameByArchitecture = Object.fromEntries(
105
+ platforms.map((arch) => [arch, `${componentDirName}-${arch}`]),
106
+ );
107
+ const artifactBaseNames =
108
+ platforms.length === 0
109
+ ? [componentDirName]
110
+ : platforms.map((arch) => baseNameByArchitecture[arch]);
111
+
112
+ let componentName: string;
113
+ let componentVersion: string;
114
+ let recipe: ReturnType<typeof loadRecipe>;
115
+ try {
116
+ recipe = loadRecipe(recipePath);
117
+ ({ componentName, componentVersion } = validateRecipe(
118
+ recipe,
119
+ artifactBaseNames,
120
+ ));
121
+ // Only meaningful per architecture, so only checked when this build knows
122
+ // which architecture each zip is for.
123
+ if (platforms.length > 0) {
124
+ validateManifestArchitectures(recipe, baseNameByArchitecture);
125
+ }
126
+ } catch (e) {
127
+ log((e as Error).message);
128
+ process.exit(1);
129
+ return;
130
+ }
131
+
132
+ const vendorDir = join(dist, 'vendor');
133
+ // Recipe and artifact paths are named by version, so a rebuild after a
134
+ // version bump would otherwise accumulate stale siblings - and the
135
+ // GreengrassComponentVersion construct requires exactly one resolved
136
+ // recipe. Start from an empty greengrass-build every run.
137
+ rmSync(join(dist, 'greengrass-build'), { recursive: true, force: true });
138
+ const artifactDir = join(
139
+ dist,
140
+ 'greengrass-build',
141
+ 'artifacts',
142
+ componentName,
143
+ componentVersion,
144
+ );
145
+ const recipesDir = join(dist, 'greengrass-build', 'recipes');
146
+ mkdirSync(artifactDir, { recursive: true });
147
+ mkdirSync(recipesDir, { recursive: true });
148
+
149
+ if (platforms.length > 0) {
150
+ // Multi-architecture: one zip per architecture, each holding the
151
+ // component's own files plus that architecture's own vendored wheels.
152
+ for (const arch of platforms) {
153
+ const archVendorDir = join(vendorDir, arch);
154
+ if (!existsSync(archVendorDir)) {
155
+ log(
156
+ `Missing vendored dependencies for "${arch}" at "${archVendorDir}" - run the component's "-vendor" target first (it writes one directory per architecture when the component targets more than one).`,
157
+ );
158
+ process.exit(1);
159
+ return;
160
+ }
161
+ const entries = [
162
+ ...entriesFrom(
163
+ componentDir,
164
+ new Set(['recipe.yaml', 'gdk-config.json', '.lock']),
165
+ ),
166
+ ...entriesFrom(archVendorDir, new Set(['.lock'])),
167
+ ];
168
+ if (entries.length === 0) {
169
+ log(
170
+ `Nothing to package for "${arch}": "${componentDir}" has no deployable files and "${archVendorDir}" has no vendored dependencies`,
171
+ );
172
+ process.exit(1);
173
+ return;
174
+ }
175
+ const zipPath = join(artifactDir, `${componentDirName}-${arch}.zip`);
176
+ writeZip(entries, zipPath);
177
+ log(`wrote ${zipPath}`);
178
+ }
179
+ } else {
180
+ let entries: ZipEntry[];
181
+ if (bundleDir && existsSync(bundleDir)) {
182
+ // A pre-bundled language (e.g. TypeScript via rolldown): the bundle
183
+ // output is the deployable content, so the source that produced it is
184
+ // never packaged.
185
+ entries = entriesFrom(bundleDir, new Set(['.lock']));
186
+ const packageJsonPath = join(componentDir, 'package.json');
187
+ if (existsSync(packageJsonPath)) {
188
+ // Ships alongside the bundle only when an Install lifecycle step needs
189
+ // it (e.g. `npm install` for a native dependency the bundle marked
190
+ // external) - absent for a fully self-contained bundle.
191
+ entries.push({
192
+ name: 'package.json',
193
+ data: readFileSync(packageJsonPath),
194
+ });
195
+ }
196
+ } else {
197
+ // Framework metadata that ships alongside the recipe but never inside
198
+ // the deployed artifact. A package.json here is the user's own, so it is
199
+ // packaged like any other source file - only bundle mode treats one as
200
+ // framework metadata.
201
+ entries = entriesFrom(
202
+ componentDir,
203
+ new Set(['recipe.yaml', 'gdk-config.json', '.lock']),
204
+ );
205
+ if (existsSync(vendorDir)) {
206
+ // requirements.txt is the "-vendor" target's own intermediate, not
207
+ // something the device needs.
208
+ entries.push(
209
+ ...entriesFrom(vendorDir, new Set(['requirements.txt', '.lock'])),
210
+ );
211
+ }
212
+ }
213
+ if (entries.length === 0) {
214
+ log(
215
+ `Nothing to package: "${bundleDir && existsSync(bundleDir) ? bundleDir : componentDir}" has no deployable files and "${vendorDir}" does not exist`,
216
+ );
217
+ process.exit(1);
218
+ return;
219
+ }
220
+
221
+ const zipPath = join(artifactDir, `${componentDirName}.zip`);
222
+ writeZip(entries, zipPath);
223
+ log(`wrote ${zipPath}`);
224
+ }
225
+
226
+ // The BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION artifact URI placeholders
227
+ // are left exactly as authored - a later IaC step substitutes them.
228
+ const recipeOutPath = join(
229
+ recipesDir,
230
+ `${componentName}-${componentVersion}.yaml`,
231
+ );
232
+ writeFileSync(recipeOutPath, yaml.dump(recipe, { lineWidth: -1 }));
233
+ log(`wrote ${recipeOutPath}`);
234
+ }
235
+
236
+ main();
@@ -0,0 +1,48 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { join } from 'node:path';
3
+
4
+ /*
5
+ * Usage: component-logs.ts <component-name>
6
+ *
7
+ * <component-name> the recipe's ComponentName, e.g. "com.example.MyComponent"
8
+ *
9
+ * Tails <GREENGRASS_ROOT>/logs/<component-name>.log in follow mode. Ctrl-C
10
+ * (SIGINT) stops it - this target never exits on its own.
11
+ */
12
+
13
+ const log = (msg: string): void => console.error(`[component-logs] ${msg}`);
14
+
15
+ function usage(): never {
16
+ log('Usage: component-logs.ts <component-name>');
17
+ process.exit(1);
18
+ }
19
+
20
+ function main(): void {
21
+ const [componentName] = process.argv.slice(2);
22
+ if (!componentName) {
23
+ usage();
24
+ }
25
+
26
+ const greengrassRoot = process.env.GREENGRASS_ROOT || '/greengrass/v2';
27
+ const logPath = join(greengrassRoot, 'logs', `${componentName}.log`);
28
+
29
+ log(`Tailing ${logPath} - Ctrl-C to stop`);
30
+ const tail = spawn('tail', ['-n', '200', '-f', logPath], {
31
+ stdio: 'inherit',
32
+ });
33
+
34
+ const stop = (): void => {
35
+ tail.kill();
36
+ process.exit(0);
37
+ };
38
+ process.on('SIGINT', stop);
39
+ process.on('SIGTERM', stop);
40
+
41
+ tail.on('exit', (code) => process.exit(code ?? 0));
42
+ tail.on('error', (err) => {
43
+ log(`Failed to start tail: ${err.message}`);
44
+ process.exit(1);
45
+ });
46
+ }
47
+
48
+ main();