@empire-builder-kit/nx 1.0.0-beta.10

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 (243) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +34 -0
  4. package/executors.json +74 -0
  5. package/generators.json +40 -0
  6. package/migrations/standard-pre-v1-to-v1.md +11 -0
  7. package/package.json +80 -0
  8. package/src/blueprints/execution.d.ts +31 -0
  9. package/src/blueprints/execution.js +166 -0
  10. package/src/blueprints/execution.js.map +1 -0
  11. package/src/blueprints/index.d.ts +5 -0
  12. package/src/blueprints/index.js +9 -0
  13. package/src/blueprints/index.js.map +1 -0
  14. package/src/blueprints/inputs.d.ts +43 -0
  15. package/src/blueprints/inputs.js +103 -0
  16. package/src/blueprints/inputs.js.map +1 -0
  17. package/src/blueprints/manifest.d.ts +281 -0
  18. package/src/blueprints/manifest.js +441 -0
  19. package/src/blueprints/manifest.js.map +1 -0
  20. package/src/blueprints/resolver.d.ts +28 -0
  21. package/src/blueprints/resolver.js +218 -0
  22. package/src/blueprints/resolver.js.map +1 -0
  23. package/src/blueprints/transitions.d.ts +20 -0
  24. package/src/blueprints/transitions.js +61 -0
  25. package/src/blueprints/transitions.js.map +1 -0
  26. package/src/executors/deploy/deploy.d.ts +4 -0
  27. package/src/executors/deploy/deploy.js +6 -0
  28. package/src/executors/deploy/deploy.js.map +1 -0
  29. package/src/executors/deployment-plan/deployment-plan.d.ts +9 -0
  30. package/src/executors/deployment-plan/deployment-plan.js +50 -0
  31. package/src/executors/deployment-plan/deployment-plan.js.map +1 -0
  32. package/src/executors/deployment-plan/schema.json +24 -0
  33. package/src/executors/dev/dev.d.ts +4 -0
  34. package/src/executors/dev/dev.js +6 -0
  35. package/src/executors/dev/dev.js.map +1 -0
  36. package/src/executors/dev-doctor/dev-doctor.d.ts +31 -0
  37. package/src/executors/dev-doctor/dev-doctor.js +260 -0
  38. package/src/executors/dev-doctor/dev-doctor.js.map +1 -0
  39. package/src/executors/dev-doctor/schema.json +17 -0
  40. package/src/executors/dev-setup/dev-setup.d.ts +11 -0
  41. package/src/executors/dev-setup/dev-setup.js +454 -0
  42. package/src/executors/dev-setup/dev-setup.js.map +1 -0
  43. package/src/executors/dev-setup/schema.json +16 -0
  44. package/src/executors/fleet/fleet.d.ts +62 -0
  45. package/src/executors/fleet/fleet.js +613 -0
  46. package/src/executors/fleet/fleet.js.map +1 -0
  47. package/src/executors/fleet/schema.json +37 -0
  48. package/src/executors/foundation-preflight/foundation-preflight.d.ts +15 -0
  49. package/src/executors/foundation-preflight/foundation-preflight.js +116 -0
  50. package/src/executors/foundation-preflight/foundation-preflight.js.map +1 -0
  51. package/src/executors/foundation-preflight/schema.json +31 -0
  52. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +8 -0
  53. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +41 -0
  54. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +1 -0
  55. package/src/executors/foundation-profile-preflight/schema.json +21 -0
  56. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.d.ts +13 -0
  57. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js +69 -0
  58. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js.map +1 -0
  59. package/src/executors/foundation-remove-preflight/schema.json +17 -0
  60. package/src/executors/github-bootstrap/github-bootstrap.d.ts +8 -0
  61. package/src/executors/github-bootstrap/github-bootstrap.js +30 -0
  62. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -0
  63. package/src/executors/github-bootstrap/schema.json +25 -0
  64. package/src/executors/refresh/refresh.d.ts +4 -0
  65. package/src/executors/refresh/refresh.js +6 -0
  66. package/src/executors/refresh/refresh.js.map +1 -0
  67. package/src/executors/remove/remove.d.ts +4 -0
  68. package/src/executors/remove/remove.js +6 -0
  69. package/src/executors/remove/remove.js.map +1 -0
  70. package/src/executors/sst-lifecycle/run-sst-command.d.ts +31 -0
  71. package/src/executors/sst-lifecycle/run-sst-command.js +226 -0
  72. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -0
  73. package/src/executors/sst-lifecycle/schema.json +45 -0
  74. package/src/executors/unlock/unlock.d.ts +4 -0
  75. package/src/executors/unlock/unlock.js +6 -0
  76. package/src/executors/unlock/unlock.js.map +1 -0
  77. package/src/executors/work-markers/schema.json +14 -0
  78. package/src/executors/work-markers/work-markers.d.ts +6 -0
  79. package/src/executors/work-markers/work-markers.js +20 -0
  80. package/src/executors/work-markers/work-markers.js.map +1 -0
  81. package/src/foundation/aurora-logical-database.d.ts +76 -0
  82. package/src/foundation/aurora-logical-database.js +419 -0
  83. package/src/foundation/aurora-logical-database.js.map +1 -0
  84. package/src/foundation/discovery.d.ts +55 -0
  85. package/src/foundation/discovery.js +55 -0
  86. package/src/foundation/discovery.js.map +1 -0
  87. package/src/foundation/index.d.ts +6 -0
  88. package/src/foundation/index.js +10 -0
  89. package/src/foundation/index.js.map +1 -0
  90. package/src/foundation/local-database-contract.d.ts +30 -0
  91. package/src/foundation/local-database-contract.js +75 -0
  92. package/src/foundation/local-database-contract.js.map +1 -0
  93. package/src/foundation/preflight.d.ts +31 -0
  94. package/src/foundation/preflight.js +114 -0
  95. package/src/foundation/preflight.js.map +1 -0
  96. package/src/foundation/provision-database-bindings.d.ts +30 -0
  97. package/src/foundation/provision-database-bindings.js +113 -0
  98. package/src/foundation/provision-database-bindings.js.map +1 -0
  99. package/src/foundation/provision-logical-database.d.ts +26 -0
  100. package/src/foundation/provision-logical-database.js +163 -0
  101. package/src/foundation/provision-logical-database.js.map +1 -0
  102. package/src/foundation/requirements.d.ts +37 -0
  103. package/src/foundation/requirements.js +141 -0
  104. package/src/foundation/requirements.js.map +1 -0
  105. package/src/foundation/stages.d.ts +14 -0
  106. package/src/foundation/stages.js +51 -0
  107. package/src/foundation/stages.js.map +1 -0
  108. package/src/generators/function/function.d.ts +13 -0
  109. package/src/generators/function/function.js +71 -0
  110. package/src/generators/function/function.js.map +1 -0
  111. package/src/generators/function/schema.d.ts +5 -0
  112. package/src/generators/function/schema.json +20 -0
  113. package/src/generators/job/job.d.ts +4 -0
  114. package/src/generators/job/job.js +5 -0
  115. package/src/generators/job/job.js.map +1 -0
  116. package/src/generators/preset/generator.d.ts +5 -0
  117. package/src/generators/preset/generator.js +41 -0
  118. package/src/generators/preset/generator.js.map +1 -0
  119. package/src/generators/preset/schema.d.ts +4 -0
  120. package/src/generators/preset/schema.json +22 -0
  121. package/src/generators/preset/workspace-files.d.ts +18 -0
  122. package/src/generators/preset/workspace-files.js +1605 -0
  123. package/src/generators/preset/workspace-files.js.map +1 -0
  124. package/src/generators/repository-policy/repository-policy.d.ts +4 -0
  125. package/src/generators/repository-policy/repository-policy.js +107 -0
  126. package/src/generators/repository-policy/repository-policy.js.map +1 -0
  127. package/src/generators/repository-policy/schema.d.ts +18 -0
  128. package/src/generators/repository-policy/schema.json +46 -0
  129. package/src/generators/service/service.d.ts +4 -0
  130. package/src/generators/service/service.js +5 -0
  131. package/src/generators/service/service.js.map +1 -0
  132. package/src/generators/slice/schema.d.ts +7 -0
  133. package/src/generators/slice/schema.json +38 -0
  134. package/src/generators/slice/slice.d.ts +26 -0
  135. package/src/generators/slice/slice.js +1698 -0
  136. package/src/generators/slice/slice.js.map +1 -0
  137. package/src/generators/upgrade/schema.d.ts +8 -0
  138. package/src/generators/upgrade/schema.json +31 -0
  139. package/src/generators/upgrade/upgrade.d.ts +27 -0
  140. package/src/generators/upgrade/upgrade.js +682 -0
  141. package/src/generators/upgrade/upgrade.js.map +1 -0
  142. package/src/generators/workload/schema.d.ts +6 -0
  143. package/src/generators/workload/schema.json +21 -0
  144. package/src/generators/workload/workload.d.ts +16 -0
  145. package/src/generators/workload/workload.js +157 -0
  146. package/src/generators/workload/workload.js.map +1 -0
  147. package/src/git-policy/action-pins.d.ts +28 -0
  148. package/src/git-policy/action-pins.js +35 -0
  149. package/src/git-policy/action-pins.js.map +1 -0
  150. package/src/git-policy/github-bootstrap.d.ts +23 -0
  151. package/src/git-policy/github-bootstrap.js +759 -0
  152. package/src/git-policy/github-bootstrap.js.map +1 -0
  153. package/src/git-policy/index.d.ts +3 -0
  154. package/src/git-policy/index.js +7 -0
  155. package/src/git-policy/index.js.map +1 -0
  156. package/src/git-policy/routing.d.ts +15 -0
  157. package/src/git-policy/routing.js +77 -0
  158. package/src/git-policy/routing.js.map +1 -0
  159. package/src/index.d.ts +8 -0
  160. package/src/index.js +12 -0
  161. package/src/index.js.map +1 -0
  162. package/src/local-dev/contracts.d.ts +31 -0
  163. package/src/local-dev/contracts.js +126 -0
  164. package/src/local-dev/contracts.js.map +1 -0
  165. package/src/local-dev/effects.d.ts +16 -0
  166. package/src/local-dev/effects.js +63 -0
  167. package/src/local-dev/effects.js.map +1 -0
  168. package/src/local-dev/gateway-daemon.d.ts +4 -0
  169. package/src/local-dev/gateway-daemon.js +39 -0
  170. package/src/local-dev/gateway-daemon.js.map +1 -0
  171. package/src/local-dev/gateway.d.ts +60 -0
  172. package/src/local-dev/gateway.js +368 -0
  173. package/src/local-dev/gateway.js.map +1 -0
  174. package/src/local-dev/identity.d.ts +16 -0
  175. package/src/local-dev/identity.js +101 -0
  176. package/src/local-dev/identity.js.map +1 -0
  177. package/src/local-dev/index.d.ts +7 -0
  178. package/src/local-dev/index.js +11 -0
  179. package/src/local-dev/index.js.map +1 -0
  180. package/src/local-dev/portless.d.ts +15 -0
  181. package/src/local-dev/portless.js +115 -0
  182. package/src/local-dev/portless.js.map +1 -0
  183. package/src/local-dev/ports.d.ts +10 -0
  184. package/src/local-dev/ports.js +39 -0
  185. package/src/local-dev/ports.js.map +1 -0
  186. package/src/local-dev/proxy.d.ts +37 -0
  187. package/src/local-dev/proxy.js +271 -0
  188. package/src/local-dev/proxy.js.map +1 -0
  189. package/src/local-dev/tls.d.ts +24 -0
  190. package/src/local-dev/tls.js +294 -0
  191. package/src/local-dev/tls.js.map +1 -0
  192. package/src/ownership/composition.d.ts +16 -0
  193. package/src/ownership/composition.js +125 -0
  194. package/src/ownership/composition.js.map +1 -0
  195. package/src/ownership/foundation-record.d.ts +66 -0
  196. package/src/ownership/foundation-record.js +108 -0
  197. package/src/ownership/foundation-record.js.map +1 -0
  198. package/src/ownership/hash.d.ts +2 -0
  199. package/src/ownership/hash.js +10 -0
  200. package/src/ownership/hash.js.map +1 -0
  201. package/src/ownership/index.d.ts +6 -0
  202. package/src/ownership/index.js +10 -0
  203. package/src/ownership/index.js.map +1 -0
  204. package/src/ownership/json-ownership.d.ts +13 -0
  205. package/src/ownership/json-ownership.js +147 -0
  206. package/src/ownership/json-ownership.js.map +1 -0
  207. package/src/ownership/record.d.ts +186 -0
  208. package/src/ownership/record.js +336 -0
  209. package/src/ownership/record.js.map +1 -0
  210. package/src/ownership/workspace-record.d.ts +66 -0
  211. package/src/ownership/workspace-record.js +108 -0
  212. package/src/ownership/workspace-record.js.map +1 -0
  213. package/src/repository-policy/aurora-preflight.d.ts +15 -0
  214. package/src/repository-policy/aurora-preflight.js +45 -0
  215. package/src/repository-policy/aurora-preflight.js.map +1 -0
  216. package/src/repository-policy/deployment-plan.d.ts +24 -0
  217. package/src/repository-policy/deployment-plan.js +124 -0
  218. package/src/repository-policy/deployment-plan.js.map +1 -0
  219. package/src/repository-policy/foundation-profile.d.ts +20 -0
  220. package/src/repository-policy/foundation-profile.js +45 -0
  221. package/src/repository-policy/foundation-profile.js.map +1 -0
  222. package/src/repository-policy/index.d.ts +4 -0
  223. package/src/repository-policy/index.js +8 -0
  224. package/src/repository-policy/index.js.map +1 -0
  225. package/src/repository-policy/policy.d.ts +59 -0
  226. package/src/repository-policy/policy.js +274 -0
  227. package/src/repository-policy/policy.js.map +1 -0
  228. package/src/schemas/blueprint-input-schema-v1.json +23 -0
  229. package/src/schemas/blueprint-v1.json +186 -0
  230. package/src/schemas/foundation-ownership-v2.json +42 -0
  231. package/src/schemas/foundation-requirement-v1.json +32 -0
  232. package/src/schemas/generated-ownership-v2.json +117 -0
  233. package/src/schemas/repository-policy-v1.json +58 -0
  234. package/src/schemas/workspace-ownership-v2.json +42 -0
  235. package/src/validation.d.ts +14 -0
  236. package/src/validation.js +14 -0
  237. package/src/validation.js.map +1 -0
  238. package/src/work-markers/index.d.ts +1 -0
  239. package/src/work-markers/index.js +5 -0
  240. package/src/work-markers/index.js.map +1 -0
  241. package/src/work-markers/work-markers.d.ts +39 -0
  242. package/src/work-markers/work-markers.js +359 -0
  243. package/src/work-markers/work-markers.js.map +1 -0
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POSTGRES_IDENTIFIER_MAX_BYTES = void 0;
4
+ exports.normalizePostgresIdentifier = normalizePostgresIdentifier;
5
+ exports.postgresIdentifierByteLength = postgresIdentifierByteLength;
6
+ exports.assertPostgresIdentifierLength = assertPostgresIdentifierLength;
7
+ exports.resolveLogicalDatabaseIdentifiers = resolveLogicalDatabaseIdentifiers;
8
+ exports.resolveLocalDatabaseContract = resolveLocalDatabaseContract;
9
+ exports.POSTGRES_IDENTIFIER_MAX_BYTES = 63;
10
+ function normalizePostgresIdentifier(input) {
11
+ const sanitized = input.replace(/[^A-Za-z0-9_]/g, '_');
12
+ return /^[A-Za-z_]/.test(sanitized) ? sanitized : `s_${sanitized}`;
13
+ }
14
+ function requireIdentifierInput(value, label) {
15
+ if (value.trim() === '') {
16
+ throw new Error(`${label} must be a non-empty string.`);
17
+ }
18
+ }
19
+ function postgresIdentifierByteLength(identifier) {
20
+ return new TextEncoder().encode(identifier).byteLength;
21
+ }
22
+ function assertPostgresIdentifierLength(identifier, label) {
23
+ const bytes = postgresIdentifierByteLength(identifier);
24
+ if (bytes > exports.POSTGRES_IDENTIFIER_MAX_BYTES) {
25
+ throw new Error(`${label} "${identifier}" is ${bytes} UTF-8 bytes; PostgreSQL identifiers must be ${exports.POSTGRES_IDENTIFIER_MAX_BYTES} bytes or fewer. Choose a shorter stage, Slice, or database identifier. Identifiers are never truncated.`);
26
+ }
27
+ }
28
+ function resolveLogicalDatabaseIdentifiers(options) {
29
+ requireIdentifierInput(options.stage, 'Consumer stage');
30
+ requireIdentifierInput(options.slice, 'Product Slice name');
31
+ requireIdentifierInput(options.database, 'Logical database identifier');
32
+ const database = normalizePostgresIdentifier(`${options.stage}_${options.slice}_${options.database}`);
33
+ const readwriteRole = `${database}_readwrite`;
34
+ const readonlyRole = `${database}_readonly`;
35
+ const localDatabase = normalizePostgresIdentifier(`${options.slice}_${options.database}`);
36
+ const localReadwriteRole = `${localDatabase}_readwrite`;
37
+ for (const [identifier, label] of [
38
+ [database, 'Physical database identifier'],
39
+ [readwriteRole, 'Physical read-write role identifier'],
40
+ [readonlyRole, 'Physical read-only role identifier'],
41
+ [localDatabase, 'Local database identifier'],
42
+ [localReadwriteRole, 'Local read-write role identifier'],
43
+ ]) {
44
+ assertPostgresIdentifierLength(identifier, label);
45
+ }
46
+ return {
47
+ database,
48
+ localDatabase,
49
+ localReadwriteRole,
50
+ readonlyRole,
51
+ readwriteRole,
52
+ };
53
+ }
54
+ function deterministicLocalDatabasePort(key) {
55
+ let hash = 5381;
56
+ for (let index = 0; index < key.length; index += 1) {
57
+ hash = (hash * 33) ^ key.charCodeAt(index);
58
+ }
59
+ return 54320 + (Math.abs(hash) % 100);
60
+ }
61
+ function resolveLocalDatabaseContract(options) {
62
+ const database = normalizePostgresIdentifier(`${options.slice}_${options.database}`);
63
+ const username = `${database}_readwrite`;
64
+ assertPostgresIdentifierLength(database, 'Local database identifier');
65
+ assertPostgresIdentifierLength(username, 'Local read-write role identifier');
66
+ return {
67
+ database,
68
+ host: '127.0.0.1',
69
+ password: options.password ?? `${options.slice}-local-dev`,
70
+ port: options.port ??
71
+ deterministicLocalDatabasePort(`${options.slice}_${options.database}`),
72
+ username,
73
+ };
74
+ }
75
+ //# sourceMappingURL=local-database-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-database-contract.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/local-database-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type FoundationDiscovery } from './discovery.js';
2
+ import { type FoundationRequirement } from './requirements.js';
3
+ export interface FoundationParameterReadResult {
4
+ invalidNames: readonly string[];
5
+ values: ReadonlyMap<string, string | undefined>;
6
+ }
7
+ export type FoundationParameterReader = (names: readonly string[]) => Promise<FoundationParameterReadResult>;
8
+ export interface FoundationPreflightReport {
9
+ consumerStage: string;
10
+ discovery?: FoundationDiscovery;
11
+ foundationStage: string;
12
+ issues: readonly string[];
13
+ ok: boolean;
14
+ region: string;
15
+ state: 'absent' | 'invalid' | 'ready';
16
+ }
17
+ export declare function createFoundationParameterReader(options: {
18
+ profile?: string;
19
+ region?: string;
20
+ }): {
21
+ read: FoundationParameterReader;
22
+ resolveRegion: () => Promise<string>;
23
+ };
24
+ export declare function evaluateFoundationPreflight(options: {
25
+ consumerStage: string;
26
+ foundationStage?: string;
27
+ readParameters: FoundationParameterReader;
28
+ region: string;
29
+ requirement: FoundationRequirement;
30
+ }): Promise<FoundationPreflightReport>;
31
+ export declare function formatFoundationPreflightReport(report: FoundationPreflightReport): string;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createFoundationParameterReader = createFoundationParameterReader;
4
+ exports.evaluateFoundationPreflight = evaluateFoundationPreflight;
5
+ exports.formatFoundationPreflightReport = formatFoundationPreflightReport;
6
+ const client_ssm_1 = require("@aws-sdk/client-ssm");
7
+ const credential_providers_1 = require("@aws-sdk/credential-providers");
8
+ const discovery_js_1 = require("./discovery.js");
9
+ const requirements_js_1 = require("./requirements.js");
10
+ const stages_js_1 = require("./stages.js");
11
+ function chunks(values, size) {
12
+ const result = [];
13
+ for (let index = 0; index < values.length; index += size) {
14
+ result.push(values.slice(index, index + size));
15
+ }
16
+ return result;
17
+ }
18
+ function createFoundationParameterReader(options) {
19
+ const profile = options.profile?.trim();
20
+ const client = new client_ssm_1.SSMClient({
21
+ ...(profile ? { credentials: (0, credential_providers_1.fromIni)({ profile }), profile } : {}),
22
+ ...(options.region?.trim() ? { region: options.region.trim() } : {}),
23
+ });
24
+ return {
25
+ read: async (names) => {
26
+ const response = await client.send(new client_ssm_1.GetParametersCommand({ Names: [...names] }));
27
+ return {
28
+ invalidNames: response.InvalidParameters ?? [],
29
+ values: new Map((response.Parameters ?? []).map((parameter) => [
30
+ parameter.Name ?? '',
31
+ parameter.Value,
32
+ ])),
33
+ };
34
+ },
35
+ resolveRegion: () => client.config.region(),
36
+ };
37
+ }
38
+ async function evaluateFoundationPreflight(options) {
39
+ const { consumerStage, foundationStage } = (0, stages_js_1.resolveFoundationStages)(options);
40
+ const names = discovery_js_1.FOUNDATION_REQUIRED_SSM_KEYS.map((key) => (0, discovery_js_1.foundationSsmPath)(foundationStage, key));
41
+ const values = new Map();
42
+ const invalidNames = new Set();
43
+ for (const batch of chunks(names, 10)) {
44
+ const result = await options.readParameters(batch);
45
+ result.invalidNames.forEach((name) => invalidNames.add(name));
46
+ result.values.forEach((value, name) => values.set(name, value));
47
+ }
48
+ const issues = names
49
+ .filter((name) => invalidNames.has(name) || !values.get(name))
50
+ .map((name) => `missing required parameter ${name}`);
51
+ const allRequiredParametersMissing = names.every((name) => invalidNames.has(name) || !values.has(name));
52
+ const value = (key) => values.get((0, discovery_js_1.foundationSsmPath)(foundationStage, key)) ?? '';
53
+ const schemaVersion = Number(value('schemaVersion'));
54
+ if (schemaVersion !== discovery_js_1.FOUNDATION_SSM_SCHEMA_VERSION) {
55
+ issues.push(`Foundation discovery schema ${value('schemaVersion') || 'missing'} does not match ${discovery_js_1.FOUNDATION_SSM_SCHEMA_VERSION}`);
56
+ }
57
+ const capabilities = value('capabilities')
58
+ .split(',')
59
+ .map((capability) => capability.trim())
60
+ .filter(Boolean);
61
+ const compatibility = (0, requirements_js_1.validateFoundationCompatibility)(options.requirement, {
62
+ capabilities,
63
+ contractVersion: value('contractVersion'),
64
+ });
65
+ issues.push(...compatibility.issues.map((issue) => `${issue.path}: ${issue.message}`));
66
+ if (issues.length > 0 || !compatibility.valid) {
67
+ return {
68
+ consumerStage,
69
+ foundationStage,
70
+ issues: [...new Set(issues)],
71
+ ok: false,
72
+ region: options.region,
73
+ state: allRequiredParametersMissing ? 'absent' : 'invalid',
74
+ };
75
+ }
76
+ return {
77
+ discovery: {
78
+ alertTopicArn: value('alertTopicArn'),
79
+ capabilities: compatibility.value.capabilities,
80
+ clusterId: value('clusterId'),
81
+ contractVersion: compatibility.value.contractVersion,
82
+ databaseClusterArn: value('databaseClusterArn'),
83
+ databaseClusterId: value('databaseClusterId'),
84
+ databaseMasterSecretArn: value('databaseMasterSecretArn'),
85
+ eventBusArn: value('eventBusArn'),
86
+ eventBusName: value('eventBusName'),
87
+ hasPublicDomain: value('hasPublicDomain') === 'true',
88
+ identityUserPoolArn: value('identityUserPoolArn'),
89
+ identityUserPoolId: value('identityUserPoolId'),
90
+ rootDomain: value('rootDomain') === 'none' ? undefined : value('rootDomain'),
91
+ routerDistributionId: value('routerDistributionId'),
92
+ routerUrl: value('routerUrl'),
93
+ schemaVersion: discovery_js_1.FOUNDATION_SSM_SCHEMA_VERSION,
94
+ vpcId: value('vpcId'),
95
+ },
96
+ consumerStage,
97
+ foundationStage,
98
+ issues: [],
99
+ ok: true,
100
+ region: options.region,
101
+ state: 'ready',
102
+ };
103
+ }
104
+ function formatFoundationPreflightReport(report) {
105
+ const lines = [
106
+ `[foundation-preflight] consumerStage=${report.consumerStage} foundationStage=${report.foundationStage} region=${report.region}: ${report.ok ? 'ready' : 'NOT ready'}`,
107
+ ];
108
+ report.issues.forEach((issue) => lines.push(` - ${issue}`));
109
+ if (!report.ok) {
110
+ lines.push(` Deploy the Foundation first: pnpm nx run foundation:deploy --stage=${report.foundationStage}`);
111
+ }
112
+ return lines.join('\n');
113
+ }
114
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/preflight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type LogicalDatabaseIdentifiers } from './local-database-contract.js';
2
+ import { type FoundationInfrastructure, type ProvisionLogicalDatabaseOptions, type ProvisionLogicalDatabaseResult } from './provision-logical-database.js';
3
+ export interface DatabaseBinding {
4
+ active: string;
5
+ provisioned: readonly string[];
6
+ }
7
+ export type DatabaseBindingDeclaration = Readonly<Record<string, DatabaseBinding>>;
8
+ export interface DatabaseBindingPlan {
9
+ active: Readonly<Record<string, string>>;
10
+ identifiers: Readonly<Record<string, LogicalDatabaseIdentifiers>>;
11
+ provisioned: readonly string[];
12
+ }
13
+ export interface ProvisionDatabaseBindingsOptions {
14
+ bindings: DatabaseBindingDeclaration;
15
+ localDev?: boolean;
16
+ localDevPassword?: string;
17
+ removalPolicy?: ProvisionLogicalDatabaseOptions['removalPolicy'];
18
+ rotationTokens?: Readonly<Record<string, string>>;
19
+ slice: string;
20
+ }
21
+ export type ProvisionedDatabaseBindings<TBindings extends DatabaseBindingDeclaration> = {
22
+ [TBinding in keyof TBindings]: ProvisionLogicalDatabaseResult;
23
+ };
24
+ export declare function createDatabaseBindingPlan(bindings: DatabaseBindingDeclaration, context: {
25
+ slice: string;
26
+ stage: string;
27
+ }): DatabaseBindingPlan;
28
+ export declare function provisionDatabaseBindings<TBindings extends DatabaseBindingDeclaration>(foundation: FoundationInfrastructure, options: ProvisionDatabaseBindingsOptions & {
29
+ bindings: TBindings;
30
+ }): ProvisionedDatabaseBindings<TBindings>;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDatabaseBindingPlan = createDatabaseBindingPlan;
4
+ exports.provisionDatabaseBindings = provisionDatabaseBindings;
5
+ const local_database_contract_js_1 = require("./local-database-contract.js");
6
+ const provision_logical_database_js_1 = require("./provision-logical-database.js");
7
+ const databaseIdentifierPattern = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/;
8
+ function collisionKey(value) {
9
+ return (0, local_database_contract_js_1.normalizePostgresIdentifier)(value).normalize('NFKC').toLowerCase();
10
+ }
11
+ function createDatabaseBindingPlan(bindings, context) {
12
+ if (typeof bindings !== 'object' ||
13
+ bindings === null ||
14
+ Array.isArray(bindings)) {
15
+ throw new Error('Database bindings must be an object.');
16
+ }
17
+ const entries = Object.entries(bindings);
18
+ if (entries.length === 0) {
19
+ throw new Error('Database bindings must declare at least one stable role.');
20
+ }
21
+ const active = {};
22
+ const identifiers = {};
23
+ const declared = new Set();
24
+ const normalized = new Map();
25
+ const componentNames = new Map();
26
+ for (const [role, binding] of entries) {
27
+ if (!/^[a-z][a-z0-9-]*$/.test(role)) {
28
+ throw new Error(`Database binding role "${role}" must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens.`);
29
+ }
30
+ if (typeof binding !== 'object' ||
31
+ binding === null ||
32
+ Array.isArray(binding)) {
33
+ throw new Error(`Database binding "${role}" must be an object.`);
34
+ }
35
+ const unexpectedMembers = Object.keys(binding).filter((key) => key !== 'active' && key !== 'provisioned');
36
+ if (unexpectedMembers.length > 0) {
37
+ throw new Error(`Database binding "${role}" contains unsupported member${unexpectedMembers.length === 1 ? '' : 's'}: ${unexpectedMembers.join(', ')}. Only active and provisioned are allowed.`);
38
+ }
39
+ if (typeof binding.active !== 'string' || binding.active.trim() === '') {
40
+ throw new Error(`Database binding "${role}" must select a non-empty active identifier.`);
41
+ }
42
+ if (!Array.isArray(binding.provisioned) ||
43
+ binding.provisioned.length === 0) {
44
+ throw new Error(`Database binding "${role}" must provision at least one identifier.`);
45
+ }
46
+ if (!binding.provisioned.includes(binding.active)) {
47
+ throw new Error(`Database binding "${role}" selects "${binding.active}", but that identifier is not provisioned.`);
48
+ }
49
+ active[role] = binding.active;
50
+ for (const identifier of binding.provisioned) {
51
+ if (typeof identifier !== 'string' || identifier.trim() === '') {
52
+ throw new Error(`Database binding "${role}" contains an invalid empty identifier.`);
53
+ }
54
+ if (!databaseIdentifierPattern.test(identifier)) {
55
+ throw new Error(`Database identifier "${identifier}" must start with a lowercase letter and contain only lowercase letters, numbers, single hyphens, or single underscores.`);
56
+ }
57
+ if (declared.has(identifier)) {
58
+ throw new Error(`Database identifier "${identifier}" is declared more than once. Each provisioned identifier must be unique across the binding set.`);
59
+ }
60
+ const resolved = (0, local_database_contract_js_1.resolveLogicalDatabaseIdentifiers)({
61
+ database: identifier,
62
+ slice: context.slice,
63
+ stage: context.stage,
64
+ });
65
+ const key = collisionKey(resolved.database);
66
+ const previous = normalized.get(key);
67
+ if (previous !== undefined) {
68
+ throw new Error(`Database identifiers "${previous}" and "${identifier}" collide after PostgreSQL normalization. Rename one identifier; EBK never truncates or aliases database bindings.`);
69
+ }
70
+ const componentName = (0, provision_logical_database_js_1.defaultDatabaseLinkableName)(context.slice, identifier);
71
+ const previousComponent = componentNames.get(componentName);
72
+ if (previousComponent !== undefined) {
73
+ throw new Error(`Database identifiers "${previousComponent}" and "${identifier}" collide after SST logical-name normalization as "${componentName}". Rename one identifier so every resource name is unique before deployment.`);
74
+ }
75
+ declared.add(identifier);
76
+ normalized.set(key, identifier);
77
+ componentNames.set(componentName, identifier);
78
+ identifiers[identifier] = resolved;
79
+ }
80
+ }
81
+ return {
82
+ active,
83
+ identifiers,
84
+ provisioned: [...declared],
85
+ };
86
+ }
87
+ function provisionDatabaseBindings(foundation, options) {
88
+ // Validate the complete set before the first provisioner call. This is what
89
+ // makes a collision or overlong identifier fail before any local Linkable,
90
+ // Pulumi dynamic resource, Secrets Manager secret, or SQL mutation exists.
91
+ const plan = createDatabaseBindingPlan(options.bindings, {
92
+ slice: options.slice,
93
+ stage: $app.stage,
94
+ });
95
+ const provisioned = new Map();
96
+ for (const database of plan.provisioned) {
97
+ provisioned.set(database, (0, provision_logical_database_js_1.provisionLogicalDatabase)(foundation, {
98
+ database,
99
+ localDev: options.localDev,
100
+ localDevPassword: options.localDevPassword,
101
+ removalPolicy: options.removalPolicy,
102
+ ...(options.rotationTokens?.[database] !== undefined
103
+ ? { rotationToken: options.rotationTokens[database] }
104
+ : {}),
105
+ slice: options.slice,
106
+ }));
107
+ }
108
+ return Object.fromEntries(Object.entries(plan.active).map(([role, database]) => [
109
+ role,
110
+ provisioned.get(database),
111
+ ]));
112
+ }
113
+ //# sourceMappingURL=provision-database-bindings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision-database-bindings.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/provision-database-bindings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface FoundationDatabaseCapacity {
2
+ cluster: any;
3
+ clusterArn: string;
4
+ masterSecretArn: string;
5
+ }
6
+ export interface FoundationInfrastructure {
7
+ database: FoundationDatabaseCapacity;
8
+ }
9
+ export interface ProvisionLogicalDatabaseOptions {
10
+ slice: string;
11
+ database: string;
12
+ localDev?: boolean;
13
+ localDevPassword?: string;
14
+ localDevPort?: number;
15
+ linkableName?: string;
16
+ removalPolicy?: 'retain' | 'destroy';
17
+ rotationToken?: string;
18
+ }
19
+ export interface ProvisionLogicalDatabaseResult {
20
+ db: any;
21
+ logicalDb?: any;
22
+ readwriteSecretArn?: any;
23
+ readonlySecretArn?: any;
24
+ }
25
+ export declare function defaultDatabaseLinkableName(slice: string, database: string): string;
26
+ export declare function provisionLogicalDatabase(foundation: FoundationInfrastructure, options: ProvisionLogicalDatabaseOptions): ProvisionLogicalDatabaseResult;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultDatabaseLinkableName = defaultDatabaseLinkableName;
4
+ exports.provisionLogicalDatabase = provisionLogicalDatabase;
5
+ const aurora_logical_database_js_1 = require("./aurora-logical-database.js");
6
+ const local_database_contract_js_1 = require("./local-database-contract.js");
7
+ function classNameForDatabaseComponent(value) {
8
+ // 'example-primary' -> 'ExamplePrimary'. Simple normalizer; the db
9
+ // generator always passes already-kebab-cased segments.
10
+ return value
11
+ .split(/[-_]/)
12
+ .filter(Boolean)
13
+ .map((p) => p.charAt(0).toUpperCase() + p.slice(1))
14
+ .join('');
15
+ }
16
+ function defaultDatabaseLinkableName(slice, database) {
17
+ return `${classNameForDatabaseComponent(slice)}${classNameForDatabaseComponent(database)}Database`;
18
+ }
19
+ // Carves out an app-scoped logical database on the shared `CoreDb` Aurora
20
+ // cluster. Creates:
21
+ // * `<app>_<database>` logical Postgres database on the shared cluster
22
+ // * `<app>_readwrite` role (full DML + DDL) + `<app>_readonly` role (SELECT only)
23
+ // * AWS Secrets Manager secrets for each role at
24
+ // `ebk/<stage>/<slice>/database/<database>/<access-mode>` with JSON
25
+ // `{ host, port, database, username, password }`
26
+ // * An `sst.Linkable` exposing the readwrite credentials — consumers link
27
+ // this into their Nextjs / Service / Function stacks so runtime code sees
28
+ // `Resource.<Linkable>.host/port/database/username/password` unchanged
29
+ //
30
+ // Passwords are generated inside the `AuroraLogicalDb` dynamic resource via
31
+ // Node `crypto.randomBytes` and persisted in Pulumi state, so no
32
+ // `@pulumi/random` dep is needed. They are never rotated automatically —
33
+ // change `rotationToken` to rotate on the next deploy (see the rotation
34
+ // runbook in this package's README).
35
+ //
36
+ // DO NOT pass `core.db.cluster` (the raw Aurora handle) into
37
+ // `new sst.aws.Nextjs({ link })` — that leaks the master password. This
38
+ // helper is the sanctioned consumer path.
39
+ function provisionLogicalDatabase(foundation, options) {
40
+ // Resolve and validate every deployed and local PostgreSQL identifier before
41
+ // constructing an SST Linkable, Pulumi dynamic resource, or AWS secret.
42
+ // PostgreSQL truncates overlong identifiers by default; EBK fails instead so
43
+ // two declarations can never alias silently.
44
+ const identifiers = (0, local_database_contract_js_1.resolveLogicalDatabaseIdentifiers)({
45
+ database: options.database,
46
+ slice: options.slice,
47
+ stage: $app.stage,
48
+ });
49
+ const linkableName = options.linkableName ??
50
+ defaultDatabaseLinkableName(options.slice, options.database);
51
+ // Local live mode needs only the workload-facing Linkable. Return before
52
+ // constructing the Pulumi dynamic resource or either Secrets Manager secret
53
+ // so `sst dev` does not provision unused AWS database resources merely to
54
+ // point the application at Docker Postgres.
55
+ if ($dev && (options.localDev ?? true)) {
56
+ const localDatabase = (0, local_database_contract_js_1.resolveLocalDatabaseContract)({
57
+ database: options.database,
58
+ password: options.localDevPassword,
59
+ port: options.localDevPort,
60
+ slice: options.slice,
61
+ });
62
+ return {
63
+ db: new sst.Linkable(linkableName, {
64
+ properties: localDatabase,
65
+ }),
66
+ };
67
+ }
68
+ // `<consumer_stage>_<app>_<database>` — scoped by the CONSUMER stage, not
69
+ // core's. Personal/preview stages (`pr-123`, `lukas`) share the shared
70
+ // development cluster via `EBK_CORE_STAGE=development` for cost, but their
71
+ // data MUST be isolated from every other stage's. Without stage-scoping, two stages
72
+ // pointing at the same core would stomp on each other's database rows and
73
+ // rotate each other's passwords via the retained-role `ALTER ROLE` path.
74
+ // Hyphens become underscores because Postgres identifiers reject `-`.
75
+ const databaseIdentifier = identifiers.database;
76
+ const readwriteRole = identifiers.readwriteRole;
77
+ const readonlyRole = identifiers.readonlyRole;
78
+ // Default removal policy depends on stage. Canonical persistent stages
79
+ // (development/staging/production) retain data — destroying a consumer stack
80
+ // shouldn't nuke anything anyone cares about. Ephemeral stages (preview
81
+ // `pr-123`, personal `lukas`, etc.) destroy — every such stage creates
82
+ // its own stage-scoped logical DB, and leaving it behind after the
83
+ // preview is torn down would leak Aurora state + roles forever.
84
+ // Callers can override explicitly via `options.removalPolicy`.
85
+ const canonicalStages = new Set(['development', 'staging', 'production']);
86
+ const defaultRemovalPolicy = canonicalStages.has($app.stage)
87
+ ? 'retain'
88
+ : 'destroy';
89
+ const logicalDb = (0, aurora_logical_database_js_1.createAuroraLogicalDbResource)({
90
+ name: linkableName,
91
+ args: {
92
+ clusterArn: foundation.database.clusterArn,
93
+ masterSecretArn: foundation.database.masterSecretArn,
94
+ database: databaseIdentifier,
95
+ readwriteRole,
96
+ readonlyRole,
97
+ removalPolicy: options.removalPolicy ?? defaultRemovalPolicy,
98
+ // Only include the rotation trigger when the caller set one — keeping
99
+ // the key out of the inputs entirely when unset avoids a spurious
100
+ // `undefined` diff against resources created before this option existed.
101
+ ...(options.rotationToken !== undefined
102
+ ? { rotationToken: options.rotationToken }
103
+ : {}),
104
+ },
105
+ });
106
+ // `core.db.cluster.host` auto-resolves to the proxy endpoint when proxy is
107
+ // enabled (production) or the cluster writer endpoint otherwise.
108
+ // `core.db.cluster.port` similarly resolves to either the proxy port or the
109
+ // cluster port.
110
+ const host = foundation.database.cluster.host;
111
+ const port = foundation.database.cluster.port;
112
+ // Outputs from the dynamic resource — Pulumi unwraps them on link.
113
+ const readwritePassword = logicalDb.readwritePassword;
114
+ const readonlyPassword = logicalDb.readonlyPassword;
115
+ const secretJsonFor = (role, password) => $interpolate `{"host":"${host}","port":${port},"database":"${databaseIdentifier}","username":"${role}","password":"${password}"}`;
116
+ // Secret paths are keyed by the CONSUMER's stage, not core's. Two stages
117
+ // pointing at the same core via `EBK_CORE_STAGE` (e.g. `pr-123` → `development`)
118
+ // would otherwise collide on `ebk/development/<app>/db/<db>/...`. Keying by
119
+ // `$app.stage` isolates each consumer's secret namespace while the actual
120
+ // cluster remains shared.
121
+ const secretBasePath = `ebk/${$app.stage}/${options.slice}/database/${options.database}`;
122
+ // `recoveryWindowInDays: 0` skips the default 7-day soft-delete window.
123
+ // Destroy frees the secret name immediately so a subsequent create (or a
124
+ // redeploy after `sst remove`) doesn't hit `InvalidRequestException:
125
+ // ...already scheduled for deletion`. App-scoped DB role credentials are
126
+ // regenerated on every create() anyway — a recovery window serves no
127
+ // purpose here.
128
+ const readwriteSecret = new aws.secretsmanager.Secret(`${linkableName}ReadwriteSecret`, {
129
+ name: `${secretBasePath}/readwrite`,
130
+ recoveryWindowInDays: 0,
131
+ }, { dependsOn: logicalDb });
132
+ const readwriteSecretVersion = new aws.secretsmanager.SecretVersion(`${linkableName}ReadwriteSecretVersion`, {
133
+ secretId: readwriteSecret.id,
134
+ secretString: secretJsonFor(readwriteRole, readwritePassword),
135
+ });
136
+ const readonlySecret = new aws.secretsmanager.Secret(`${linkableName}ReadonlySecret`, {
137
+ name: `${secretBasePath}/readonly`,
138
+ recoveryWindowInDays: 0,
139
+ }, { dependsOn: logicalDb });
140
+ const readonlySecretVersion = new aws.secretsmanager.SecretVersion(`${linkableName}ReadonlySecretVersion`, {
141
+ secretId: readonlySecret.id,
142
+ secretString: secretJsonFor(readonlyRole, readonlyPassword),
143
+ });
144
+ const linkable = new sst.Linkable(linkableName, {
145
+ properties: {
146
+ host,
147
+ port,
148
+ database: databaseIdentifier,
149
+ username: readwriteRole,
150
+ password: $util.secret(readwritePassword),
151
+ },
152
+ });
153
+ // Touch the version refs so Pulumi tracks them + keep them alive in GC.
154
+ void readwriteSecretVersion;
155
+ void readonlySecretVersion;
156
+ return {
157
+ db: linkable,
158
+ logicalDb,
159
+ readwriteSecretArn: readwriteSecret.arn,
160
+ readonlySecretArn: readonlySecret.arn,
161
+ };
162
+ }
163
+ //# sourceMappingURL=provision-logical-database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision-logical-database.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/provision-logical-database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { type ValidationResult } from '../validation.js';
2
+ export declare const STANDARD_FOUNDATION_CONTRACT_VERSION: 1;
3
+ export declare const STANDARD_FOUNDATION_CAPABILITIES: readonly ["network", "routing", "container-compute", "postgres", "identity", "events", "observability", "configuration", "deployment"];
4
+ export type StandardFoundationCapability = (typeof STANDARD_FOUNDATION_CAPABILITIES)[number];
5
+ export interface FoundationRequirement {
6
+ capabilities: StandardFoundationCapability[];
7
+ contract: string;
8
+ }
9
+ export interface FoundationDescriptor {
10
+ capabilities: StandardFoundationCapability[];
11
+ contractVersion: string;
12
+ }
13
+ export declare function isStandardFoundationCapability(value: unknown): value is StandardFoundationCapability;
14
+ export declare function validateFoundationRequirement(value: unknown, path?: string): ValidationResult<FoundationRequirement>;
15
+ export declare function validateFoundationCompatibility(requirement: unknown, foundation: unknown): ValidationResult<FoundationDescriptor>;
16
+ export declare const foundationRequirementSchema: {
17
+ readonly $id: "https://empirebuilderkit.dev/schemas/foundation-requirement-v1.json";
18
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
19
+ readonly additionalProperties: false;
20
+ readonly properties: {
21
+ readonly capabilities: {
22
+ readonly items: {
23
+ readonly enum: readonly ["network", "routing", "container-compute", "postgres", "identity", "events", "observability", "configuration", "deployment"];
24
+ readonly type: "string";
25
+ };
26
+ readonly type: "array";
27
+ readonly uniqueItems: true;
28
+ };
29
+ readonly contract: {
30
+ readonly minLength: 1;
31
+ readonly type: "string";
32
+ };
33
+ };
34
+ readonly required: readonly ["contract", "capabilities"];
35
+ readonly title: "Empire Builder Kit Standard Foundation Requirement v1";
36
+ readonly type: "object";
37
+ };