@fjall/generator 0.88.4 → 0.89.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/src/ast/astCdnParser.d.ts +15 -0
- package/dist/src/ast/astCdnParser.js +114 -0
- package/dist/src/ast/astCommonParser.d.ts +90 -0
- package/dist/src/ast/astCommonParser.js +351 -0
- package/dist/src/ast/astComputeParser.d.ts +14 -2
- package/dist/src/ast/astComputeParser.js +55 -9
- package/dist/src/ast/astDatabaseParser.d.ts +104 -0
- package/dist/src/ast/astDatabaseParser.js +275 -0
- package/dist/src/ast/astInfrastructureParser.d.ts +23 -277
- package/dist/src/ast/astInfrastructureParser.js +83 -1456
- package/dist/src/ast/astMessagingParser.d.ts +25 -0
- package/dist/src/ast/astMessagingParser.js +78 -0
- package/dist/src/ast/astNetworkParser.d.ts +70 -0
- package/dist/src/ast/astNetworkParser.js +219 -0
- package/dist/src/ast/astPatternParser.d.ts +80 -0
- package/dist/src/ast/astPatternParser.js +155 -0
- package/dist/src/ast/astStorageParser.d.ts +18 -0
- package/dist/src/ast/astStorageParser.js +164 -0
- package/dist/src/ast/index.d.ts +1 -0
- package/dist/src/ast/index.js +4 -0
- package/dist/src/dns/bindParser.d.ts +13 -0
- package/dist/src/dns/bindParser.js +224 -0
- package/dist/src/dns/bindWriter.d.ts +2 -0
- package/dist/src/dns/bindWriter.js +52 -0
- package/dist/src/dns/index.d.ts +4 -0
- package/dist/src/dns/index.js +4 -0
- package/dist/src/dns/infrastructureWriter.d.ts +2 -0
- package/dist/src/dns/infrastructureWriter.js +58 -0
- package/dist/src/dns/types.d.ts +82 -0
- package/dist/src/dns/types.js +52 -0
- package/dist/src/generation/common.d.ts +1 -16
- package/dist/src/generation/common.js +2 -28
- package/dist/src/generation/compute.js +77 -28
- package/dist/src/generation/index.d.ts +2 -1
- package/dist/src/generation/index.js +3 -1
- package/dist/src/generation/messagingConnections.d.ts +33 -0
- package/dist/src/generation/messagingConnections.js +73 -0
- package/dist/src/generation/storage.d.ts +5 -1
- package/dist/src/generation/storage.js +9 -1
- package/dist/src/generation/storageConnections.d.ts +3 -3
- package/dist/src/generation/storageConnections.js +8 -4
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/planning/resourcePlanning.js +0 -2
- package/dist/src/presets/tierTypes.d.ts +4 -1
- package/dist/src/schemas/applicationSchemas.d.ts +854 -0
- package/dist/src/schemas/applicationSchemas.js +80 -0
- package/dist/src/schemas/baseSchemas.d.ts +206 -0
- package/dist/src/schemas/baseSchemas.js +248 -0
- package/dist/src/schemas/cdnSchemas.d.ts +61 -0
- package/dist/src/schemas/cdnSchemas.js +62 -0
- package/dist/src/schemas/computeSchemas.d.ts +723 -0
- package/dist/src/schemas/computeSchemas.js +727 -0
- package/dist/src/schemas/constants.d.ts +12 -8
- package/dist/src/schemas/constants.js +14 -4
- package/dist/src/schemas/databaseSchemas.d.ts +638 -0
- package/dist/src/schemas/databaseSchemas.js +366 -0
- package/dist/src/schemas/messagingSchemas.d.ts +20 -0
- package/dist/src/schemas/messagingSchemas.js +29 -0
- package/dist/src/schemas/networkSchemas.d.ts +246 -0
- package/dist/src/schemas/networkSchemas.js +125 -0
- package/dist/src/schemas/patternSchemas.d.ts +708 -0
- package/dist/src/schemas/patternSchemas.js +294 -0
- package/dist/src/schemas/resourceSchemas.d.ts +24 -3530
- package/dist/src/schemas/resourceSchemas.js +24 -2011
- package/dist/src/schemas/storageSchemas.d.ts +93 -0
- package/dist/src/schemas/storageSchemas.js +119 -0
- package/dist/src/util/errorUtils.d.ts +1 -2
- package/dist/src/util/errorUtils.js +1 -15
- package/dist/src/validation/patterns.d.ts +9 -0
- package/dist/src/validation/patterns.js +9 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +5 -3
|
@@ -5,26 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { IdentifierValue, ExpressionValue, CallValue, SpecialValue } from "../schemas/resourceSchemas.js";
|
|
7
7
|
export type { IdentifierValue, ExpressionValue, CallValue, SpecialValue };
|
|
8
|
+
export { toPascalCase, toKebab, toValidDatabaseName } from "@fjall/util";
|
|
8
9
|
/**
|
|
9
10
|
* Type guard to check if a value is a special code generation value
|
|
10
11
|
*/
|
|
11
12
|
export declare function isSpecialValue(value: unknown): value is SpecialValue;
|
|
12
|
-
/**
|
|
13
|
-
* Convert hyphenated/underscored names to PascalCase for resource names
|
|
14
|
-
*/
|
|
15
|
-
export declare function toPascalCase(str: string): string;
|
|
16
|
-
/**
|
|
17
|
-
* Convert any case (PascalCase, camelCase, kebab-case, snake_case) to kebab-case.
|
|
18
|
-
* Three-pass regex: split acronyms, split camel boundaries, replace separators.
|
|
19
|
-
* e.g., "MyApp" -> "my-app", "AWSLambda" -> "aws-lambda", "myApp" -> "my-app"
|
|
20
|
-
*/
|
|
21
|
-
export declare function toKebab(str: string): string;
|
|
22
|
-
/**
|
|
23
|
-
* Convert a name to a valid RDS database name (snake_case).
|
|
24
|
-
* RDS API allows letters, numbers, and underscores for PostgreSQL/MySQL DatabaseName.
|
|
25
|
-
* Hyphens are rejected, so convert them to underscores.
|
|
26
|
-
*/
|
|
27
|
-
export declare function toValidDatabaseName(name: string): string;
|
|
28
13
|
/**
|
|
29
14
|
* Convert resource names to camelCase variable names
|
|
30
15
|
*/
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Shared helper functions used across all generation modules.
|
|
5
5
|
*/
|
|
6
|
+
// Re-export case conversion functions from @fjall/util for backwards compatibility
|
|
7
|
+
export { toPascalCase, toKebab, toValidDatabaseName } from "@fjall/util";
|
|
6
8
|
/**
|
|
7
9
|
* Type guard to check if a value is a special code generation value
|
|
8
10
|
*/
|
|
@@ -15,34 +17,6 @@ export function isSpecialValue(value) {
|
|
|
15
17
|
typeof obj.__expression === "string" ||
|
|
16
18
|
typeof obj.__call === "string");
|
|
17
19
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Convert hyphenated/underscored names to PascalCase for resource names
|
|
20
|
-
*/
|
|
21
|
-
export function toPascalCase(str) {
|
|
22
|
-
return str
|
|
23
|
-
.replace(/[-_](.)/g, (_, c) => c.toUpperCase())
|
|
24
|
-
.replace(/^./, (c) => c.toUpperCase());
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Convert any case (PascalCase, camelCase, kebab-case, snake_case) to kebab-case.
|
|
28
|
-
* Three-pass regex: split acronyms, split camel boundaries, replace separators.
|
|
29
|
-
* e.g., "MyApp" -> "my-app", "AWSLambda" -> "aws-lambda", "myApp" -> "my-app"
|
|
30
|
-
*/
|
|
31
|
-
export function toKebab(str) {
|
|
32
|
-
return str
|
|
33
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2")
|
|
34
|
-
.replace(/([a-z\d])([A-Z])/g, "$1-$2")
|
|
35
|
-
.replace(/[\s_]+/g, "-")
|
|
36
|
-
.toLowerCase();
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Convert a name to a valid RDS database name (snake_case).
|
|
40
|
-
* RDS API allows letters, numbers, and underscores for PostgreSQL/MySQL DatabaseName.
|
|
41
|
-
* Hyphens are rejected, so convert them to underscores.
|
|
42
|
-
*/
|
|
43
|
-
export function toValidDatabaseName(name) {
|
|
44
|
-
return toKebab(name).replace(/-/g, "_");
|
|
45
|
-
}
|
|
46
20
|
/**
|
|
47
21
|
* Convert resource names to camelCase variable names
|
|
48
22
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { formatValue, getVariableName, emitExtraProperties } from "./common.js";
|
|
2
2
|
import { DATABASE_ENV_VARS, getConnectedDatabases, generateDatabaseEnvVarEntries, buildDatabaseEnvVars, } from "./database.js";
|
|
3
3
|
import { STORAGE_ENV_VARS, getConnectedStorage, generateStorageEnvVarEntries, buildStorageEnvVars, formatAllConnectionsCode, } from "./storageConnections.js";
|
|
4
|
+
import { MESSAGING_ENV_VARS, getConnectedMessaging, generateMessagingEnvVarEntries, buildMessagingEnvVars, } from "./messagingConnections.js";
|
|
4
5
|
import { COMPUTE_TYPE, DEPLOYMENT_TYPE, DEFAULT_COMPUTE_ARCHITECTURE, } from "../schemas/constants.js";
|
|
5
6
|
/** Check if a compute resource has database connections */
|
|
6
7
|
function computeHasDatabaseConnections(compute) {
|
|
@@ -10,10 +11,15 @@ function computeHasDatabaseConnections(compute) {
|
|
|
10
11
|
function computeHasStorageConnections(compute) {
|
|
11
12
|
return Boolean(compute.connectedStorage?.length);
|
|
12
13
|
}
|
|
13
|
-
/** Check if a compute resource has
|
|
14
|
+
/** Check if a compute resource has messaging connections */
|
|
15
|
+
function computeHasMessagingConnections(compute) {
|
|
16
|
+
return Boolean(compute.connectedMessaging?.length);
|
|
17
|
+
}
|
|
18
|
+
/** Check if a compute resource has any connections (database, storage, or messaging) */
|
|
14
19
|
function computeHasConnections(compute) {
|
|
15
20
|
return (computeHasDatabaseConnections(compute) ||
|
|
16
|
-
computeHasStorageConnections(compute)
|
|
21
|
+
computeHasStorageConnections(compute) ||
|
|
22
|
+
computeHasMessagingConnections(compute));
|
|
17
23
|
}
|
|
18
24
|
const BASE_ENVIRONMENT_VARS = {
|
|
19
25
|
ENVIRONMENT: { __expression: "getConfig().environment" },
|
|
@@ -106,7 +112,8 @@ export function generateLambdaConnectionsCode(compute, plan) {
|
|
|
106
112
|
return "";
|
|
107
113
|
const hasDatabaseConnections = computeHasDatabaseConnections(compute);
|
|
108
114
|
const hasStorageConns = computeHasStorageConnections(compute);
|
|
109
|
-
|
|
115
|
+
const hasMessagingConns = computeHasMessagingConnections(compute);
|
|
116
|
+
if (!hasDatabaseConnections && !hasStorageConns && !hasMessagingConns)
|
|
110
117
|
return "";
|
|
111
118
|
const connectedDatabases = hasDatabaseConnections
|
|
112
119
|
? getConnectedDatabases(plan, compute)
|
|
@@ -114,7 +121,12 @@ export function generateLambdaConnectionsCode(compute, plan) {
|
|
|
114
121
|
const connectedStorage = hasStorageConns
|
|
115
122
|
? getConnectedStorage(plan, compute)
|
|
116
123
|
: [];
|
|
117
|
-
|
|
124
|
+
const connectedMessaging = hasMessagingConns
|
|
125
|
+
? getConnectedMessaging(plan, compute)
|
|
126
|
+
: [];
|
|
127
|
+
if (connectedDatabases.length === 0 &&
|
|
128
|
+
connectedStorage.length === 0 &&
|
|
129
|
+
connectedMessaging.length === 0) {
|
|
118
130
|
return "";
|
|
119
131
|
}
|
|
120
132
|
// All env/secret values are stored as typed objects so formatValue handles
|
|
@@ -146,6 +158,13 @@ export function generateLambdaConnectionsCode(compute, plan) {
|
|
|
146
158
|
envVars[entry.key] = { __expression: entry.expression };
|
|
147
159
|
}
|
|
148
160
|
}
|
|
161
|
+
// Messaging env vars (no secrets — SQS uses IAM)
|
|
162
|
+
if (connectedMessaging.length > 0) {
|
|
163
|
+
const entries = generateMessagingEnvVarEntries(connectedMessaging);
|
|
164
|
+
for (const entry of entries) {
|
|
165
|
+
envVars[entry.key] = { __expression: entry.expression };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
149
168
|
// Merge compute.environment values directly — formatValue handles all types
|
|
150
169
|
if (compute.environment) {
|
|
151
170
|
for (const [key, value] of Object.entries(compute.environment)) {
|
|
@@ -175,7 +194,7 @@ export function generateLambdaConnectionsCode(compute, plan) {
|
|
|
175
194
|
},`;
|
|
176
195
|
}
|
|
177
196
|
code += `
|
|
178
|
-
${formatAllConnectionsCode(connectedDatabases, connectedStorage)}`;
|
|
197
|
+
${formatAllConnectionsCode(connectedDatabases, connectedStorage, connectedMessaging)}`;
|
|
179
198
|
return code;
|
|
180
199
|
}
|
|
181
200
|
export function generateEc2Code(compute) {
|
|
@@ -218,7 +237,7 @@ function generateEcsClusterCode(compute) {
|
|
|
218
237
|
cluster: {${inner}
|
|
219
238
|
},`;
|
|
220
239
|
}
|
|
221
|
-
function generateEcsContainerCode(containerConfig, shouldAddConnectionEnv, dbEnvVars, storageEnvVars, baseEnvVars) {
|
|
240
|
+
function generateEcsContainerCode(containerConfig, shouldAddConnectionEnv, dbEnvVars, storageEnvVars, messagingEnvVars, baseEnvVars) {
|
|
222
241
|
let code = "";
|
|
223
242
|
if (containerConfig.name) {
|
|
224
243
|
code += `
|
|
@@ -252,6 +271,8 @@ function generateEcsContainerCode(containerConfig, shouldAddConnectionEnv, dbEnv
|
|
|
252
271
|
DATABASE_ENV_VARS.USERNAME,
|
|
253
272
|
DATABASE_ENV_VARS.PASSWORD,
|
|
254
273
|
STORAGE_ENV_VARS.NAME,
|
|
274
|
+
MESSAGING_ENV_VARS.URL,
|
|
275
|
+
MESSAGING_ENV_VARS.ARN,
|
|
255
276
|
];
|
|
256
277
|
const stripConnectionEnv = (env) => {
|
|
257
278
|
if (!env)
|
|
@@ -272,6 +293,7 @@ function generateEcsContainerCode(containerConfig, shouldAddConnectionEnv, dbEnv
|
|
|
272
293
|
...baseEnvVars,
|
|
273
294
|
...dbEnvVars.env,
|
|
274
295
|
...storageEnvVars.env,
|
|
296
|
+
...messagingEnvVars.env,
|
|
275
297
|
...containerConfig.environment,
|
|
276
298
|
}
|
|
277
299
|
: { ...baseEnvVars, ...stripConnectionEnv(containerConfig.environment) };
|
|
@@ -364,8 +386,22 @@ function generateEcsServiceScalingCode(scaling) {
|
|
|
364
386
|
scaling: {${inner}
|
|
365
387
|
},`;
|
|
366
388
|
}
|
|
389
|
+
/** Derive which connection types a service needs (DRY — used for both container env and service-level connections) */
|
|
390
|
+
function deriveServiceConnectionNeeds(service, isFirstService, compute) {
|
|
391
|
+
return {
|
|
392
|
+
needsDb: service.needsDatabaseConnection !== undefined
|
|
393
|
+
? service.needsDatabaseConnection
|
|
394
|
+
: isFirstService && computeHasDatabaseConnections(compute),
|
|
395
|
+
needsStorage: service.needsStorageConnection !== undefined
|
|
396
|
+
? service.needsStorageConnection
|
|
397
|
+
: isFirstService && computeHasStorageConnections(compute),
|
|
398
|
+
needsMessaging: service.needsMessagingConnection !== undefined
|
|
399
|
+
? service.needsMessagingConnection
|
|
400
|
+
: isFirstService && computeHasMessagingConnections(compute),
|
|
401
|
+
};
|
|
402
|
+
}
|
|
367
403
|
function generateEcsServiceCode(options) {
|
|
368
|
-
const { service, isFirstService, hasConnections, dbEnvVars, storageEnvVars, baseEnvVars, plan, compute, } = options;
|
|
404
|
+
const { service, isFirstService, hasConnections, dbEnvVars, storageEnvVars, messagingEnvVars, baseEnvVars, plan, compute, } = options;
|
|
369
405
|
let code = `
|
|
370
406
|
name: "${service.name}",`;
|
|
371
407
|
code += `
|
|
@@ -390,6 +426,7 @@ function generateEcsServiceCode(options) {
|
|
|
390
426
|
code += `
|
|
391
427
|
ssmSecretsPath: "${service.ssmSecretsPath}",`;
|
|
392
428
|
}
|
|
429
|
+
const connectionNeeds = deriveServiceConnectionNeeds(service, isFirstService, compute);
|
|
393
430
|
if (service.containers?.length) {
|
|
394
431
|
code += `
|
|
395
432
|
containers: [{`;
|
|
@@ -397,25 +434,26 @@ function generateEcsServiceCode(options) {
|
|
|
397
434
|
const container = service.containers[i];
|
|
398
435
|
if (!container)
|
|
399
436
|
continue;
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
: isFirstService && computeHasStorageConnections(compute);
|
|
406
|
-
const shouldAddConnectionEnv = i === 0 && (serviceNeedsDb || serviceNeedsStorage) && hasConnections;
|
|
437
|
+
const shouldAddConnectionEnv = i === 0 &&
|
|
438
|
+
(connectionNeeds.needsDb ||
|
|
439
|
+
connectionNeeds.needsStorage ||
|
|
440
|
+
connectionNeeds.needsMessaging) &&
|
|
441
|
+
hasConnections;
|
|
407
442
|
// Build per-container env vars: only include the connection types this service needs
|
|
408
|
-
const containerDbEnvVars =
|
|
443
|
+
const containerDbEnvVars = connectionNeeds.needsDb
|
|
409
444
|
? dbEnvVars
|
|
410
445
|
: { env: {}, secrets: {} };
|
|
411
|
-
const containerStorageEnvVars =
|
|
446
|
+
const containerStorageEnvVars = connectionNeeds.needsStorage
|
|
412
447
|
? storageEnvVars
|
|
413
448
|
: { env: {}, secrets: {} };
|
|
449
|
+
const containerMessagingEnvVars = connectionNeeds.needsMessaging
|
|
450
|
+
? messagingEnvVars
|
|
451
|
+
: { env: {}, secrets: {} };
|
|
414
452
|
if (i > 0) {
|
|
415
453
|
code += `
|
|
416
454
|
}, {`;
|
|
417
455
|
}
|
|
418
|
-
code += generateEcsContainerCode(container, shouldAddConnectionEnv, containerDbEnvVars, containerStorageEnvVars, baseEnvVars);
|
|
456
|
+
code += generateEcsContainerCode(container, shouldAddConnectionEnv, containerDbEnvVars, containerStorageEnvVars, containerMessagingEnvVars, baseEnvVars);
|
|
419
457
|
}
|
|
420
458
|
code += `
|
|
421
459
|
}],`;
|
|
@@ -439,22 +477,23 @@ function generateEcsServiceCode(options) {
|
|
|
439
477
|
code += generateEcsServiceScalingCode(service.scaling);
|
|
440
478
|
}
|
|
441
479
|
code += emitExtraProperties(service.extraProperties, " ");
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
? service.needsStorageConnection
|
|
447
|
-
: isFirstService && computeHasStorageConnections(compute);
|
|
448
|
-
if (serviceNeedsDbConnection || serviceNeedsStorageConnection) {
|
|
449
|
-
const connectedDatabases = serviceNeedsDbConnection
|
|
480
|
+
if (connectionNeeds.needsDb ||
|
|
481
|
+
connectionNeeds.needsStorage ||
|
|
482
|
+
connectionNeeds.needsMessaging) {
|
|
483
|
+
const connectedDatabases = connectionNeeds.needsDb
|
|
450
484
|
? getConnectedDatabases(plan, compute)
|
|
451
485
|
: [];
|
|
452
|
-
const connectedStorage =
|
|
486
|
+
const connectedStorage = connectionNeeds.needsStorage
|
|
453
487
|
? getConnectedStorage(plan, compute)
|
|
454
488
|
: [];
|
|
455
|
-
|
|
489
|
+
const connectedMessaging = connectionNeeds.needsMessaging
|
|
490
|
+
? getConnectedMessaging(plan, compute)
|
|
491
|
+
: [];
|
|
492
|
+
if (connectedDatabases.length > 0 ||
|
|
493
|
+
connectedStorage.length > 0 ||
|
|
494
|
+
connectedMessaging.length > 0) {
|
|
456
495
|
code += `
|
|
457
|
-
${formatAllConnectionsCode(connectedDatabases, connectedStorage)}`;
|
|
496
|
+
${formatAllConnectionsCode(connectedDatabases, connectedStorage, connectedMessaging)}`;
|
|
458
497
|
}
|
|
459
498
|
}
|
|
460
499
|
return code;
|
|
@@ -483,6 +522,15 @@ export function generateEcsCode(compute, plan) {
|
|
|
483
522
|
const builtStorageEnvVars = buildStorageEnvVars(plan, compute);
|
|
484
523
|
Object.assign(storageEnvVars.env, builtStorageEnvVars.env);
|
|
485
524
|
}
|
|
525
|
+
// Messaging env vars (no secrets — SQS uses IAM)
|
|
526
|
+
const messagingEnvVars = {
|
|
527
|
+
env: {},
|
|
528
|
+
secrets: {},
|
|
529
|
+
};
|
|
530
|
+
if (computeHasMessagingConnections(compute)) {
|
|
531
|
+
const builtMessagingEnvVars = buildMessagingEnvVars(plan, compute);
|
|
532
|
+
Object.assign(messagingEnvVars.env, builtMessagingEnvVars.env);
|
|
533
|
+
}
|
|
486
534
|
let code = `
|
|
487
535
|
ecrRepository: app.getDefaultContainerRegistry(),`;
|
|
488
536
|
code += generateEcsClusterCode(compute);
|
|
@@ -503,6 +551,7 @@ export function generateEcsCode(compute, plan) {
|
|
|
503
551
|
hasConnections: !!hasConnections,
|
|
504
552
|
dbEnvVars,
|
|
505
553
|
storageEnvVars,
|
|
554
|
+
messagingEnvVars,
|
|
506
555
|
baseEnvVars,
|
|
507
556
|
plan,
|
|
508
557
|
compute,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
export { type IdentifierValue, type ExpressionValue, type CallValue, type SpecialValue, isSpecialValue, toPascalCase, toKebab, toValidDatabaseName, toVariableName, formatValue, buildProperty, getVariableName, resolveResourceVariable, emitExtraProperties, } from "./common.js";
|
|
8
8
|
export { DATABASE_ENV_VARS, CREDENTIAL_KEYS, type DatabaseEnvVarEntry, type DatabaseEnvVars, getConnectedDatabases, generateDatabaseEnvVarEntries, formatConnectionsCode, buildDatabaseEnvVars, databaseNeedsVariable, generateDatabaseCode, } from "./database.js";
|
|
9
9
|
export { STORAGE_ENV_VARS, type StorageEnvVarEntry, type StorageEnvVars, getConnectedStorage, generateStorageEnvVarEntries, buildStorageEnvVars, formatAllConnectionsCode, } from "./storageConnections.js";
|
|
10
|
+
export { MESSAGING_ENV_VARS, type MessagingEnvVarEntry, type MessagingEnvVars, getConnectedMessaging, generateMessagingEnvVarEntries, buildMessagingEnvVars, } from "./messagingConnections.js";
|
|
10
11
|
export { generateLambdaCode, generateLambdaConnectionsCode, generateEc2Code, generateEcsCode, generateComputeCode, } from "./compute.js";
|
|
11
|
-
export { generateS3Code, generateDynamoDBCode, generateSQSCode, s3NeedsVariable, } from "./storage.js";
|
|
12
|
+
export { generateS3Code, generateDynamoDBCode, generateSQSCode, s3NeedsVariable, sqsNeedsVariable, } from "./storage.js";
|
|
12
13
|
export { generateNetworkCode, generateTags, generateAppInit, generateImports, generateCDNCode, collectCdnReferencedResources, usesPatternApproach, generatePatternCodeWithComments, } from "./infrastructure.js";
|
|
@@ -10,9 +10,11 @@ export { isSpecialValue, toPascalCase, toKebab, toValidDatabaseName, toVariableN
|
|
|
10
10
|
export { DATABASE_ENV_VARS, CREDENTIAL_KEYS, getConnectedDatabases, generateDatabaseEnvVarEntries, formatConnectionsCode, buildDatabaseEnvVars, databaseNeedsVariable, generateDatabaseCode, } from "./database.js";
|
|
11
11
|
// Storage connections
|
|
12
12
|
export { STORAGE_ENV_VARS, getConnectedStorage, generateStorageEnvVarEntries, buildStorageEnvVars, formatAllConnectionsCode, } from "./storageConnections.js";
|
|
13
|
+
// Messaging connections
|
|
14
|
+
export { MESSAGING_ENV_VARS, getConnectedMessaging, generateMessagingEnvVarEntries, buildMessagingEnvVars, } from "./messagingConnections.js";
|
|
13
15
|
// Compute generation
|
|
14
16
|
export { generateLambdaCode, generateLambdaConnectionsCode, generateEc2Code, generateEcsCode, generateComputeCode, } from "./compute.js";
|
|
15
17
|
// Storage generation
|
|
16
|
-
export { generateS3Code, generateDynamoDBCode, generateSQSCode, s3NeedsVariable, } from "./storage.js";
|
|
18
|
+
export { generateS3Code, generateDynamoDBCode, generateSQSCode, s3NeedsVariable, sqsNeedsVariable, } from "./storage.js";
|
|
17
19
|
// Infrastructure generation
|
|
18
20
|
export { generateNetworkCode, generateTags, generateAppInit, generateImports, generateCDNCode, collectCdnReferencedResources, usesPatternApproach, generatePatternCodeWithComments, } from "./infrastructure.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messaging Connection Code Generation
|
|
3
|
+
*
|
|
4
|
+
* Functions for generating messaging connection code (env vars, connections array)
|
|
5
|
+
* following the same pattern as database and storage connections.
|
|
6
|
+
*/
|
|
7
|
+
import type { SQSResourcePlan, ApplicationResourcePlan, ComputeResourcePlan } from "../schemas/resourceSchemas.js";
|
|
8
|
+
export declare const MESSAGING_ENV_VARS: Readonly<{
|
|
9
|
+
readonly URL: "QUEUE_URL";
|
|
10
|
+
readonly ARN: "QUEUE_ARN";
|
|
11
|
+
}>;
|
|
12
|
+
export type MessagingEnvVarEntry = {
|
|
13
|
+
key: string;
|
|
14
|
+
expression: string;
|
|
15
|
+
};
|
|
16
|
+
export interface MessagingEnvVars {
|
|
17
|
+
env: Record<string, unknown>;
|
|
18
|
+
secrets: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get SQS queues connected to a compute resource
|
|
22
|
+
*/
|
|
23
|
+
export declare function getConnectedMessaging(plan: ApplicationResourcePlan, compute: ComputeResourcePlan): SQSResourcePlan[];
|
|
24
|
+
/**
|
|
25
|
+
* Generate messaging environment variable entries for a list of connected queues.
|
|
26
|
+
* SQS uses IAM-based access, so there are no secrets — only QUEUE_URL and QUEUE_ARN env vars.
|
|
27
|
+
*/
|
|
28
|
+
export declare function generateMessagingEnvVarEntries(connectedMessaging: SQSResourcePlan[]): MessagingEnvVarEntry[];
|
|
29
|
+
/**
|
|
30
|
+
* Build messaging environment variables for a compute resource.
|
|
31
|
+
* SQS always uses IAM — secrets is always empty.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildMessagingEnvVars(plan: ApplicationResourcePlan, compute: ComputeResourcePlan): MessagingEnvVars;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messaging Connection Code Generation
|
|
3
|
+
*
|
|
4
|
+
* Functions for generating messaging connection code (env vars, connections array)
|
|
5
|
+
* following the same pattern as database and storage connections.
|
|
6
|
+
*/
|
|
7
|
+
import { getVariableName } from "./common.js";
|
|
8
|
+
export const MESSAGING_ENV_VARS = Object.freeze({
|
|
9
|
+
URL: "QUEUE_URL",
|
|
10
|
+
ARN: "QUEUE_ARN",
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Get SQS queues connected to a compute resource
|
|
14
|
+
*/
|
|
15
|
+
export function getConnectedMessaging(plan, compute) {
|
|
16
|
+
const { connectedMessaging } = compute;
|
|
17
|
+
if (!connectedMessaging?.length)
|
|
18
|
+
return [];
|
|
19
|
+
return (plan.sqs ?? []).filter((queue) => connectedMessaging.includes(queue.name));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generate messaging environment variable entries for a list of connected queues.
|
|
23
|
+
* SQS uses IAM-based access, so there are no secrets — only QUEUE_URL and QUEUE_ARN env vars.
|
|
24
|
+
*/
|
|
25
|
+
export function generateMessagingEnvVarEntries(connectedMessaging) {
|
|
26
|
+
const entries = [];
|
|
27
|
+
if (connectedMessaging.length === 1) {
|
|
28
|
+
const queue = connectedMessaging[0];
|
|
29
|
+
if (!queue)
|
|
30
|
+
return entries;
|
|
31
|
+
const queueVar = getVariableName(queue);
|
|
32
|
+
entries.push({
|
|
33
|
+
key: MESSAGING_ENV_VARS.URL,
|
|
34
|
+
expression: `${queueVar}.getQueueUrl()`,
|
|
35
|
+
});
|
|
36
|
+
entries.push({
|
|
37
|
+
key: MESSAGING_ENV_VARS.ARN,
|
|
38
|
+
expression: `${queueVar}.getQueueArn()`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
for (const [index, queue] of connectedMessaging.entries()) {
|
|
43
|
+
const queueVar = getVariableName(queue);
|
|
44
|
+
const suffix = index === 0 ? "" : `_${index + 1}`;
|
|
45
|
+
entries.push({
|
|
46
|
+
key: `${MESSAGING_ENV_VARS.URL}${suffix}`,
|
|
47
|
+
expression: `${queueVar}.getQueueUrl()`,
|
|
48
|
+
});
|
|
49
|
+
entries.push({
|
|
50
|
+
key: `${MESSAGING_ENV_VARS.ARN}${suffix}`,
|
|
51
|
+
expression: `${queueVar}.getQueueArn()`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return entries;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build messaging environment variables for a compute resource.
|
|
59
|
+
* SQS always uses IAM — secrets is always empty.
|
|
60
|
+
*/
|
|
61
|
+
export function buildMessagingEnvVars(plan, compute) {
|
|
62
|
+
const env = {};
|
|
63
|
+
const secrets = {};
|
|
64
|
+
if (!compute.connectedMessaging?.length) {
|
|
65
|
+
return { env, secrets };
|
|
66
|
+
}
|
|
67
|
+
const connectedMessaging = getConnectedMessaging(plan, compute);
|
|
68
|
+
const entries = generateMessagingEnvVarEntries(connectedMessaging);
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
env[entry.key] = { __expression: entry.expression };
|
|
71
|
+
}
|
|
72
|
+
return { env, secrets };
|
|
73
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Functions for generating storage infrastructure code including
|
|
5
5
|
* S3 buckets, DynamoDB tables, and SQS queues.
|
|
6
6
|
*/
|
|
7
|
-
import type { ApplicationResourcePlan, S3ResourcePlan } from "../schemas/resourceSchemas.js";
|
|
7
|
+
import type { ApplicationResourcePlan, S3ResourcePlan, SQSResourcePlan } from "../schemas/resourceSchemas.js";
|
|
8
8
|
/**
|
|
9
9
|
* Check if an S3 bucket needs a variable assignment (referenced by compute or CDN)
|
|
10
10
|
*/
|
|
@@ -17,6 +17,10 @@ export declare function generateS3Code(plan: ApplicationResourcePlan): string;
|
|
|
17
17
|
* Generate DynamoDB table infrastructure code
|
|
18
18
|
*/
|
|
19
19
|
export declare function generateDynamoDBCode(plan: ApplicationResourcePlan): string;
|
|
20
|
+
/**
|
|
21
|
+
* Check if an SQS queue needs a variable assignment (referenced by compute)
|
|
22
|
+
*/
|
|
23
|
+
export declare function sqsNeedsVariable(queue: SQSResourcePlan, plan: ApplicationResourcePlan): boolean;
|
|
20
24
|
/**
|
|
21
25
|
* Generate SQS queue infrastructure code
|
|
22
26
|
*/
|
|
@@ -138,6 +138,12 @@ const ${tableVariable} = app.addDatabase(
|
|
|
138
138
|
}
|
|
139
139
|
return code;
|
|
140
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Check if an SQS queue needs a variable assignment (referenced by compute)
|
|
143
|
+
*/
|
|
144
|
+
export function sqsNeedsVariable(queue, plan) {
|
|
145
|
+
return plan.compute.some((compute) => compute.connectedMessaging?.includes(queue.name));
|
|
146
|
+
}
|
|
141
147
|
/**
|
|
142
148
|
* Generate SQS queue infrastructure code
|
|
143
149
|
*/
|
|
@@ -147,8 +153,10 @@ export function generateSQSCode(plan) {
|
|
|
147
153
|
let code = "";
|
|
148
154
|
for (const queue of plan.sqs) {
|
|
149
155
|
const queueVariable = getVariableName(queue);
|
|
156
|
+
const hasReferences = sqsNeedsVariable(queue, plan);
|
|
157
|
+
const prefix = hasReferences ? `const ${queueVariable} = ` : "";
|
|
150
158
|
code += `
|
|
151
|
-
|
|
159
|
+
${prefix}app.addMessaging(
|
|
152
160
|
MessagingFactory.build("${queue.name}", {
|
|
153
161
|
type: "queue",
|
|
154
162
|
queueType: "${queue.queueType}"`;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Functions for generating storage connection code (env vars, connections array)
|
|
5
5
|
* following the same pattern as database connections.
|
|
6
6
|
*/
|
|
7
|
-
import type { S3ResourcePlan, ApplicationResourcePlan, ComputeResourcePlan, DatabaseResourcePlan } from "../schemas/resourceSchemas.js";
|
|
7
|
+
import type { S3ResourcePlan, SQSResourcePlan, ApplicationResourcePlan, ComputeResourcePlan, DatabaseResourcePlan } from "../schemas/resourceSchemas.js";
|
|
8
8
|
export declare const STORAGE_ENV_VARS: Readonly<{
|
|
9
9
|
readonly NAME: "BUCKET_NAME";
|
|
10
10
|
}>;
|
|
@@ -32,6 +32,6 @@ export declare function generateStorageEnvVarEntries(connectedStorage: S3Resourc
|
|
|
32
32
|
export declare function buildStorageEnvVars(plan: ApplicationResourcePlan, compute: ComputeResourcePlan): StorageEnvVars;
|
|
33
33
|
/**
|
|
34
34
|
* Format combined connections array for generated infrastructure code.
|
|
35
|
-
* Merges
|
|
35
|
+
* Merges database, storage, and messaging variable names into a single connections line.
|
|
36
36
|
*/
|
|
37
|
-
export declare function formatAllConnectionsCode(connectedDatabases: DatabaseResourcePlan[], connectedStorage: S3ResourcePlan[]): string;
|
|
37
|
+
export declare function formatAllConnectionsCode(connectedDatabases: DatabaseResourcePlan[], connectedStorage: S3ResourcePlan[], connectedMessaging?: SQSResourcePlan[]): string;
|
|
@@ -24,7 +24,10 @@ export function getConnectedStorage(plan, compute) {
|
|
|
24
24
|
export function generateStorageEnvVarEntries(connectedStorage) {
|
|
25
25
|
const entries = [];
|
|
26
26
|
if (connectedStorage.length === 1) {
|
|
27
|
-
const
|
|
27
|
+
const bucket = connectedStorage[0];
|
|
28
|
+
if (!bucket)
|
|
29
|
+
return entries;
|
|
30
|
+
const bucketVar = getVariableName(bucket);
|
|
28
31
|
entries.push({
|
|
29
32
|
key: STORAGE_ENV_VARS.NAME,
|
|
30
33
|
expression: `${bucketVar}.getBucketName()`,
|
|
@@ -61,11 +64,12 @@ export function buildStorageEnvVars(plan, compute) {
|
|
|
61
64
|
}
|
|
62
65
|
/**
|
|
63
66
|
* Format combined connections array for generated infrastructure code.
|
|
64
|
-
* Merges
|
|
67
|
+
* Merges database, storage, and messaging variable names into a single connections line.
|
|
65
68
|
*/
|
|
66
|
-
export function formatAllConnectionsCode(connectedDatabases, connectedStorage) {
|
|
69
|
+
export function formatAllConnectionsCode(connectedDatabases, connectedStorage, connectedMessaging = []) {
|
|
67
70
|
const dbVars = connectedDatabases.map((db) => getVariableName(db));
|
|
68
71
|
const storageVars = connectedStorage.map((b) => getVariableName(b));
|
|
69
|
-
const
|
|
72
|
+
const messagingVars = connectedMessaging.map((q) => getVariableName(q));
|
|
73
|
+
const allVars = [...dbVars, ...storageVars, ...messagingVars].join(", ");
|
|
70
74
|
return `connections: [${allVars}],`;
|
|
71
75
|
}
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -17,7 +17,6 @@ export function planApplicationResources(appName, appType, includeDatabase = tru
|
|
|
17
17
|
database: [],
|
|
18
18
|
s3: [],
|
|
19
19
|
compute: [],
|
|
20
|
-
importedResources: [],
|
|
21
20
|
};
|
|
22
21
|
if (appType === "custom") {
|
|
23
22
|
return basePlan;
|
|
@@ -136,7 +135,6 @@ export function planOpenNextResources(appName, pattern, options) {
|
|
|
136
135
|
s3: [],
|
|
137
136
|
compute: [],
|
|
138
137
|
tags: tags ?? {},
|
|
139
|
-
importedResources: [],
|
|
140
138
|
});
|
|
141
139
|
}
|
|
142
140
|
function mergeDatabaseConfig(database, tierPreset) {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* consumers. Extracted from tierPresets.ts for maintainability.
|
|
6
6
|
*/
|
|
7
7
|
import type { EcsCapacityProvider, BackupVaultTier } from "../schemas/constants.js";
|
|
8
|
+
import type { WarmPool } from "../schemas/computeSchemas.js";
|
|
8
9
|
/**
|
|
9
10
|
* Proxy configuration for tier presets
|
|
10
11
|
* Presence = enabled. Use `false` to explicitly disable.
|
|
@@ -105,7 +106,7 @@ export interface DatabaseTierPreset {
|
|
|
105
106
|
* Only applies when capacityProvider is "EC2".
|
|
106
107
|
*/
|
|
107
108
|
export interface TierEc2CapacityConfig {
|
|
108
|
-
/** EC2 instance type. Default: "
|
|
109
|
+
/** EC2 instance type. Default: "t4g.micro" */
|
|
109
110
|
instanceType?: string;
|
|
110
111
|
/** AMI hardware type. Default: "ARM" for cost efficiency */
|
|
111
112
|
amiHardwareType?: "ARM" | "STANDARD";
|
|
@@ -115,6 +116,8 @@ export interface TierEc2CapacityConfig {
|
|
|
115
116
|
maxCapacity?: number;
|
|
116
117
|
/** Memory limit for container in MiB. Default: 400 */
|
|
117
118
|
memoryLimitMiB?: number;
|
|
119
|
+
/** Warm pool configuration for faster instance start times. */
|
|
120
|
+
warmPool?: WarmPool;
|
|
118
121
|
}
|
|
119
122
|
/**
|
|
120
123
|
* Cluster configuration for ECS tier presets.
|