@aws/nx-plugin 1.1.0 → 1.2.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.
- package/README.md +30 -29
- package/generators.json +8 -0
- package/migrations.json +6 -1
- package/package.json +1 -1
- package/src/agentcore-harness/generator.d.ts +1 -1
- package/src/greengrass/component/common.d.ts +60 -0
- package/src/greengrass/component/common.js +191 -0
- package/src/greengrass/component/common.js.map +1 -0
- package/src/greengrass/component/dependencies.d.ts +101 -0
- package/src/greengrass/component/dependencies.js +37 -0
- package/src/greengrass/component/dependencies.js.map +1 -0
- package/src/greengrass/component/generator.d.ts +174 -0
- package/src/greengrass/component/generator.js +32 -0
- package/src/greengrass/component/generator.js.map +1 -0
- package/src/greengrass/component/metadata.d.ts +2 -0
- package/src/greengrass/component/metadata.js +14 -0
- package/src/greengrass/component/metadata.js.map +1 -0
- package/src/greengrass/component/python/__snapshots__/generator.spec.ts.snap +450 -0
- package/src/greengrass/component/python/files/component/main.py.template +60 -0
- package/src/greengrass/component/python/files/component/recipe.yaml.template +30 -0
- package/src/greengrass/component/python/files/gdk/gdk-config.json.template +13 -0
- package/src/greengrass/component/python/files/tests/test___componentSnakeCase__.py.template +37 -0
- package/src/greengrass/component/python/generator.d.ts +15 -0
- package/src/greengrass/component/python/generator.js +192 -0
- package/src/greengrass/component/python/generator.js.map +1 -0
- package/src/greengrass/component/schema.d.js +6 -0
- package/src/greengrass/component/schema.d.js.map +1 -0
- package/src/greengrass/component/schema.d.ts +18 -0
- package/src/greengrass/component/schema.json +82 -0
- package/src/greengrass/component/typescript/__snapshots__/generator.spec.ts.snap +275 -0
- package/src/greengrass/component/typescript/files/component/recipe.yaml.template +41 -0
- package/src/greengrass/component/typescript/files/entrypoint/main.ts.template +58 -0
- package/src/greengrass/component/typescript/files/gdk/gdk-config.json.template +13 -0
- package/src/greengrass/component/typescript/files/scripts/vendor-crt-addon.ts.template +115 -0
- package/src/greengrass/component/typescript/generator.d.ts +16 -0
- package/src/greengrass/component/typescript/generator.js +194 -0
- package/src/greengrass/component/typescript/generator.js.map +1 -0
- package/src/infra/app/generator.d.ts +1 -1
- package/src/init/generator.d.ts +1 -1
- package/src/internal/test-matrix/generator.js +42 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/license/dependency-check/pre-approved.js +2 -1
- package/src/license/dependency-check/pre-approved.js.map +1 -1
- package/src/migrations/latest/ts-agent-guardrails-synth-input/metadata.json +3 -0
- package/src/migrations/latest/ts-agent-guardrails-synth-input/migration.d.ts +22 -0
- package/src/migrations/latest/ts-agent-guardrails-synth-input/migration.js +42 -0
- package/src/migrations/latest/ts-agent-guardrails-synth-input/migration.js.map +1 -0
- package/src/open-api/py-client/generator.d.ts +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/preset/generator.d.ts +1 -1
- package/src/py/agent/a2a-connection/generator.d.ts +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +1 -1
- package/src/py/agent/mcp-connection/generator.d.ts +1 -1
- package/src/py/agent/react-connection/generator.d.ts +1 -1
- package/src/py/fast-api/react/generator.d.ts +1 -1
- package/src/py/project/generator.js +2 -0
- package/src/py/project/generator.js.map +1 -1
- package/src/sdk/greengrass.d.ts +6 -0
- package/src/sdk/greengrass.js +6 -0
- package/src/sdk/greengrass.js.map +1 -0
- package/src/smithy/project/generator.d.ts +1 -1
- package/src/smithy/react-connection/generator.d.ts +1 -1
- package/src/terraform/project/generator.d.ts +1 -1
- package/src/trpc/react/generator.d.ts +1 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +1 -1
- package/src/ts/agent/gateway-connection/generator.d.ts +1 -1
- package/src/ts/agent/guardrails/generator.js +10 -1
- package/src/ts/agent/guardrails/generator.js.map +1 -1
- package/src/ts/agent/guardrails/synth-inputs.d.ts +19 -0
- package/src/ts/agent/guardrails/synth-inputs.js +50 -0
- package/src/ts/agent/guardrails/synth-inputs.js.map +1 -0
- 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/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/generator.d.ts +1 -1
- package/src/ts/react-website/agui/generator.d.ts +1 -1
- package/src/utils/__snapshots__/shared-greengrass-scripts.spec.ts.snap +1279 -0
- package/src/utils/files/common/scripts/src/greengrass/build-artifact.ts.template +236 -0
- package/src/utils/files/common/scripts/src/greengrass/component-logs.ts.template +48 -0
- package/src/utils/files/common/scripts/src/greengrass/deploy-local.ts.template +497 -0
- package/src/utils/files/common/scripts/src/greengrass/recipe-utils.ts.template +356 -0
- package/src/utils/files/common/scripts/src/greengrass/zip-writer.ts.template +121 -0
- package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +3 -3
- package/src/utils/files/terraform/src/metrics/metrics.tf.template +1 -1
- package/src/utils/greengrass/constants.d.ts +58 -0
- package/src/utils/greengrass/constants.js +63 -0
- package/src/utils/greengrass/constants.js.map +1 -0
- package/src/utils/greengrass/naming.d.ts +46 -0
- package/src/utils/greengrass/naming.js +67 -0
- package/src/utils/greengrass/naming.js.map +1 -0
- package/src/utils/greengrass/recipe.d.ts +143 -0
- package/src/utils/greengrass/recipe.js +119 -0
- package/src/utils/greengrass/recipe.js.map +1 -0
- package/src/utils/greengrass-constructs/files/cdk/app/greengrass-component/__componentDirName__.ts.template +42 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/artifact-bucket.ts.template +82 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/component-version.ts.template +370 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/deployment.ts.template +276 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/index.ts.template +5 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/next-version.ts.template +119 -0
- package/src/utils/greengrass-constructs/files/cdk/core/greengrass/recipe.ts.template +90 -0
- package/src/utils/greengrass-constructs/files/next-version/__nextVersionFileName__.template +195 -0
- package/src/utils/greengrass-constructs/files/terraform/app/greengrass-component/__componentDirName__/__componentDirName__.tf.template +26 -0
- package/src/utils/greengrass-constructs/files/terraform/core/greengrass/artifact-bucket/main.tf.template +204 -0
- package/src/utils/greengrass-constructs/files/terraform/core/greengrass/component-version/main.tf.template +156 -0
- package/src/utils/greengrass-constructs/files/terraform/core/greengrass/deployment/main.tf.template +186 -0
- package/src/utils/greengrass-constructs/greengrass-constructs.d.ts +57 -0
- package/src/utils/greengrass-constructs/greengrass-constructs.js +154 -0
- package/src/utils/greengrass-constructs/greengrass-constructs.js.map +1 -0
- package/src/utils/guardrail-constructs/guardrail-constructs.d.ts +3 -1
- package/src/utils/guardrail-constructs/guardrail-constructs.js +3 -1
- package/src/utils/guardrail-constructs/guardrail-constructs.js.map +1 -1
- package/src/utils/nx.d.ts +15 -0
- package/src/utils/nx.js +32 -0
- package/src/utils/nx.js.map +1 -1
- package/src/utils/shared-greengrass-scripts.d.ts +21 -0
- package/src/utils/shared-greengrass-scripts.js +43 -0
- package/src/utils/shared-greengrass-scripts.js.map +1 -0
- package/src/utils/versions.d.ts +7 -0
- package/src/utils/versions.js +7 -0
- package/src/utils/versions.js.map +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<%_ if (ipc) { _%>
|
|
2
|
+
import { greengrasscoreipc } from 'aws-iot-device-sdk-v2';
|
|
3
|
+
|
|
4
|
+
const TOPIC = '<%- componentName %>/heartbeat';
|
|
5
|
+
const PUBLISH_INTERVAL_MS = 30_000;
|
|
6
|
+
|
|
7
|
+
async function getIpcClient(): Promise<greengrasscoreipc.Client> {
|
|
8
|
+
const client = greengrasscoreipc.createClient();
|
|
9
|
+
await client.connect();
|
|
10
|
+
return client;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function publishHeartbeat(
|
|
14
|
+
client: greengrasscoreipc.Client,
|
|
15
|
+
sequence: number,
|
|
16
|
+
): Promise<void> {
|
|
17
|
+
const request: greengrasscoreipc.model.PublishToTopicRequest = {
|
|
18
|
+
topic: TOPIC,
|
|
19
|
+
publishMessage: { jsonMessage: { message: { sequence } } },
|
|
20
|
+
};
|
|
21
|
+
await client.publishToTopic(request);
|
|
22
|
+
console.log(`Published heartbeat ${sequence} to ${TOPIC}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function main(): Promise<void> {
|
|
26
|
+
const client = await getIpcClient();
|
|
27
|
+
let sequence = 0;
|
|
28
|
+
for (;;) {
|
|
29
|
+
await publishHeartbeat(client, sequence);
|
|
30
|
+
sequence += 1;
|
|
31
|
+
await new Promise((resolve) => setTimeout(resolve, PUBLISH_INTERVAL_MS));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
main().catch((error) => {
|
|
36
|
+
console.error(error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
|
39
|
+
<%_ } else { _%>
|
|
40
|
+
const RUN_INTERVAL_MS = 30_000;
|
|
41
|
+
|
|
42
|
+
export function runOnce(sequence: number): void {
|
|
43
|
+
console.log(
|
|
44
|
+
`[<%- componentName %>] heartbeat ${sequence} at ${new Date().toISOString()}`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function main(): Promise<void> {
|
|
49
|
+
let sequence = 0;
|
|
50
|
+
for (;;) {
|
|
51
|
+
runOnce(sequence);
|
|
52
|
+
sequence += 1;
|
|
53
|
+
await new Promise((resolve) => setTimeout(resolve, RUN_INTERVAL_MS));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main();
|
|
58
|
+
<%_ } _%>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"component": {
|
|
3
|
+
"<%- componentName %>": {
|
|
4
|
+
"author": "<%- publisher %>",
|
|
5
|
+
"version": "<%- version %>",
|
|
6
|
+
"build": {
|
|
7
|
+
"build_system": "custom",
|
|
8
|
+
"custom_build_command": ["nx", "run", "<%- project %>:<%- componentDirName %>-artifact"]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"gdk_version": "1.0.0"
|
|
13
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* Usage: vendor-crt-addon.ts <project-root> <bundle-dir> <stage-dir> <addon-dir>[,<addon-dir>]
|
|
7
|
+
*
|
|
8
|
+
* Writes the deployable tree for an ipc=true TypeScript Greengrass component:
|
|
9
|
+
* every file from <bundle-dir> at the tree root, plus
|
|
10
|
+
* native/aws-crt/<addon-dir>/aws-crt-nodejs.node for each requested addon dir,
|
|
11
|
+
* copied out of the installed aws-crt. <stage-dir> is then the `bundle-dir`
|
|
12
|
+
* build-artifact.ts zips, so build-artifact.ts needs no knowledge of any of
|
|
13
|
+
* this. <addon-dir> is aws-crt's own
|
|
14
|
+
* `<platform>-<arch>-<cRuntime>` directory name, e.g. linux-arm64-glibc.
|
|
15
|
+
*
|
|
16
|
+
* aws-crt publishes its addon prebuilt for every platform it supports, so this
|
|
17
|
+
* is a file copy, never a compile, and the device never installs anything.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const log = (msg: string): void => console.error(`[vendor-crt-addon] ${msg}`);
|
|
21
|
+
|
|
22
|
+
function usage(): never {
|
|
23
|
+
log(
|
|
24
|
+
'Usage: vendor-crt-addon.ts <project-root> <bundle-dir> <stage-dir> <addon-dir>[,<addon-dir>]',
|
|
25
|
+
);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The directory of `specifier`'s package.json, resolved from `fromPath`. Falls
|
|
31
|
+
* back to walking up from the resolved entry point, because a package with an
|
|
32
|
+
* `exports` map need not expose its own package.json. Both the subpath
|
|
33
|
+
* resolve and the fallback can throw - a missing package fails the first and
|
|
34
|
+
* would otherwise crash uncaught out of the second - so both are covered by
|
|
35
|
+
* one exit path with one diagnostic.
|
|
36
|
+
*
|
|
37
|
+
* `fromPath` is made absolute first: `createRequire` accepts only an absolute
|
|
38
|
+
* path or a file URL, and Nx expands `{projectRoot}` to a workspace-relative
|
|
39
|
+
* path, so passing it through unchanged throws ERR_INVALID_ARG_VALUE before
|
|
40
|
+
* either branch below can run.
|
|
41
|
+
*/
|
|
42
|
+
function packageRoot(fromPath: string, specifier: string): string {
|
|
43
|
+
const from = resolve(fromPath);
|
|
44
|
+
const req = createRequire(from);
|
|
45
|
+
try {
|
|
46
|
+
return dirname(req.resolve(`${specifier}/package.json`));
|
|
47
|
+
} catch {
|
|
48
|
+
// Falls through to the walk-up fallback below.
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
let dir = dirname(req.resolve(specifier));
|
|
52
|
+
while (!existsSync(join(dir, 'package.json'))) {
|
|
53
|
+
const parent = dirname(dir);
|
|
54
|
+
if (parent === dir) {
|
|
55
|
+
throw new Error('reached the filesystem root');
|
|
56
|
+
}
|
|
57
|
+
dir = parent;
|
|
58
|
+
}
|
|
59
|
+
return dir;
|
|
60
|
+
} catch {
|
|
61
|
+
log(`Cannot locate the package root of "${specifier}" from "${from}"`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function main(): void {
|
|
67
|
+
const [projectRoot, bundleDir, stageDir, addonDirList] = process.argv.slice(2);
|
|
68
|
+
if (!projectRoot || !bundleDir || !stageDir || !addonDirList) usage();
|
|
69
|
+
|
|
70
|
+
const addonDirs = addonDirList
|
|
71
|
+
.split(',')
|
|
72
|
+
.map((a) => a.trim())
|
|
73
|
+
.filter((a) => a.length > 0);
|
|
74
|
+
if (addonDirs.length === 0) usage();
|
|
75
|
+
|
|
76
|
+
if (!existsSync(bundleDir)) {
|
|
77
|
+
log(`Bundle output "${bundleDir}" does not exist - run this project's "bundle" target first.`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Started empty every run: a stale addon dir from a deliberate platform
|
|
82
|
+
// change must never survive into the next artifact, because artifact bytes
|
|
83
|
+
// must depend only on the current source and the current pin.
|
|
84
|
+
rmSync(stageDir, { recursive: true, force: true });
|
|
85
|
+
mkdirSync(stageDir, { recursive: true });
|
|
86
|
+
cpSync(bundleDir, stageDir, { recursive: true });
|
|
87
|
+
|
|
88
|
+
// Two hops: pnpm's default isolated linker does not expose a transitive
|
|
89
|
+
// dependency to the host project, so aws-crt resolves from the SDK that
|
|
90
|
+
// pins it, never from here.
|
|
91
|
+
const sdkRoot = packageRoot(join(projectRoot, 'package.json'), 'aws-iot-device-sdk-v2');
|
|
92
|
+
const crtRoot = packageRoot(join(sdkRoot, 'package.json'), 'aws-crt');
|
|
93
|
+
const binDir = join(crtRoot, 'dist', 'bin');
|
|
94
|
+
|
|
95
|
+
for (const addonDir of addonDirs) {
|
|
96
|
+
const source = join(binDir, addonDir, 'aws-crt-nodejs.node');
|
|
97
|
+
if (!existsSync(source)) {
|
|
98
|
+
const available = existsSync(binDir) ? readdirSync(binDir).join(', ') : '<missing>';
|
|
99
|
+
log(
|
|
100
|
+
`aws-crt at "${crtRoot}" ships no prebuilt addon for "${addonDir}" (looked for "${source}"). Available: ${available}`,
|
|
101
|
+
);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const dest = join(stageDir, 'native', 'aws-crt', addonDir, 'aws-crt-nodejs.node');
|
|
105
|
+
if (existsSync(dest)) {
|
|
106
|
+
log(`Refusing to overwrite "${dest}" - the bundle already writes that path.`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
110
|
+
cpSync(source, dest);
|
|
111
|
+
log(`vendored ${addonDir}/aws-crt-nodejs.node`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
main();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
|
+
import type { NormalizedComponent } from '../common.js';
|
|
7
|
+
/**
|
|
8
|
+
* Generates an AWS IoT Greengrass v2 component on an existing TypeScript
|
|
9
|
+
* project: a single-file rolldown bundle plus packaging and local-deployment
|
|
10
|
+
* targets (`<c>-artifact`, `<c>-deploy-local`, `<c>-logs`), plus, unless
|
|
11
|
+
* `--infra none`, a `GreengrassComponentVersion` CDK construct (or Terraform
|
|
12
|
+
* module, via the `hashicorp/awscc` provider) that publishes the built
|
|
13
|
+
* artifact.
|
|
14
|
+
*/
|
|
15
|
+
export declare const typescriptGreengrassComponentGenerator: (tree: Tree, component: NormalizedComponent) => Promise<GeneratorCallback>;
|
|
16
|
+
export default typescriptGreengrassComponentGenerator;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { generateFiles, joinPathFragments, logger, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { addTypeScriptBundleTarget } from "../../../utils/bundle/bundle.js";
|
|
6
|
+
import { GREENGRASS_PLATFORM_MAPPINGS, RECIPE_FORMAT_VERSION } from "../../../utils/greengrass/constants.js";
|
|
7
|
+
import { addArtifactDependencyToTargets, normalizeTargetKeyOrder } from "../../../utils/nx.js";
|
|
8
|
+
import { sortObjectKeys } from "../../../utils/object.js";
|
|
9
|
+
import { toProjectRelativePath } from "../../../utils/paths.js";
|
|
10
|
+
import { registerPnpmBuiltDependencies } from "../../../utils/pnpm-workspace.js";
|
|
11
|
+
import { sharedGreengrassScriptsGenerator } from "../../../utils/shared-greengrass-scripts.js";
|
|
12
|
+
import { assertUnchangedPlatform, finalizeComponent, GREENGRASS_SCRIPTS_DIR, sharedComponentTargets } from "../common.js";
|
|
13
|
+
import { TYPESCRIPT_DEPENDENCIES as DEPENDENCIES } from "../dependencies.js";
|
|
14
|
+
/**
|
|
15
|
+
* Generates an AWS IoT Greengrass v2 component on an existing TypeScript
|
|
16
|
+
* project: a single-file rolldown bundle plus packaging and local-deployment
|
|
17
|
+
* targets (`<c>-artifact`, `<c>-deploy-local`, `<c>-logs`), plus, unless
|
|
18
|
+
* `--infra none`, a `GreengrassComponentVersion` CDK construct (or Terraform
|
|
19
|
+
* module, via the `hashicorp/awscc` provider) that publishes the built
|
|
20
|
+
* artifact.
|
|
21
|
+
*/ export const typescriptGreengrassComponentGenerator = async (tree, component)=>{
|
|
22
|
+
const { project: projectConfig } = component;
|
|
23
|
+
const componentDirName = component.componentDirName;
|
|
24
|
+
const componentName = component.componentName;
|
|
25
|
+
const componentVersion = component.componentVersion;
|
|
26
|
+
const publisher = component.publisher;
|
|
27
|
+
const ipc = component.ipc;
|
|
28
|
+
const gdkConfig = component.gdkConfig;
|
|
29
|
+
const platforms = component.platforms;
|
|
30
|
+
// A rolldown bundle is pure JavaScript over every architecture, and with
|
|
31
|
+
// `ipc=true` one zip carries every targeted architecture's own vendored
|
|
32
|
+
// addon - each manifest's Setenv selects only its own - so, unlike the
|
|
33
|
+
// Python component, this generator has ONE artifact over N manifests, never
|
|
34
|
+
// N artifacts.
|
|
35
|
+
const manifests = platforms.map((p)=>{
|
|
36
|
+
const { manifestPlatform, nodeCrtAddonDir } = GREENGRASS_PLATFORM_MAPPINGS[p];
|
|
37
|
+
return {
|
|
38
|
+
os: manifestPlatform.os,
|
|
39
|
+
architecture: manifestPlatform.architecture,
|
|
40
|
+
artifactBaseName: componentDirName,
|
|
41
|
+
nodeCrtAddonDir
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
const componentDir = joinPathFragments(projectConfig.root, 'greengrass', componentDirName);
|
|
45
|
+
const entrypointDir = joinPathFragments(projectConfig.sourceRoot, 'greengrass', componentDirName);
|
|
46
|
+
const mainPath = joinPathFragments(entrypointDir, 'main.ts');
|
|
47
|
+
const mainPathFromProjectRoot = joinPathFragments(toProjectRelativePath(projectConfig, mainPath));
|
|
48
|
+
const gdkConfigPath = joinPathFragments(componentDir, 'gdk-config.json');
|
|
49
|
+
const manifestPreview = manifests.map((m)=>` - Platform:\n os: ${m.os}\n architecture: ${m.architecture}\n Artifacts:\n - Uri: s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/${m.artifactBaseName}.zip\n Unarchive: ZIP\n Lifecycle:\n${// The Setenv block is per-manifest and names this architecture's
|
|
50
|
+
// vendored addon, so a preview without it is not paste-ready for an
|
|
51
|
+
// ipc=true component.
|
|
52
|
+
ipc ? ` Setenv:\n AWS_CRT_NODEJS_BINARY_RELATIVE_PATH: native/aws-crt/${m.nodeCrtAddonDir}/aws-crt-nodejs.node\n` : ''} Run: node {artifacts:decompressedPath}/${m.artifactBaseName}/index.js`).join('\n');
|
|
53
|
+
assertUnchangedPlatform(component, manifestPreview);
|
|
54
|
+
const templateOptions = {
|
|
55
|
+
componentName,
|
|
56
|
+
// Named `version` / `recipeFormat`, not `componentVersion` /
|
|
57
|
+
// `recipeFormatVersion`: a `*Version` template variable is how a template
|
|
58
|
+
// names a vended dependency pin (see `VENDED_TEMPLATE_VARS` in
|
|
59
|
+
// `version-upgrade-migration/real-templates.spec.ts`), which neither a
|
|
60
|
+
// user-owned option nor a fixed protocol constant is.
|
|
61
|
+
version: componentVersion,
|
|
62
|
+
recipeFormat: RECIPE_FORMAT_VERSION,
|
|
63
|
+
componentDescription: `${componentName} Greengrass component, generated by greengrass#component.`,
|
|
64
|
+
publisher,
|
|
65
|
+
ipc,
|
|
66
|
+
manifests,
|
|
67
|
+
componentDirName,
|
|
68
|
+
project: projectConfig.name
|
|
69
|
+
};
|
|
70
|
+
// recipe.yaml is user-owned from first generation onward, so `ipc` shapes it
|
|
71
|
+
// only on the first run: a later run that flips `ipc` to true adds the vendor
|
|
72
|
+
// target and stages the addon, but leaves the recipe without the `Setenv` that
|
|
73
|
+
// points aws-crt's loader at it, and the component then fails on the device
|
|
74
|
+
// with "AWS CRT binary not present". Add that block by hand - the guide's
|
|
75
|
+
// migration note carries the exact shape.
|
|
76
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'component'), componentDir, templateOptions, {
|
|
77
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
78
|
+
});
|
|
79
|
+
// main.ts is user-owned from first generation onward. It lives under the
|
|
80
|
+
// project's own source tree (not beside recipe.yaml, unlike Python components)
|
|
81
|
+
// so it participates in the project's normal TypeScript compile/lint/test targets.
|
|
82
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'entrypoint'), entrypointDir, templateOptions, {
|
|
83
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
84
|
+
});
|
|
85
|
+
if (gdkConfig) {
|
|
86
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'gdk'), componentDir, templateOptions, {
|
|
87
|
+
overwriteStrategy: OverwriteStrategy.Overwrite
|
|
88
|
+
});
|
|
89
|
+
} else if (tree.exists(gdkConfigPath)) {
|
|
90
|
+
tree.delete(gdkConfigPath);
|
|
91
|
+
logger.info(`Removed ${gdkConfigPath}; pass --gdkConfig to keep it.`);
|
|
92
|
+
}
|
|
93
|
+
await sharedGreengrassScriptsGenerator(tree, DEPENDENCIES);
|
|
94
|
+
if (ipc) {
|
|
95
|
+
// aws-crt ships an install script that builds its native addon from
|
|
96
|
+
// source. Recorded as `false`: this component vendors the prebuilt addon at
|
|
97
|
+
// build time, so the script must not run - and pnpm 11 fails the install
|
|
98
|
+
// outright with ERR_PNPM_IGNORED_BUILDS unless the decision is explicit.
|
|
99
|
+
registerPnpmBuiltDependencies(tree, {
|
|
100
|
+
'aws-crt': false
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (ipc) {
|
|
104
|
+
// AFTER sharedGreengrassScriptsGenerator, never before: in a workspace with
|
|
105
|
+
// no shared scripts project yet, that generator creates one and deletes the
|
|
106
|
+
// whole `src` tree it scaffolded, which would take this script with it and
|
|
107
|
+
// leave the `-vendor` target invoking a file that does not exist.
|
|
108
|
+
//
|
|
109
|
+
// Vended here rather than by that generator, and only when ipc is true,
|
|
110
|
+
// because it vends its whole directory into every workspace - putting this
|
|
111
|
+
// script there would change what an ipc=false run produces. KeepExisting
|
|
112
|
+
// like every other vended script, so a user's patches survive.
|
|
113
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'scripts'), GREENGRASS_SCRIPTS_DIR, templateOptions, {
|
|
114
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const bundleOutputDir = joinPathFragments('greengrass', componentDirName);
|
|
118
|
+
await addTypeScriptBundleTarget(tree, projectConfig, {
|
|
119
|
+
targetFilePath: mainPathFromProjectRoot,
|
|
120
|
+
bundleOutputDir,
|
|
121
|
+
platform: 'node'
|
|
122
|
+
}, DEPENDENCIES);
|
|
123
|
+
const artifactTarget = `${componentDirName}-artifact`;
|
|
124
|
+
const vendorTarget = `${componentDirName}-vendor`;
|
|
125
|
+
const distDir = `dist/{projectRoot}/greengrass/${componentDirName}`;
|
|
126
|
+
const bundleDir = `dist/{projectRoot}/bundle/${bundleOutputDir}`;
|
|
127
|
+
// Named `stage`, not `vendor`, so it cannot be confused with the
|
|
128
|
+
// `<dist>/vendor` path build-artifact.ts reads in Python (non-bundle) mode.
|
|
129
|
+
const stageDir = `${distDir}/stage`;
|
|
130
|
+
projectConfig.targets ??= {};
|
|
131
|
+
if (ipc) {
|
|
132
|
+
projectConfig.targets[vendorTarget] = normalizeTargetKeyOrder({
|
|
133
|
+
cache: true,
|
|
134
|
+
inputs: [
|
|
135
|
+
'production',
|
|
136
|
+
'^production',
|
|
137
|
+
`{workspaceRoot}/${GREENGRASS_SCRIPTS_DIR}/**/*`,
|
|
138
|
+
// The addon bytes come from the installed aws-crt, not from any file
|
|
139
|
+
// in this project, so without this the target would serve the
|
|
140
|
+
// previous SDK's addon from cache after a version bump.
|
|
141
|
+
{
|
|
142
|
+
externalDependencies: [
|
|
143
|
+
'aws-iot-device-sdk-v2'
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
outputs: [
|
|
148
|
+
`{workspaceRoot}/${stageDir}`
|
|
149
|
+
],
|
|
150
|
+
executor: 'nx:run-commands',
|
|
151
|
+
dependsOn: [
|
|
152
|
+
'bundle'
|
|
153
|
+
],
|
|
154
|
+
options: {
|
|
155
|
+
command: `tsx ${GREENGRASS_SCRIPTS_DIR}/vendor-crt-addon.ts {projectRoot} ${bundleDir} ${stageDir} ${manifests.map((m)=>m.nodeCrtAddonDir).join(',')}`
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
projectConfig.targets[artifactTarget] = normalizeTargetKeyOrder({
|
|
160
|
+
cache: true,
|
|
161
|
+
// The vended scripts live outside this project, so the cache key must
|
|
162
|
+
// name them explicitly or a refreshed script serves a stale artifact.
|
|
163
|
+
inputs: [
|
|
164
|
+
'production',
|
|
165
|
+
'^production',
|
|
166
|
+
`{workspaceRoot}/${GREENGRASS_SCRIPTS_DIR}/**/*`
|
|
167
|
+
],
|
|
168
|
+
outputs: [
|
|
169
|
+
`{workspaceRoot}/${distDir}/greengrass-build`
|
|
170
|
+
],
|
|
171
|
+
executor: 'nx:run-commands',
|
|
172
|
+
dependsOn: [
|
|
173
|
+
ipc ? vendorTarget : 'bundle'
|
|
174
|
+
],
|
|
175
|
+
options: {
|
|
176
|
+
command: `tsx ${GREENGRASS_SCRIPTS_DIR}/build-artifact.ts {projectRoot} ${componentDirName} ${distDir} ${ipc ? stageDir : bundleDir}`
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
addArtifactDependencyToTargets(projectConfig, artifactTarget);
|
|
180
|
+
Object.assign(projectConfig.targets, sharedComponentTargets({
|
|
181
|
+
artifactTarget,
|
|
182
|
+
componentDirName,
|
|
183
|
+
componentName,
|
|
184
|
+
distDir
|
|
185
|
+
}));
|
|
186
|
+
// py#project and ts#project sort targets on every run, including re-runs,
|
|
187
|
+
// so append in the same order or a later project re-run reorders the file.
|
|
188
|
+
projectConfig.targets = sortObjectKeys(projectConfig.targets);
|
|
189
|
+
updateProjectConfiguration(tree, projectConfig.name, projectConfig);
|
|
190
|
+
return finalizeComponent(tree, component, mainPathFromProjectRoot, DEPENDENCIES);
|
|
191
|
+
};
|
|
192
|
+
export default typescriptGreengrassComponentGenerator;
|
|
193
|
+
|
|
194
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/greengrass/component/typescript/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n logger,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTypeScriptBundleTarget } from '../../../utils/bundle/bundle.js';\nimport {\n GREENGRASS_PLATFORM_MAPPINGS,\n RECIPE_FORMAT_VERSION,\n} from '../../../utils/greengrass/constants.js';\nimport {\n addArtifactDependencyToTargets,\n normalizeTargetKeyOrder,\n} from '../../../utils/nx.js';\nimport { sortObjectKeys } from '../../../utils/object.js';\nimport { toProjectRelativePath } from '../../../utils/paths.js';\nimport { registerPnpmBuiltDependencies } from '../../../utils/pnpm-workspace.js';\nimport { sharedGreengrassScriptsGenerator } from '../../../utils/shared-greengrass-scripts.js';\nimport type { NormalizedComponent } from '../common.js';\nimport {\n assertUnchangedPlatform,\n finalizeComponent,\n GREENGRASS_SCRIPTS_DIR,\n sharedComponentTargets,\n} from '../common.js';\nimport { TYPESCRIPT_DEPENDENCIES as DEPENDENCIES } from '../dependencies.js';\n\n/**\n * Generates an AWS IoT Greengrass v2 component on an existing TypeScript\n * project: a single-file rolldown bundle plus packaging and local-deployment\n * targets (`<c>-artifact`, `<c>-deploy-local`, `<c>-logs`), plus, unless\n * `--infra none`, a `GreengrassComponentVersion` CDK construct (or Terraform\n * module, via the `hashicorp/awscc` provider) that publishes the built\n * artifact.\n */\nexport const typescriptGreengrassComponentGenerator = async (\n tree: Tree,\n component: NormalizedComponent,\n): Promise<GeneratorCallback> => {\n const { project: projectConfig } = component;\n\n const componentDirName = component.componentDirName;\n const componentName = component.componentName;\n const componentVersion = component.componentVersion;\n const publisher = component.publisher;\n const ipc = component.ipc;\n const gdkConfig = component.gdkConfig;\n const platforms = component.platforms;\n // A rolldown bundle is pure JavaScript over every architecture, and with\n // `ipc=true` one zip carries every targeted architecture's own vendored\n // addon - each manifest's Setenv selects only its own - so, unlike the\n // Python component, this generator has ONE artifact over N manifests, never\n // N artifacts.\n const manifests = platforms.map((p) => {\n const { manifestPlatform, nodeCrtAddonDir } =\n GREENGRASS_PLATFORM_MAPPINGS[p];\n return {\n os: manifestPlatform.os,\n architecture: manifestPlatform.architecture,\n artifactBaseName: componentDirName,\n nodeCrtAddonDir,\n };\n });\n\n const componentDir = joinPathFragments(\n projectConfig.root,\n 'greengrass',\n componentDirName,\n );\n const entrypointDir = joinPathFragments(\n projectConfig.sourceRoot!,\n 'greengrass',\n componentDirName,\n );\n const mainPath = joinPathFragments(entrypointDir, 'main.ts');\n const mainPathFromProjectRoot = joinPathFragments(\n toProjectRelativePath(projectConfig, mainPath),\n );\n const gdkConfigPath = joinPathFragments(componentDir, 'gdk-config.json');\n\n const manifestPreview = manifests\n .map(\n (m) =>\n ` - Platform:\\n os: ${m.os}\\n architecture: ${m.architecture}\\n Artifacts:\\n - Uri: s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/${m.artifactBaseName}.zip\\n Unarchive: ZIP\\n Lifecycle:\\n${\n // The Setenv block is per-manifest and names this architecture's\n // vendored addon, so a preview without it is not paste-ready for an\n // ipc=true component.\n ipc\n ? ` Setenv:\\n AWS_CRT_NODEJS_BINARY_RELATIVE_PATH: native/aws-crt/${m.nodeCrtAddonDir}/aws-crt-nodejs.node\\n`\n : ''\n } Run: node {artifacts:decompressedPath}/${m.artifactBaseName}/index.js`,\n )\n .join('\\n');\n assertUnchangedPlatform(component, manifestPreview);\n\n const templateOptions = {\n componentName,\n // Named `version` / `recipeFormat`, not `componentVersion` /\n // `recipeFormatVersion`: a `*Version` template variable is how a template\n // names a vended dependency pin (see `VENDED_TEMPLATE_VARS` in\n // `version-upgrade-migration/real-templates.spec.ts`), which neither a\n // user-owned option nor a fixed protocol constant is.\n version: componentVersion,\n recipeFormat: RECIPE_FORMAT_VERSION,\n componentDescription: `${componentName} Greengrass component, generated by greengrass#component.`,\n publisher,\n ipc,\n manifests,\n componentDirName,\n project: projectConfig.name,\n };\n\n // recipe.yaml is user-owned from first generation onward, so `ipc` shapes it\n // only on the first run: a later run that flips `ipc` to true adds the vendor\n // target and stages the addon, but leaves the recipe without the `Setenv` that\n // points aws-crt's loader at it, and the component then fails on the device\n // with \"AWS CRT binary not present\". Add that block by hand - the guide's\n // migration note carries the exact shape.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'component'),\n componentDir,\n templateOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // main.ts is user-owned from first generation onward. It lives under the\n // project's own source tree (not beside recipe.yaml, unlike Python components)\n // so it participates in the project's normal TypeScript compile/lint/test targets.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'entrypoint'),\n entrypointDir,\n templateOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (gdkConfig) {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'gdk'),\n componentDir,\n templateOptions,\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n } else if (tree.exists(gdkConfigPath)) {\n tree.delete(gdkConfigPath);\n logger.info(`Removed ${gdkConfigPath}; pass --gdkConfig to keep it.`);\n }\n\n await sharedGreengrassScriptsGenerator(tree, DEPENDENCIES);\n\n if (ipc) {\n // aws-crt ships an install script that builds its native addon from\n // source. Recorded as `false`: this component vendors the prebuilt addon at\n // build time, so the script must not run - and pnpm 11 fails the install\n // outright with ERR_PNPM_IGNORED_BUILDS unless the decision is explicit.\n registerPnpmBuiltDependencies(tree, { 'aws-crt': false });\n }\n\n if (ipc) {\n // AFTER sharedGreengrassScriptsGenerator, never before: in a workspace with\n // no shared scripts project yet, that generator creates one and deletes the\n // whole `src` tree it scaffolded, which would take this script with it and\n // leave the `-vendor` target invoking a file that does not exist.\n //\n // Vended here rather than by that generator, and only when ipc is true,\n // because it vends its whole directory into every workspace - putting this\n // script there would change what an ipc=false run produces. KeepExisting\n // like every other vended script, so a user's patches survive.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'scripts'),\n GREENGRASS_SCRIPTS_DIR,\n templateOptions,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n const bundleOutputDir = joinPathFragments('greengrass', componentDirName);\n await addTypeScriptBundleTarget(\n tree,\n projectConfig,\n {\n targetFilePath: mainPathFromProjectRoot,\n bundleOutputDir,\n platform: 'node',\n },\n DEPENDENCIES,\n );\n\n const artifactTarget = `${componentDirName}-artifact`;\n const vendorTarget = `${componentDirName}-vendor`;\n const distDir = `dist/{projectRoot}/greengrass/${componentDirName}`;\n const bundleDir = `dist/{projectRoot}/bundle/${bundleOutputDir}`;\n // Named `stage`, not `vendor`, so it cannot be confused with the\n // `<dist>/vendor` path build-artifact.ts reads in Python (non-bundle) mode.\n const stageDir = `${distDir}/stage`;\n\n projectConfig.targets ??= {};\n\n if (ipc) {\n projectConfig.targets[vendorTarget] = normalizeTargetKeyOrder({\n cache: true,\n inputs: [\n 'production',\n '^production',\n `{workspaceRoot}/${GREENGRASS_SCRIPTS_DIR}/**/*`,\n // The addon bytes come from the installed aws-crt, not from any file\n // in this project, so without this the target would serve the\n // previous SDK's addon from cache after a version bump.\n { externalDependencies: ['aws-iot-device-sdk-v2'] },\n ],\n outputs: [`{workspaceRoot}/${stageDir}`],\n executor: 'nx:run-commands',\n dependsOn: ['bundle'],\n options: {\n command: `tsx ${GREENGRASS_SCRIPTS_DIR}/vendor-crt-addon.ts {projectRoot} ${bundleDir} ${stageDir} ${manifests\n .map((m) => m.nodeCrtAddonDir)\n .join(',')}`,\n },\n });\n }\n\n projectConfig.targets[artifactTarget] = normalizeTargetKeyOrder({\n cache: true,\n // The vended scripts live outside this project, so the cache key must\n // name them explicitly or a refreshed script serves a stale artifact.\n inputs: [\n 'production',\n '^production',\n `{workspaceRoot}/${GREENGRASS_SCRIPTS_DIR}/**/*`,\n ],\n outputs: [`{workspaceRoot}/${distDir}/greengrass-build`],\n executor: 'nx:run-commands',\n dependsOn: [ipc ? vendorTarget : 'bundle'],\n options: {\n command: `tsx ${GREENGRASS_SCRIPTS_DIR}/build-artifact.ts {projectRoot} ${componentDirName} ${distDir} ${ipc ? stageDir : bundleDir}`,\n },\n });\n addArtifactDependencyToTargets(projectConfig, artifactTarget);\n\n Object.assign(\n projectConfig.targets,\n sharedComponentTargets({\n artifactTarget,\n componentDirName,\n componentName,\n distDir,\n }),\n );\n\n // py#project and ts#project sort targets on every run, including re-runs,\n // so append in the same order or a later project re-run reorders the file.\n projectConfig.targets = sortObjectKeys(projectConfig.targets);\n updateProjectConfiguration(tree, projectConfig.name, projectConfig);\n\n return finalizeComponent(\n tree,\n component,\n mainPathFromProjectRoot,\n DEPENDENCIES,\n );\n};\n\nexport default typescriptGreengrassComponentGenerator;\n"],"names":["generateFiles","joinPathFragments","logger","OverwriteStrategy","updateProjectConfiguration","addTypeScriptBundleTarget","GREENGRASS_PLATFORM_MAPPINGS","RECIPE_FORMAT_VERSION","addArtifactDependencyToTargets","normalizeTargetKeyOrder","sortObjectKeys","toProjectRelativePath","registerPnpmBuiltDependencies","sharedGreengrassScriptsGenerator","assertUnchangedPlatform","finalizeComponent","GREENGRASS_SCRIPTS_DIR","sharedComponentTargets","TYPESCRIPT_DEPENDENCIES","DEPENDENCIES","typescriptGreengrassComponentGenerator","tree","component","project","projectConfig","componentDirName","componentName","componentVersion","publisher","ipc","gdkConfig","platforms","manifests","map","p","manifestPlatform","nodeCrtAddonDir","os","architecture","artifactBaseName","componentDir","root","entrypointDir","sourceRoot","mainPath","mainPathFromProjectRoot","gdkConfigPath","manifestPreview","m","join","templateOptions","version","recipeFormat","componentDescription","name","dirname","overwriteStrategy","KeepExisting","Overwrite","exists","delete","info","bundleOutputDir","targetFilePath","platform","artifactTarget","vendorTarget","distDir","bundleDir","stageDir","targets","cache","inputs","externalDependencies","outputs","executor","dependsOn","options","command","Object","assign"],"mappings":"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"}
|
|
@@ -47,7 +47,7 @@ export declare const DEPENDENCIES: import("../../utils/declared-dependencies.js"
|
|
|
47
47
|
readonly when: (m: import("../../utils/shared-constructs-constants.js").IacMetadata) => boolean;
|
|
48
48
|
} & {
|
|
49
49
|
versionOnly: true;
|
|
50
|
-
}], readonly import("../../utils/declared-dependencies.js").DeclaredPyDependency<"ruff" | "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" | "pydantic" | "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.js").DeclaredPyDependency<"ruff" | "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" | "awsiotsdk" | "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" | "pydantic" | "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.js").D
|
|
|
17
17
|
readonly name: "typescript";
|
|
18
18
|
}, {
|
|
19
19
|
readonly name: "@biomejs/biome";
|
|
20
|
-
}], readonly import("../utils/declared-dependencies.js").DeclaredPyDependency<"ruff" | "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" | "pydantic" | "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.js").DeclaredPyDependency<"ruff" | "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" | "awsiotsdk" | "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" | "pydantic" | "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.
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/ import { agentcoreGatewayGenerator } from "../../sdk/agentcore-gateway.js";
|
|
5
5
|
import { agentcoreHarnessGenerator } from "../../sdk/agentcore-harness.js";
|
|
6
6
|
import { connectionGenerator } from "../../sdk/connection.js";
|
|
7
|
+
import { greengrassComponentGenerator } from "../../sdk/greengrass.js";
|
|
7
8
|
import { licenseGenerator } from "../../sdk/license.js";
|
|
8
9
|
import { pyAgentGenerator, pyApiGenerator, pyDynamoDBGenerator, pyLambdaFunctionGenerator, pyMcpServerGenerator, pyProjectGenerator, pyRdbGenerator } from "../../sdk/py.js";
|
|
9
10
|
import { smithyProjectGenerator } from "../../sdk/smithy.js";
|
|
@@ -216,6 +217,47 @@ import { getNpmScope, getNpmScopePrefix } from "../../utils/npm-scope.js";
|
|
|
216
217
|
iac: 'inherit',
|
|
217
218
|
...defaults
|
|
218
219
|
});
|
|
220
|
+
// Greengrass: the `AWS::GreengrassV2` resources exist in the
|
|
221
|
+
// `hashicorp/awscc` Terraform provider (this workspace pins it), so both
|
|
222
|
+
// `--iac cdk` and `--iac terraform` are exercised here via `iac: 'inherit'`.
|
|
223
|
+
//
|
|
224
|
+
// A component with publication infrastructure and an app wrapper in the
|
|
225
|
+
// workspace's infrastructure project. Hosted on a dedicated project:
|
|
226
|
+
// vendoring's `--only-binary :all:` refuses the source-built workspace
|
|
227
|
+
// members other entries add to py-project, and one component per project is
|
|
228
|
+
// the documented production default.
|
|
229
|
+
await pyProjectGenerator(tree, {
|
|
230
|
+
name: 'py-greengrass-project',
|
|
231
|
+
type: 'application',
|
|
232
|
+
...projectDefaults
|
|
233
|
+
});
|
|
234
|
+
await greengrassComponentGenerator(tree, {
|
|
235
|
+
project: py('py-greengrass-project'),
|
|
236
|
+
name: 'my-greengrass-component',
|
|
237
|
+
language: 'python',
|
|
238
|
+
platform: 'linux-amd64-arm64',
|
|
239
|
+
gdkConfig: true,
|
|
240
|
+
iac: 'inherit',
|
|
241
|
+
...defaults
|
|
242
|
+
});
|
|
243
|
+
// The TypeScript component gets a dedicated host project for the same
|
|
244
|
+
// reason: the shared `bundle` target this generator wires rebuilds every
|
|
245
|
+
// bundled entrypoint in its project together, so hosting it alongside
|
|
246
|
+
// `ts-project`'s Lambda function would couple this device-oriented
|
|
247
|
+
// bundle's cache invalidation to an unrelated Lambda bundle's.
|
|
248
|
+
await tsProjectGenerator(tree, {
|
|
249
|
+
name: 'ts-greengrass-project',
|
|
250
|
+
...projectDefaults
|
|
251
|
+
});
|
|
252
|
+
await greengrassComponentGenerator(tree, {
|
|
253
|
+
project: 'ts-greengrass-project',
|
|
254
|
+
name: 'my-ts-greengrass-component',
|
|
255
|
+
language: 'typescript',
|
|
256
|
+
ipc: true,
|
|
257
|
+
componentVersion: '1.0.0',
|
|
258
|
+
iac: 'inherit',
|
|
259
|
+
...defaults
|
|
260
|
+
});
|
|
219
261
|
// MCP servers — uninfra'd and hosted on AgentCore.
|
|
220
262
|
await pyMcpServerGenerator(tree, {
|
|
221
263
|
project: 'py_project',
|