@aws/nx-plugin 1.0.0-rc.13 → 1.0.0-rc.14

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 (82) hide show
  1. package/generators.json +28 -1
  2. package/package.json +1 -1
  3. package/src/connection/generator.d.ts +1 -1
  4. package/src/connection/generator.js +58 -42
  5. package/src/connection/generator.js.map +1 -1
  6. package/src/infra/app/__snapshots__/generator.spec.ts.snap +7 -7
  7. package/src/infra/app/generator.js +4 -4
  8. package/src/infra/app/generator.js.map +1 -1
  9. package/src/preset/__snapshots__/generator.spec.ts.snap +3 -1
  10. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +1486 -0
  11. package/src/py/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
  12. package/src/py/dynamodb/agent-connection/generator.d.ts +10 -0
  13. package/src/py/dynamodb/agent-connection/generator.js +39 -0
  14. package/src/py/dynamodb/agent-connection/generator.js.map +1 -0
  15. package/src/py/dynamodb/agent-connection/schema.d.ts +14 -0
  16. package/src/py/dynamodb/agent-connection/schema.json +22 -0
  17. package/src/py/dynamodb/fast-api-connection/__snapshots__/generator.spec.ts.snap +23 -0
  18. package/src/py/dynamodb/fast-api-connection/generator.d.ts +10 -0
  19. package/src/py/dynamodb/fast-api-connection/generator.js +37 -0
  20. package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -0
  21. package/src/py/dynamodb/fast-api-connection/schema.d.ts +12 -0
  22. package/src/py/dynamodb/fast-api-connection/schema.json +18 -0
  23. package/src/py/dynamodb/files/__name__/__init__.py.template +6 -0
  24. package/src/py/dynamodb/files/__name__/client.py.template +39 -0
  25. package/src/py/dynamodb/files/__name__/entities/__init__.py.template +4 -0
  26. package/src/py/dynamodb/files/__name__/entities/base.py.template +63 -0
  27. package/src/py/dynamodb/files/__name__/entities/example.py.template +64 -0
  28. package/src/py/dynamodb/files/config.json.template +24 -0
  29. package/src/py/dynamodb/generator.d.ts +10 -0
  30. package/src/py/dynamodb/generator.js +106 -0
  31. package/src/py/dynamodb/generator.js.map +1 -0
  32. package/src/py/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
  33. package/src/py/dynamodb/mcp-server-connection/generator.d.ts +10 -0
  34. package/src/py/dynamodb/mcp-server-connection/generator.js +39 -0
  35. package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -0
  36. package/src/py/dynamodb/mcp-server-connection/schema.d.ts +14 -0
  37. package/src/py/dynamodb/mcp-server-connection/schema.json +22 -0
  38. package/src/py/dynamodb/schema.d.ts +15 -0
  39. package/src/py/dynamodb/schema.json +70 -0
  40. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +303 -512
  41. package/src/ts/dynamodb/files/config.json.template +24 -0
  42. package/src/ts/dynamodb/files/src/client.ts.template +26 -10
  43. package/src/ts/dynamodb/files/src/index.ts.template +0 -8
  44. package/src/ts/dynamodb/generator.js +15 -12
  45. package/src/ts/dynamodb/generator.js.map +1 -1
  46. package/src/ts/dynamodb/schema.d.ts +1 -0
  47. package/src/ts/dynamodb/schema.json +20 -2
  48. package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +0 -1
  49. package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
  50. package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +12 -13
  51. package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +3 -3
  52. package/src/{ts/dynamodb/files/scripts → utils/files/common/scripts/src/dynamodb}/create-local-table.ts.template +63 -36
  53. package/src/utils/files/common/scripts/src/dynamodb/pull-image.ts.template +13 -0
  54. package/src/{ts/dynamodb/files/scripts → utils/files/common/scripts/src/dynamodb}/start-container.ts.template +28 -18
  55. package/src/utils/port.d.ts +6 -5
  56. package/src/utils/port.js +7 -5
  57. package/src/utils/port.js.map +1 -1
  58. package/src/utils/shared-constructs-constants.d.ts +1 -0
  59. package/src/utils/shared-constructs-constants.js +2 -1
  60. package/src/utils/shared-constructs-constants.js.map +1 -1
  61. package/src/utils/shared-dynamodb-scripts.d.ts +11 -0
  62. package/src/utils/shared-dynamodb-scripts.js +23 -0
  63. package/src/utils/shared-dynamodb-scripts.js.map +1 -0
  64. package/src/utils/shared-infra-scripts.d.ts +11 -0
  65. package/src/utils/shared-infra-scripts.js +35 -0
  66. package/src/utils/shared-infra-scripts.js.map +1 -0
  67. package/src/utils/shared-scripts.d.ts +1 -4
  68. package/src/utils/shared-scripts.js +2 -23
  69. package/src/utils/shared-scripts.js.map +1 -1
  70. package/src/utils/versions.d.ts +1 -0
  71. package/src/utils/versions.js +1 -0
  72. package/src/utils/versions.js.map +1 -1
  73. package/src/ts/dynamodb/files/dynamodb.config.json +0 -14
  74. package/src/ts/dynamodb/files/scripts/pull-image.ts.template +0 -15
  75. package/src/ts/dynamodb/files/src/constants.ts.template +0 -9
  76. /package/src/utils/files/common/scripts/src/{index.ts.template → infra/index.ts.template} +0 -0
  77. /package/src/utils/files/common/scripts/src/{infra-deploy.ts.template → infra/infra-deploy.ts.template} +0 -0
  78. /package/src/utils/files/common/scripts/src/{infra-destroy.ts.template → infra/infra-destroy.ts.template} +0 -0
  79. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/cdk-command.ts.template +0 -0
  80. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/credentials.ts.template +0 -0
  81. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/run.ts.template +0 -0
  82. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/stage-parser.ts.template +0 -0
@@ -0,0 +1,24 @@
1
+ {
2
+ "runtimeConfigKey": "<%= runtimeConfigKey %>",
3
+ "serveLocal": {
4
+ "port": <%= localDynamoDBPort %>,
5
+ "tableName": "<%= localTableName %>",
6
+ "image": "public.ecr.aws/aws-dynamodb-local/aws-dynamodb-local:latest",
7
+ "containerName": "<%= containerName %>",
8
+ "containerEngine": "<%= containerEngine %>"
9
+ },
10
+ "tableConfig": {
11
+ "globalSecondaryIndexes": [
12
+ {
13
+ "indexName": "gsi1pk-gsi1sk-index",
14
+ "partitionKey": "gsi1pk",
15
+ "sortKey": "gsi1sk"
16
+ },
17
+ {
18
+ "indexName": "gsi2pk-gsi2sk-index",
19
+ "partitionKey": "gsi2pk",
20
+ "sortKey": "gsi2sk"
21
+ }
22
+ ]
23
+ }
24
+ }
@@ -1,17 +1,32 @@
1
1
  import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
2
2
  import { getAppConfig } from '@aws-lambda-powertools/parameters/appconfig';
3
- import { PACKAGE_NAME, LOCAL_ACCESS_KEY_ID, LOCAL_ENDPOINT, LOCAL_REGION, LOCAL_SECRET_ACCESS_KEY, LOCAL_TABLE_NAME } from './constants.js';
3
+ import { readFileSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ // Generated: must match runtimeConfigKey in config.json
8
+ const runtimeConfigKey = '<%= runtimeConfigKey %>';
9
+
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ // config.json is only present in local dev (not included in the deployed bundle); guard with SERVE_LOCAL check
12
+ const serveLocal = () =>
13
+ JSON.parse(readFileSync(join(__dirname, '../config.json'), 'utf-8')).serveLocal;
4
14
 
5
15
  let _client: DynamoDBClient | undefined;
6
16
 
7
17
  export const getDynamoDBClient = (): DynamoDBClient => {
8
- _client ??= process.env.SERVE_LOCAL === 'true'
9
- ? new DynamoDBClient({
10
- endpoint: LOCAL_ENDPOINT,
11
- region: LOCAL_REGION,
12
- credentials: { accessKeyId: LOCAL_ACCESS_KEY_ID, secretAccessKey: LOCAL_SECRET_ACCESS_KEY },
13
- })
14
- : new DynamoDBClient({});
18
+ if (!_client) {
19
+ if (process.env.SERVE_LOCAL === 'true') {
20
+ const { port } = serveLocal();
21
+ _client = new DynamoDBClient({
22
+ endpoint: `http://localhost:${port}`,
23
+ region: 'us-east-1',
24
+ credentials: { accessKeyId: 'UNUSED', secretAccessKey: 'UNUSED' },
25
+ });
26
+ } else {
27
+ _client = new DynamoDBClient({});
28
+ }
29
+ }
15
30
  return _client;
16
31
  };
17
32
 
@@ -23,7 +38,8 @@ let _tableName: string | undefined;
23
38
 
24
39
  export const resolveTableName = async (): Promise<string> => {
25
40
  if (process.env.SERVE_LOCAL === 'true') {
26
- return LOCAL_TABLE_NAME;
41
+ const { tableName } = serveLocal();
42
+ return tableName;
27
43
  }
28
44
  if (_tableName === undefined) {
29
45
  const appId = process.env.RUNTIME_CONFIG_APP_ID;
@@ -35,7 +51,7 @@ export const resolveTableName = async (): Promise<string> => {
35
51
  environment: 'default',
36
52
  transform: 'json',
37
53
  });
38
- const tableName = config?.[PACKAGE_NAME]?.tableName;
54
+ const tableName = config?.[runtimeConfigKey]?.tableName;
39
55
  if (!tableName) {
40
56
  throw new Error('Could not resolve table name from runtime config');
41
57
  }
@@ -1,10 +1,2 @@
1
- export {
2
- PACKAGE_NAME,
3
- LOCAL_ACCESS_KEY_ID,
4
- LOCAL_ENDPOINT,
5
- LOCAL_REGION,
6
- LOCAL_SECRET_ACCESS_KEY,
7
- LOCAL_TABLE_NAME,
8
- } from './constants.js';
9
1
  export { getDynamoDBClient, resolveTableName } from './client.js';
10
2
  export * from './entities/index.js';
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.tsDynamoDBGenerator = exports.TS_DYNAMODB_GENERATOR_INFO = void 0;
4
- const tslib_1 = require("tslib");
5
2
  /**
6
3
  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
7
4
  * SPDX-License-Identifier: Apache-2.0
8
5
  */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.tsDynamoDBGenerator = exports.TS_DYNAMODB_GENERATOR_INFO = void 0;
8
+ const tslib_1 = require("tslib");
9
+ const node_path_1 = require("node:path");
9
10
  const devkit_1 = require("@nx/devkit");
10
11
  const containers_1 = require("../../utils/containers");
11
12
  const dynamodb_constructs_1 = require("../../utils/dynamodb-constructs/dynamodb-constructs");
@@ -17,10 +18,11 @@ const npm_scope_1 = require("../../utils/npm-scope");
17
18
  const nx_1 = require("../../utils/nx");
18
19
  const port_1 = require("../../utils/port");
19
20
  const shared_constructs_1 = require("../../utils/shared-constructs");
21
+ const shared_constructs_constants_1 = require("../../utils/shared-constructs-constants");
22
+ const shared_dynamodb_scripts_1 = require("../../utils/shared-dynamodb-scripts");
20
23
  const versions_1 = require("../../utils/versions");
21
24
  const generator_1 = tslib_1.__importStar(require("../lib/generator"));
22
25
  exports.TS_DYNAMODB_GENERATOR_INFO = (0, nx_1.getGeneratorInfo)(__filename);
23
- const DYNAMODB_LOCAL_IMAGE = 'public.ecr.aws/aws-dynamodb-local/aws-dynamodb-local:latest';
24
26
  const tsDynamoDBGenerator = async (tree, options) => {
25
27
  const nameKebabCase = (0, names_1.kebabCase)(options.name);
26
28
  const nameClassName = (0, names_1.toClassName)(options.name);
@@ -46,20 +48,22 @@ const tsDynamoDBGenerator = async (tree, options) => {
46
48
  });
47
49
  }
48
50
  const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, fullyQualifiedName);
49
- const localDynamoPort = (0, port_1.assignSharedPort)(tree, projectConfig, exports.TS_DYNAMODB_GENERATOR_INFO.id, 8000);
51
+ const localDynamoDBPort = (0, port_1.assignSharedPort)(tree, projectConfig, shared_constructs_constants_1.DYNAMODB_GENERATOR_IDS, 8000);
52
+ const containerName = `${(0, npm_scope_1.getNpmScope)(tree)}-dynamodb`;
50
53
  const templateOptions = {
51
54
  runtimeConfigKey: nameClassName,
52
- dynamoPackageAlias: (0, npm_scope_1.toScopeAlias)(fullyQualifiedName),
53
- localDynamoPort,
55
+ localDynamoDBPort,
54
56
  localTableName,
57
+ containerName,
55
58
  containerEngine,
56
59
  };
57
60
  (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files'), dir, templateOptions);
58
- const containerName = `${(0, npm_scope_1.getNpmScope)(tree)}-dynamodb`;
61
+ await (0, shared_dynamodb_scripts_1.sharedDynamoDBScriptsGenerator)(tree);
62
+ const scriptsDir = (0, node_path_1.relative)(dir, (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_SCRIPTS_DIR, 'src', 'dynamodb'));
59
63
  projectConfig.targets['pull-image'] = {
60
64
  executor: 'nx:run-commands',
61
65
  options: {
62
- command: `tsx scripts/pull-image.ts ${DYNAMODB_LOCAL_IMAGE}`,
66
+ command: `tsx ${scriptsDir}/pull-image.ts`,
63
67
  cwd: '{projectRoot}',
64
68
  },
65
69
  };
@@ -69,8 +73,8 @@ const tsDynamoDBGenerator = async (tree, options) => {
69
73
  dependsOn: ['pull-image'],
70
74
  options: {
71
75
  commands: [
72
- `tsx scripts/start-container.ts ${containerName} ${DYNAMODB_LOCAL_IMAGE} ${localDynamoPort}`,
73
- `tsx scripts/create-local-table.ts ${localTableName} ${localDynamoPort}`,
76
+ `tsx ${scriptsDir}/start-container.ts`,
77
+ `tsx ${scriptsDir}/create-local-table.ts`,
74
78
  ],
75
79
  parallel: true,
76
80
  cwd: '{projectRoot}',
@@ -86,7 +90,6 @@ const tsDynamoDBGenerator = async (tree, options) => {
86
90
  projectName: fullyQualifiedName,
87
91
  nameClassName,
88
92
  nameKebabCase,
89
- dynamoPackageAlias: (0, npm_scope_1.toScopeAlias)(fullyQualifiedName),
90
93
  tableName: localTableName,
91
94
  projectRoot: dir,
92
95
  });
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/ts/dynamodb/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,uCASoB;AACpB,uDAA2D;AAC3D,6FAAuF;AACvF,+CAA0D;AAC1D,yCAA6C;AAC7C,iDAAsE;AACtE,6CAA2D;AAC3D,qDAAkE;AAClE,uCAIwB;AACxB,2CAAoD;AACpD,qEAA0E;AAC1E,mDAAoD;AACpD,sEAAuE;AAG1D,QAAA,0BAA0B,GACrC,IAAA,qBAAgB,EAAC,UAAU,CAAC,CAAC;AAE/B,MAAM,oBAAoB,GACxB,6DAA6D,CAAC;AAEzD,MAAM,mBAAmB,GAAG,KAAK,EACtC,IAAU,EACV,OAAkC,EACN,EAAE;IAC9B,MAAM,aAAa,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,IAAA,mBAAW,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,IAAI,IAAA,iBAAS,EAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9F,MAAM,eAAe,GAAG,MAAM,IAAA,8BAAiB,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjE,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,IAAA,2BAAe,EAAC,IAAI,EAAE;QACxD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IAEH,IAAI,aAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,IAAA,iCAAwB,EAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;QACnD,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAA,mBAAkB,EAAC,IAAI,EAAE;YAC7B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,aAAa,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAEzE,MAAM,eAAe,GAAG,IAAA,uBAAgB,EACtC,IAAI,EACJ,aAAa,EACb,kCAA0B,CAAC,EAAE,EAC7B,IAAI,CACL,CAAC;IAEF,MAAM,eAAe,GAAG;QACtB,gBAAgB,EAAE,aAAa;QAC/B,kBAAkB,EAAE,IAAA,wBAAY,EAAC,kBAAkB,CAAC;QACpD,eAAe;QACf,cAAc;QACd,eAAe;KAChB,CAAC;IAEF,IAAA,sBAAa,EACX,IAAI,EACJ,IAAA,0BAAiB,EAAC,SAAS,EAAE,OAAO,CAAC,EACrC,GAAG,EACH,eAAe,CAChB,CAAC;IAEF,MAAM,aAAa,GAAG,GAAG,IAAA,uBAAW,EAAC,IAAI,CAAC,WAAW,CAAC;IAEtD,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG;QACpC,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE;YACP,OAAO,EAAE,6BAA6B,oBAAoB,EAAE;YAC5D,GAAG,EAAE,eAAe;SACrB;KACF,CAAC;IACF,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG;QACrC,QAAQ,EAAE,iBAAiB;QAC3B,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,CAAC,YAAY,CAAC;QACzB,OAAO,EAAE;YACP,QAAQ,EAAE;gBACR,kCAAkC,aAAa,IAAI,oBAAoB,IAAI,eAAe,EAAE;gBAC5F,qCAAqC,cAAc,IAAI,eAAe,EAAE;aACzE;YACD,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,eAAe;SACrB;KACF,CAAC;IAEF,IAAA,mCAA0B,EAAC,IAAI,EAAE,kBAAkB,EAAE,aAAa,CAAC,CAAC;IACpE,IAAA,yBAAoB,EAAC,IAAI,EAAE,kBAAkB,EAAE,kCAA0B,CAAC,CAAC;IAE3E,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAA,gBAAU,EAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,IAAA,6CAAyB,EAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAA,sCAAgB,EAAC,IAAI,EAAE;YAC3B,GAAG;YACH,WAAW,EAAE,kBAAkB;YAC/B,aAAa;YACb,aAAa;YACb,kBAAkB,EAAE,IAAA,wBAAY,EAAC,kBAAkB,CAAC;YACpD,SAAS,EAAE,cAAc;YACzB,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;IACL,CAAC;IAED,IAAA,qCAA4B,EAC1B,IAAI,EACJ,IAAA,uBAAY,EAAC;QACX,0BAA0B;QAC1B,WAAW;QACX,mCAAmC;QACnC,+BAA+B;KAChC,CAAC,EACF,IAAA,uBAAY,EAAC,CAAC,KAAK,EAAE,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAC1D,CAAC;IAEF,MAAM,IAAA,yCAA+B,EAAC,IAAI,EAAE,CAAC,kCAA0B,CAAC,CAAC,CAAC;IAE1E,MAAM,IAAA,6BAAoB,EAAC,IAAI,CAAC,CAAC;IACjC,OAAO,GAAG,EAAE;QACV,IAAA,4BAAmB,EAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC,CAAC;AA9GW,QAAA,mBAAmB,uBA8G9B;AAEF,kBAAe,2BAAmB,CAAC"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/ts/dynamodb/generator.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ export interface TsDynamoDBGeneratorSchema {
8
8
  name: string;
9
9
  directory?: string;
10
10
  subDirectory?: string;
11
+ framework: 'electrodb';
11
12
  tableName?: string;
12
13
  infra: 'dynamodb' | 'none';
13
14
  iac: IacOption;
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/schema",
3
3
  "$id": "ts#dynamodb",
4
4
  "title": "ts#dynamodb",
5
- "description": "Create a DynamoDB project",
5
+ "description": "Create a TypeScript DynamoDB project",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "name": {
@@ -27,9 +27,27 @@
27
27
  "description": "The sub directory the project is placed in. By default this is the project name.",
28
28
  "x-prompt": "Which sub directory do you want to create the project in? (By default this is the project name)"
29
29
  },
30
+ "framework": {
31
+ "type": "string",
32
+ "enum": ["electrodb"],
33
+ "default": "electrodb",
34
+ "description": "The framework to use for DynamoDB entities.",
35
+ "x-priority": "important",
36
+ "x-prompt": {
37
+ "message": "Which framework would you like to use for DynamoDB entities?",
38
+ "type": "list",
39
+ "items": [
40
+ {
41
+ "value": "electrodb",
42
+ "label": "ElectroDB"
43
+ }
44
+ ],
45
+ "default": "electrodb"
46
+ }
47
+ },
30
48
  "tableName": {
31
49
  "type": "string",
32
- "description": "The DynamoDB table name. Defaults to the project name."
50
+ "description": "The DynamoDB table name. Auto-generated if not specified."
33
51
  },
34
52
  "infra": {
35
53
  "type": "string",
@@ -8,7 +8,6 @@ export interface AddDynamoDBConstructOptions {
8
8
  projectName: string;
9
9
  nameClassName: string;
10
10
  nameKebabCase: string;
11
- dynamoPackageAlias: string;
12
11
  tableName: string;
13
12
  projectRoot: string;
14
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dynamodb-constructs.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/utils/dynamodb-constructs/dynamodb-constructs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dynamodb-constructs.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/utils/dynamodb-constructs/dynamodb-constructs.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Construct } from 'constructs';
2
- import { PACKAGE_NAME } from '<%= dynamoPackageAlias %>';
3
2
  import { AttributeType, ProjectionType } from 'aws-cdk-lib/aws-dynamodb';
4
3
  import {
5
4
  DynamoDBTable,
@@ -10,6 +9,16 @@ import { readFileSync } from 'fs';
10
9
  import { join } from "path";
11
10
  import { fileURLToPath } from "url";
12
11
 
12
+ const { runtimeConfigKey, tableConfig } = JSON.parse(
13
+ readFileSync(
14
+ join(
15
+ findWorkspaceRoot(fileURLToPath(new URL(import.meta.url))),
16
+ '<%= projectRoot %>/config.json',
17
+ ),
18
+ 'utf-8',
19
+ ),
20
+ ) as { runtimeConfigKey: string; tableConfig: { globalSecondaryIndexes: { indexName: string; partitionKey: string; sortKey?: string }[] } };
21
+
13
22
  export type <%= nameClassName %>Props = Omit<
14
23
  DynamoDBTableProps,
15
24
  'runtimeConfigKey'
@@ -19,20 +28,10 @@ export class <%= nameClassName %> extends DynamoDBTable {
19
28
  constructor(scope: Construct, id: string, props?: <%= nameClassName %>Props) {
20
29
  super(scope, id, {
21
30
  ...props,
22
- runtimeConfigKey: PACKAGE_NAME,
31
+ runtimeConfigKey,
23
32
  });
24
33
 
25
- const { globalSecondaryIndexes } = JSON.parse(
26
- readFileSync(
27
- join(
28
- findWorkspaceRoot(fileURLToPath(new URL(import.meta.url))),
29
- '<%= projectRoot %>/dynamodb.config.json',
30
- ),
31
- 'utf-8',
32
- ),
33
- ) as { globalSecondaryIndexes: { indexName: string; partitionKey: string; sortKey?: string }[] };
34
-
35
- for (const gsi of globalSecondaryIndexes) {
34
+ for (const gsi of tableConfig.globalSecondaryIndexes) {
36
35
  this.table.addGlobalSecondaryIndex({
37
36
  indexName: gsi.indexName,
38
37
  partitionKey: { name: gsi.partitionKey, type: AttributeType.STRING },
@@ -32,8 +32,8 @@ variable "enable_key_rotation" {
32
32
  }
33
33
 
34
34
  locals {
35
- dynamodb_config = jsondecode(file("${path.module}/../../../../../../../<%= projectRoot %>/dynamodb.config.json"))
36
- global_secondary_indexes = [for gsi in local.dynamodb_config.globalSecondaryIndexes : {
35
+ dynamodb_config = jsondecode(file("${path.module}/../../../../../../../<%= projectRoot %>/config.json"))
36
+ global_secondary_indexes = [for gsi in local.dynamodb_config.tableConfig.globalSecondaryIndexes : {
37
37
  name = gsi.indexName
38
38
  hash_key = gsi.partitionKey
39
39
  range_key = try(gsi.sortKey, null)
@@ -55,7 +55,7 @@ module "add_to_runtime_config" {
55
55
  source = "../../../core/runtime-config/entry"
56
56
 
57
57
  namespace = "dynamodb"
58
- key = "<%= nameClassName %>"
58
+ key = local.dynamodb_config.runtimeConfigKey
59
59
  value = {
60
60
  tableName = module.dynamodb_table.table_name
61
61
  }
@@ -1,33 +1,39 @@
1
1
  import {
2
+ BillingMode,
2
3
  CreateTableCommand,
3
4
  DescribeTableCommand,
4
5
  DynamoDBClient,
5
6
  GlobalSecondaryIndexDescription,
7
+ IndexStatus,
8
+ KeyType,
9
+ ProjectionType,
6
10
  ResourceInUseException,
11
+ ScalarAttributeType,
12
+ TableStatus,
7
13
  UpdateTableCommand,
8
- } from '@aws-sdk/client-dynamodb';
9
- import { readFileSync } from 'fs';
10
- import { join, dirname } from 'path';
11
- import { fileURLToPath } from 'url';
14
+ } from "@aws-sdk/client-dynamodb";
15
+ import { readFileSync } from "fs";
12
16
 
13
- const __dirname = dirname(fileURLToPath(import.meta.url));
14
- const { globalSecondaryIndexes } = JSON.parse(
15
- readFileSync(join(__dirname, '../dynamodb.config.json'), 'utf-8'),
16
- ) as { globalSecondaryIndexes: { indexName: string; partitionKey: string; sortKey?: string }[] };
17
-
18
- const [tableName, port] = process.argv.slice(2);
19
- const endpoint = `http://localhost:${port}`;
17
+ const {
18
+ serveLocal: { port, tableName },
19
+ tableConfig: { globalSecondaryIndexes },
20
+ } = JSON.parse(readFileSync("config.json", "utf-8")) as {
21
+ serveLocal: { port: number; tableName: string };
22
+ tableConfig: {
23
+ globalSecondaryIndexes: {
24
+ indexName: string;
25
+ partitionKey: string;
26
+ sortKey?: string;
27
+ }[];
28
+ };
29
+ };
20
30
 
21
- const REQUEST_TIMEOUT_MS = 10_000;
22
- const timeoutSignal = () => AbortSignal.timeout(REQUEST_TIMEOUT_MS);
31
+ const timeoutSignal = () => AbortSignal.timeout(10000);
23
32
 
24
33
  const client = new DynamoDBClient({
25
- endpoint,
34
+ endpoint: `http://localhost:${port}`,
26
35
  region: 'us-east-1',
27
- credentials: {
28
- accessKeyId: 'accessKeyId',
29
- secretAccessKey: 'secretAccessKey',
30
- },
36
+ credentials: { accessKeyId: 'UNUSED', secretAccessKey: 'UNUSED' },
31
37
  });
32
38
 
33
39
  const waitForTableActive = async (
@@ -40,9 +46,9 @@ const waitForTableActive = async (
40
46
  { abortSignal: timeoutSignal() },
41
47
  );
42
48
  const allActive =
43
- Table?.TableStatus === 'ACTIVE' &&
49
+ Table?.TableStatus === TableStatus.ACTIVE &&
44
50
  (Table?.GlobalSecondaryIndexes ?? []).every(
45
- (g: GlobalSecondaryIndexDescription) => g.IndexStatus === 'ACTIVE',
51
+ (g: GlobalSecondaryIndexDescription) => g.IndexStatus === IndexStatus.ACTIVE,
46
52
  );
47
53
  if (allActive) return;
48
54
  await new Promise((resolve) => setTimeout(resolve, 500));
@@ -55,12 +61,14 @@ const ensureTable = async (
55
61
  gsIs: { indexName: string; partitionKey: string; sortKey?: string }[],
56
62
  ): Promise<void> => {
57
63
  const gsiAttributeDefinitions = gsIs.flatMap((gsi) => [
58
- { AttributeName: gsi.partitionKey, AttributeType: 'S' as const },
59
- ...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }] : []),
64
+ { AttributeName: gsi.partitionKey, AttributeType: ScalarAttributeType.S },
65
+ ...(gsi.sortKey
66
+ ? [{ AttributeName: gsi.sortKey, AttributeType: ScalarAttributeType.S }]
67
+ : []),
60
68
  ]);
61
69
  const attributeDefinitions = [
62
- { AttributeName: 'pk', AttributeType: 'S' as const },
63
- { AttributeName: 'sk', AttributeType: 'S' as const },
70
+ { AttributeName: "pk", AttributeType: ScalarAttributeType.S },
71
+ { AttributeName: "sk", AttributeType: ScalarAttributeType.S },
64
72
  ...gsiAttributeDefinitions.filter(
65
73
  (a, i, arr) =>
66
74
  arr.findIndex((b) => b.AttributeName === a.AttributeName) === i,
@@ -69,10 +77,12 @@ const ensureTable = async (
69
77
  const globalSecondaryIndexes = gsIs.map((gsi) => ({
70
78
  IndexName: gsi.indexName,
71
79
  KeySchema: [
72
- { AttributeName: gsi.partitionKey, KeyType: 'HASH' as const },
73
- ...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' as const }] : []),
80
+ { AttributeName: gsi.partitionKey, KeyType: KeyType.HASH },
81
+ ...(gsi.sortKey
82
+ ? [{ AttributeName: gsi.sortKey, KeyType: KeyType.RANGE }]
83
+ : []),
74
84
  ],
75
- Projection: { ProjectionType: 'ALL' as const },
85
+ Projection: { ProjectionType: ProjectionType.ALL },
76
86
  }));
77
87
 
78
88
  for (let attempt = 0; attempt < 30; attempt++) {
@@ -83,10 +93,10 @@ const ensureTable = async (
83
93
  TableName: tblName,
84
94
  AttributeDefinitions: attributeDefinitions,
85
95
  KeySchema: [
86
- { AttributeName: 'pk', KeyType: 'HASH' },
87
- { AttributeName: 'sk', KeyType: 'RANGE' },
96
+ { AttributeName: "pk", KeyType: KeyType.HASH },
97
+ { AttributeName: "sk", KeyType: KeyType.RANGE },
88
98
  ],
89
- BillingMode: 'PAY_PER_REQUEST',
99
+ BillingMode: BillingMode.PAY_PER_REQUEST,
90
100
  ...(globalSecondaryIndexes.length > 0 && {
91
101
  GlobalSecondaryIndexes: globalSecondaryIndexes,
92
102
  }),
@@ -108,7 +118,7 @@ const ensureTable = async (
108
118
  const existingGSIs = Table?.GlobalSecondaryIndexes ?? [];
109
119
  const existingNames = new Set(
110
120
  existingGSIs.map(
111
- (g: GlobalSecondaryIndexDescription) => g.IndexName ?? '',
121
+ (g: GlobalSecondaryIndexDescription) => g.IndexName ?? "",
112
122
  ),
113
123
  );
114
124
  const desiredNames = new Set(gsIs.map((g) => g.indexName));
@@ -136,18 +146,35 @@ const ensureTable = async (
136
146
  new UpdateTableCommand({
137
147
  TableName: tblName,
138
148
  AttributeDefinitions: [
139
- { AttributeName: gsi.partitionKey, AttributeType: 'S' },
140
- ...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, AttributeType: 'S' as const }] : []),
149
+ { AttributeName: gsi.partitionKey, AttributeType: ScalarAttributeType.S },
150
+ ...(gsi.sortKey
151
+ ? [
152
+ {
153
+ AttributeName: gsi.sortKey,
154
+ AttributeType: ScalarAttributeType.S,
155
+ },
156
+ ]
157
+ : []),
141
158
  ],
142
159
  GlobalSecondaryIndexUpdates: [
143
160
  {
144
161
  Create: {
145
162
  IndexName: gsi.indexName,
146
163
  KeySchema: [
147
- { AttributeName: gsi.partitionKey, KeyType: 'HASH' },
148
- ...(gsi.sortKey ? [{ AttributeName: gsi.sortKey, KeyType: 'RANGE' }] : []),
164
+ {
165
+ AttributeName: gsi.partitionKey,
166
+ KeyType: KeyType.HASH,
167
+ },
168
+ ...(gsi.sortKey
169
+ ? [
170
+ {
171
+ AttributeName: gsi.sortKey,
172
+ KeyType: KeyType.RANGE,
173
+ },
174
+ ]
175
+ : []),
149
176
  ],
150
- Projection: { ProjectionType: 'ALL' },
177
+ Projection: { ProjectionType: ProjectionType.ALL },
151
178
  },
152
179
  },
153
180
  ],
@@ -0,0 +1,13 @@
1
+ import { spawnSync } from 'child_process';
2
+ import { readFileSync } from 'fs';
3
+
4
+ const { containerEngine, image } =
5
+ JSON.parse(readFileSync('config.json', 'utf-8')).serveLocal;
6
+
7
+ const inspect = spawnSync(containerEngine, ['image', 'inspect', image], { stdio: 'ignore' });
8
+ if (inspect.status !== 0) {
9
+ const pull = spawnSync(containerEngine, ['pull', image], { stdio: 'inherit' });
10
+ if (pull.status !== 0) {
11
+ process.exit(pull.status ?? 1);
12
+ }
13
+ }
@@ -1,17 +1,17 @@
1
1
  import { spawn, spawnSync } from 'child_process';
2
+ import { readFileSync } from 'fs';
2
3
 
3
- const ENGINE = '<%= containerEngine %>';
4
-
5
- const [containerName, image, hostPort] = process.argv.slice(2);
4
+ const { containerEngine, containerName, image, port } =
5
+ JSON.parse(readFileSync('config.json', 'utf-8')).serveLocal;
6
6
 
7
7
  const containerExists = (): boolean =>
8
- spawnSync(ENGINE, ['container', 'inspect', containerName], {
8
+ spawnSync(containerEngine, ['container', 'inspect', containerName], {
9
9
  stdio: 'ignore',
10
10
  }).status === 0;
11
11
 
12
12
  const isRunning = (): boolean => {
13
13
  const result = spawnSync(
14
- ENGINE,
14
+ containerEngine,
15
15
  ['container', 'inspect', '-f', '{{.State.Running}}', containerName],
16
16
  { encoding: 'utf-8' },
17
17
  );
@@ -29,19 +29,29 @@ for (;;) {
29
29
  if (!isRunning()) {
30
30
  // Another process may have started it between our inspect and start — container engine start
31
31
  // exits 0 even if the container is already running, so no special-casing needed.
32
- const start = spawnSync(ENGINE, ['start', containerName], {
32
+ const start = spawnSync(containerEngine, ['start', containerName], {
33
33
  stdio: 'inherit',
34
34
  });
35
35
  if (start.status !== 0) process.exit(start.status ?? 1);
36
36
  }
37
37
  break;
38
38
  }
39
- const runArgs = (
40
- `run <%- containerEngine === 'docker' ? '--rm ' : '' %>--name ${containerName} -u root -w /home/dynamodblocal` +
41
- ` -p ${hostPort}:${hostPort} -v ${containerName}-data:/home/dynamodblocal/data` +
42
- ` -d ${image} -jar DynamoDBLocal.jar -sharedDb -dbPath ./data -port ${hostPort} -optimizeDbBeforeStartup`
43
- ).split(' ');
44
- const create = spawnSync(ENGINE, runArgs, { stdio: 'pipe' });
39
+ const runArgs = [
40
+ 'run',
41
+ ...(containerEngine === 'docker' ? ['--rm'] : []),
42
+ '--name', containerName,
43
+ '-u', 'root',
44
+ '-w', '/home/dynamodblocal',
45
+ `-p`, `${port}:${port}`,
46
+ '-v', `${containerName}-data:/home/dynamodblocal/data`,
47
+ '-d', image,
48
+ '-jar', 'DynamoDBLocal.jar',
49
+ '-sharedDb',
50
+ '-dbPath', './data',
51
+ '-port', `${port}`,
52
+ '-optimizeDbBeforeStartup',
53
+ ];
54
+ const create = spawnSync(containerEngine, runArgs, { stdio: 'pipe' });
45
55
  if (create.status === 0) {
46
56
  created = true;
47
57
  break;
@@ -52,7 +62,7 @@ for (;;) {
52
62
  }
53
63
  }
54
64
 
55
- const logs = spawn(ENGINE, ['logs', '-f', containerName], {
65
+ const logs = spawn(containerEngine, ['logs', '-f', containerName], {
56
66
  stdio: ['ignore', 'inherit', 'inherit'],
57
67
  });
58
68
 
@@ -62,11 +72,11 @@ const cleanup = () => {
62
72
  if (exiting) return;
63
73
  exiting = true;
64
74
  if (created) {
65
- <%_ if (containerEngine === 'docker') { _%>
66
- spawnSync(ENGINE, ['stop', containerName], { stdio: 'ignore' });
67
- <%_ } else { _%>
68
- spawnSync(ENGINE, ['rm', '-f', containerName], { stdio: 'ignore' });
69
- <%_ } _%>
75
+ if (containerEngine === 'docker') {
76
+ spawnSync(containerEngine, ['stop', containerName], { stdio: 'ignore' });
77
+ } else {
78
+ spawnSync(containerEngine, ['rm', '-f', containerName], { stdio: 'ignore' });
79
+ }
70
80
  }
71
81
  logs.kill();
72
82
  process.exit(0);
@@ -20,12 +20,13 @@ export interface AssignPortOptions {
20
20
  };
21
21
  }
22
22
  /**
23
- * Assign a port shared across all projects created by the same generator.
24
- * If this project already has a port, or a sibling project created by the same
25
- * generator has one, reuse it; otherwise assign a fresh one. Mutates the
26
- * project to register the port in its metadata.ports.
23
+ * Assign a port shared across all projects created by the same generator (or
24
+ * family of generators). If this project already has a port, or a sibling
25
+ * project created by any of the given generator IDs has one, reuse it;
26
+ * otherwise assign a fresh one. Mutates the project to register the port in
27
+ * its metadata.ports.
27
28
  */
28
- export declare const assignSharedPort: (tree: Tree, project: ProjectConfiguration, generatorId: string, startPort: number) => number;
29
+ export declare const assignSharedPort: (tree: Tree, project: ProjectConfiguration, generatorId: string | string[], startPort: number) => number;
29
30
  /**
30
31
  * Assign a port for a particular target within a project.
31
32
  * Mutates the project to add/update its metadata.ports with the newly assigned port.
package/src/utils/port.js CHANGED
@@ -31,12 +31,14 @@ const getExistingComponentPort = (project, component) => {
31
31
  return typeof match?.port === 'number' ? match.port : undefined;
32
32
  };
33
33
  /**
34
- * Assign a port shared across all projects created by the same generator.
35
- * If this project already has a port, or a sibling project created by the same
36
- * generator has one, reuse it; otherwise assign a fresh one. Mutates the
37
- * project to register the port in its metadata.ports.
34
+ * Assign a port shared across all projects created by the same generator (or
35
+ * family of generators). If this project already has a port, or a sibling
36
+ * project created by any of the given generator IDs has one, reuse it;
37
+ * otherwise assign a fresh one. Mutates the project to register the port in
38
+ * its metadata.ports.
38
39
  */
39
40
  const assignSharedPort = (tree, project, generatorId, startPort) => {
41
+ const generatorIds = Array.isArray(generatorId) ? generatorId : [generatorId];
40
42
  // Reuse this project's own port if it already has one (idempotent on re-run)
41
43
  const ownPort = getExistingProjectPort(project);
42
44
  if (ownPort !== undefined) {
@@ -49,7 +51,7 @@ const assignSharedPort = (tree, project, generatorId, startPort) => {
49
51
  generator: p.metadata?.generator,
50
52
  port: getExistingProjectPort(p),
51
53
  }))
52
- .find((p) => p.generator === generatorId && p.port !== undefined)?.port;
54
+ .find((p) => generatorIds.includes(p.generator) && p.port !== undefined)?.port;
53
55
  if (siblingPort !== undefined) {
54
56
  project.metadata ??= {};
55
57
  project.metadata.ports = [