@fjall/generator 0.89.5 → 0.89.6
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 +50 -21
- package/README.md +28 -0
- package/dist/.minified +1 -0
- package/dist/src/ast/astCdnParser.d.ts +5 -0
- package/dist/src/ast/astCdnParser.js +1 -114
- package/dist/src/ast/astCommonParser.d.ts +6 -17
- package/dist/src/ast/astCommonParser.js +1 -351
- package/dist/src/ast/astComputeConnectionParser.d.ts +18 -0
- package/dist/src/ast/astComputeConnectionParser.js +1 -0
- package/dist/src/ast/astComputeParser.d.ts +6 -0
- package/dist/src/ast/astComputeParser.js +1 -473
- package/dist/src/ast/astComputeParserHelpers.d.ts +21 -0
- package/dist/src/ast/astComputeParserHelpers.js +1 -0
- package/dist/src/ast/astDatabaseParser.d.ts +9 -24
- package/dist/src/ast/astDatabaseParser.js +1 -275
- package/dist/src/ast/astDomainParser.d.ts +139 -0
- package/dist/src/ast/astDomainParser.js +1 -0
- package/dist/src/ast/astDynamoDBParser.d.ts +35 -0
- package/dist/src/ast/astDynamoDBParser.js +1 -0
- package/dist/src/ast/astExpressionEvaluator.d.ts +23 -0
- package/dist/src/ast/astExpressionEvaluator.js +1 -0
- package/dist/src/ast/astInfrastructureParser.d.ts +12 -49
- package/dist/src/ast/astInfrastructureParser.js +1 -552
- package/dist/src/ast/astMessagingParser.d.ts +5 -0
- package/dist/src/ast/astMessagingParser.js +1 -78
- package/dist/src/ast/astNetworkParser.d.ts +6 -0
- package/dist/src/ast/astNetworkParser.js +1 -219
- package/dist/src/ast/astPatternParser.d.ts +6 -0
- package/dist/src/ast/astPatternParser.js +1 -155
- package/dist/src/ast/astPlanConverter.d.ts +11 -0
- package/dist/src/ast/astPlanConverter.js +2 -0
- package/dist/src/ast/astStatementClassifier.d.ts +24 -0
- package/dist/src/ast/astStatementClassifier.js +1 -0
- package/dist/src/ast/astStatementQueries.d.ts +21 -0
- package/dist/src/ast/astStatementQueries.js +3 -0
- package/dist/src/ast/astStorageParser.d.ts +5 -0
- package/dist/src/ast/astStorageParser.js +1 -164
- package/dist/src/ast/astSurgicalModification.js +19 -400
- package/dist/src/ast/astTestHelpers.d.ts +635 -0
- package/dist/src/ast/astTestHelpers.js +1 -0
- package/dist/src/ast/index.d.ts +1 -0
- package/dist/src/ast/index.js +1 -6
- package/dist/src/aws/regions.js +1 -254
- package/dist/src/codemod/_internal.d.ts +12 -0
- package/dist/src/codemod/_internal.js +1 -0
- package/dist/src/codemod/edits/addResource/bodyIndex.d.ts +34 -0
- package/dist/src/codemod/edits/addResource/bodyIndex.js +1 -0
- package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +7 -0
- package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -0
- package/dist/src/codemod/edits/addResource.d.ts +9 -0
- package/dist/src/codemod/edits/addResource.js +1 -0
- package/dist/src/codemod/edits/ensureImports.d.ts +26 -0
- package/dist/src/codemod/edits/ensureImports.js +1 -0
- package/dist/src/codemod/edits/findInsertionPosition.d.ts +39 -0
- package/dist/src/codemod/edits/findInsertionPosition.js +1 -0
- package/dist/src/codemod/edits/index.d.ts +6 -0
- package/dist/src/codemod/edits/index.js +1 -0
- package/dist/src/codemod/edits/modifyResource/literalConversion.d.ts +37 -0
- package/dist/src/codemod/edits/modifyResource/literalConversion.js +1 -0
- package/dist/src/codemod/edits/modifyResource.d.ts +9 -0
- package/dist/src/codemod/edits/modifyResource.js +1 -0
- package/dist/src/codemod/edits/removeResource/commentHeuristic.d.ts +31 -0
- package/dist/src/codemod/edits/removeResource/commentHeuristic.js +1 -0
- package/dist/src/codemod/edits/removeResource/importPruning.d.ts +8 -0
- package/dist/src/codemod/edits/removeResource/importPruning.js +1 -0
- package/dist/src/codemod/edits/removeResource.d.ts +10 -0
- package/dist/src/codemod/edits/removeResource.js +1 -0
- package/dist/src/codemod/edits/schemaFragments.d.ts +9 -0
- package/dist/src/codemod/edits/schemaFragments.js +1 -0
- package/dist/src/codemod/fileRewriter/builders.d.ts +57 -0
- package/dist/src/codemod/fileRewriter/builders.js +1 -0
- package/dist/src/codemod/fileRewriter/index.d.ts +4 -0
- package/dist/src/codemod/fileRewriter/index.js +1 -0
- package/dist/src/codemod/fileRewriter/locateByRange.d.ts +65 -0
- package/dist/src/codemod/fileRewriter/locateByRange.js +1 -0
- package/dist/src/codemod/fileRewriter/parse.d.ts +18 -0
- package/dist/src/codemod/fileRewriter/parse.js +2 -0
- package/dist/src/codemod/fileRewriter/print.d.ts +46 -0
- package/dist/src/codemod/fileRewriter/print.js +4 -0
- package/dist/src/codemod/historyPaths.d.ts +2 -0
- package/dist/src/codemod/historyPaths.js +1 -0
- package/dist/src/codemod/index.d.ts +7 -0
- package/dist/src/codemod/index.js +1 -0
- package/dist/src/codemod/listResources.d.ts +4 -0
- package/dist/src/codemod/listResources.js +1 -0
- package/dist/src/codemod/semanticIndex/findReferences.d.ts +15 -0
- package/dist/src/codemod/semanticIndex/findReferences.js +2 -0
- package/dist/src/codemod/semanticIndex/index.d.ts +4 -0
- package/dist/src/codemod/semanticIndex/index.js +1 -0
- package/dist/src/codemod/semanticIndex/listImports.d.ts +24 -0
- package/dist/src/codemod/semanticIndex/listImports.js +1 -0
- package/dist/src/codemod/semanticIndex/locateByShape.d.ts +28 -0
- package/dist/src/codemod/semanticIndex/locateByShape.js +1 -0
- package/dist/src/codemod/semanticIndex/projectCache.d.ts +14 -0
- package/dist/src/codemod/semanticIndex/projectCache.js +1 -0
- package/dist/src/codemod/types.d.ts +172 -0
- package/dist/src/codemod/types.js +1 -0
- package/dist/src/dns/bindParser.js +2 -224
- package/dist/src/dns/bindWriter.js +3 -52
- package/dist/src/dns/domainFileGenerator.d.ts +20 -0
- package/dist/src/dns/domainFileGenerator.js +207 -0
- package/dist/src/dns/domainRecords.d.ts +164 -0
- package/dist/src/dns/domainRecords.js +1 -0
- package/dist/src/dns/index.d.ts +2 -1
- package/dist/src/dns/index.js +1 -4
- package/dist/src/dns/types.js +1 -52
- package/dist/src/generation/common.js +6 -161
- package/dist/src/generation/compute.js +82 -590
- package/dist/src/generation/database.js +12 -198
- package/dist/src/generation/generatePatternCode.d.ts +58 -0
- package/dist/src/generation/generatePatternCode.js +33 -0
- package/dist/src/generation/index.js +1 -20
- package/dist/src/generation/infrastructure.d.ts +1 -5
- package/dist/src/generation/infrastructure.js +35 -377
- package/dist/src/generation/messagingConnections.js +1 -73
- package/dist/src/generation/storage.d.ts +0 -15
- package/dist/src/generation/storage.js +35 -168
- package/dist/src/generation/storageConnections.js +1 -75
- package/dist/src/planning/generateResourceChange.d.ts +21 -0
- package/dist/src/planning/generateResourceChange.js +1 -0
- package/dist/src/planning/index.d.ts +3 -0
- package/dist/src/planning/index.js +1 -1
- package/dist/src/planning/resourceAddition.d.ts +154 -0
- package/dist/src/planning/resourceAddition.js +1 -0
- package/dist/src/planning/resourceConnections.d.ts +19 -0
- package/dist/src/planning/resourceConnections.js +1 -0
- package/dist/src/planning/resourcePlanning.js +1 -214
- package/dist/src/presets/index.js +1 -3
- package/dist/src/presets/patternTierPresets.js +1 -131
- package/dist/src/presets/storagePresets.js +1 -36
- package/dist/src/presets/tierPresets.d.ts +5 -8
- package/dist/src/presets/tierPresets.js +1 -384
- package/dist/src/presets/tierTypes.d.ts +1 -1
- package/dist/src/presets/tierTypes.js +0 -7
- package/dist/src/schemas/alarmSchemas.d.ts +19 -0
- package/dist/src/schemas/alarmSchemas.js +1 -0
- package/dist/src/schemas/applicationSchemas.d.ts +22 -6
- package/dist/src/schemas/applicationSchemas.js +1 -80
- package/dist/src/schemas/baseSchemas.d.ts +8 -3
- package/dist/src/schemas/baseSchemas.js +2 -248
- package/dist/src/schemas/cdnSchemas.js +1 -62
- package/dist/src/schemas/computeSchemas.d.ts +25 -3
- package/dist/src/schemas/computeSchemas.js +1 -727
- package/dist/src/schemas/constants.d.ts +5 -7
- package/dist/src/schemas/constants.js +1 -218
- package/dist/src/schemas/databaseSchemas.d.ts +6 -1
- package/dist/src/schemas/databaseSchemas.js +1 -366
- package/dist/src/schemas/index.js +1 -3
- package/dist/src/schemas/instanceTypeArchitecture.js +1 -75
- package/dist/src/schemas/messagingSchemas.js +1 -29
- package/dist/src/schemas/networkSchemas.js +1 -125
- package/dist/src/schemas/patternSchemas.d.ts +1 -1
- package/dist/src/schemas/patternSchemas.js +1 -294
- package/dist/src/schemas/resourceSchemas.d.ts +1 -0
- package/dist/src/schemas/resourceSchemas.js +1 -28
- package/dist/src/schemas/sharedTypes.d.ts +18 -0
- package/dist/src/schemas/sharedTypes.js +1 -0
- package/dist/src/schemas/storageSchemas.d.ts +1 -0
- package/dist/src/schemas/storageSchemas.js +1 -119
- package/dist/src/types/Result.js +1 -31
- package/dist/src/util/errorUtils.js +1 -1
- package/dist/src/validation/patterns.d.ts +9 -0
- package/dist/src/validation/patterns.js +1 -369
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +29 -9
- package/dist/src/dns/infrastructureWriter.d.ts +0 -2
- package/dist/src/dns/infrastructureWriter.js +0 -58
|
@@ -1,473 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { isPlainObject, isParsedObject, isIdentifierRef, isExpressionRef, isCallRef, asString, asNumber, asBoolean, asStringArray, asStringUnion, captureExtraProperties, collectFromAst, extractVariableName, isFactoryBuildCall, isFactoryMethodCall, parseObjectLiteral, } from "./astCommonParser.js";
|
|
3
|
-
import { COMPUTE_TYPES, DEPLOYMENT_TYPES, EC2_INSTANCE_TYPES, ECS_CAPACITY_PROVIDERS, } from "../schemas/constants.js";
|
|
4
|
-
// ---- Extraction helpers ----
|
|
5
|
-
function extractComputeResource(buildCall) {
|
|
6
|
-
if (buildCall.arguments.length < 2)
|
|
7
|
-
return null;
|
|
8
|
-
const nameArg = buildCall.arguments[0];
|
|
9
|
-
const configArg = buildCall.arguments[1];
|
|
10
|
-
if (!ts.isStringLiteral(nameArg) ||
|
|
11
|
-
!ts.isObjectLiteralExpression(configArg)) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const resourceName = nameArg.text;
|
|
15
|
-
const config = parseObjectLiteral(configArg);
|
|
16
|
-
return {
|
|
17
|
-
resourceName,
|
|
18
|
-
type: asString(config.type) ?? "ecs",
|
|
19
|
-
config,
|
|
20
|
-
node: buildCall,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
/** Find all compute resources from addCompute calls */
|
|
24
|
-
export function findComputeResources(sourceFile) {
|
|
25
|
-
return collectFromAst(sourceFile, (node) => {
|
|
26
|
-
if (!ts.isCallExpression(node) || !isFactoryMethodCall(node, "addCompute"))
|
|
27
|
-
return null;
|
|
28
|
-
const computeArg = node.arguments[0];
|
|
29
|
-
if (!isFactoryBuildCall(computeArg, "ComputeFactory"))
|
|
30
|
-
return null;
|
|
31
|
-
const resource = extractComputeResource(computeArg);
|
|
32
|
-
if (resource) {
|
|
33
|
-
const varName = extractVariableName(node);
|
|
34
|
-
if (varName)
|
|
35
|
-
resource.variableName = varName;
|
|
36
|
-
}
|
|
37
|
-
return resource;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
// ---- Internal helpers ----
|
|
41
|
-
const MAX_DATABASE_CONNECTION_INDICES = 10;
|
|
42
|
-
const LOAD_BALANCER_TYPES = ["public", "internal"];
|
|
43
|
-
function isEnvironmentRecord(value) {
|
|
44
|
-
return value !== undefined && isPlainObject(value);
|
|
45
|
-
}
|
|
46
|
-
function parseContainerSecretsImport(secretsImportValue) {
|
|
47
|
-
if (!isParsedObject(secretsImportValue))
|
|
48
|
-
return undefined;
|
|
49
|
-
const result = {};
|
|
50
|
-
for (const [key, val] of Object.entries(secretsImportValue)) {
|
|
51
|
-
if (isParsedObject(val)) {
|
|
52
|
-
const id = asString(val.id);
|
|
53
|
-
const name = asString(val.name);
|
|
54
|
-
if (id && name) {
|
|
55
|
-
result[key] = { id, name, field: asString(val.field) };
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return Object.keys(result).length > 0 ? result : undefined;
|
|
60
|
-
}
|
|
61
|
-
function parseContainerHealthCheck(healthCheckValue) {
|
|
62
|
-
if (!isParsedObject(healthCheckValue))
|
|
63
|
-
return undefined;
|
|
64
|
-
const cmd = asStringArray(healthCheckValue.command);
|
|
65
|
-
if (!cmd || cmd.length === 0)
|
|
66
|
-
return undefined;
|
|
67
|
-
return {
|
|
68
|
-
command: cmd,
|
|
69
|
-
interval: asNumber(healthCheckValue.interval),
|
|
70
|
-
timeout: asNumber(healthCheckValue.timeout),
|
|
71
|
-
retries: asNumber(healthCheckValue.retries),
|
|
72
|
-
startPeriod: asNumber(healthCheckValue.startPeriod),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function parseServiceContainer(c) {
|
|
76
|
-
const CONTAINER_KNOWN_KEYS = new Set([
|
|
77
|
-
"name",
|
|
78
|
-
"image",
|
|
79
|
-
"port",
|
|
80
|
-
"environment",
|
|
81
|
-
"essential",
|
|
82
|
-
"command",
|
|
83
|
-
"entryPoint",
|
|
84
|
-
"secretsImport",
|
|
85
|
-
"secrets",
|
|
86
|
-
"healthCheck",
|
|
87
|
-
]);
|
|
88
|
-
const extras = captureExtraProperties(c, CONTAINER_KNOWN_KEYS);
|
|
89
|
-
return {
|
|
90
|
-
name: asString(c.name),
|
|
91
|
-
image: asString(c.image),
|
|
92
|
-
port: asNumber(c.port),
|
|
93
|
-
environment: isEnvironmentRecord(c.environment) ? c.environment : undefined,
|
|
94
|
-
essential: asBoolean(c.essential),
|
|
95
|
-
command: asStringArray(c.command),
|
|
96
|
-
entryPoint: asStringArray(c.entryPoint),
|
|
97
|
-
secretsImport: parseContainerSecretsImport(c.secretsImport),
|
|
98
|
-
ssmSecrets: asStringArray(c.secrets),
|
|
99
|
-
healthCheck: parseContainerHealthCheck(c.healthCheck),
|
|
100
|
-
extraProperties: extras.length > 0 ? extras : undefined,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
function parseServiceRouting(routingVal) {
|
|
104
|
-
if (Array.isArray(routingVal)) {
|
|
105
|
-
return routingVal.filter(isParsedObject).map((rule) => ({
|
|
106
|
-
path: asString(rule.path),
|
|
107
|
-
host: asString(rule.host),
|
|
108
|
-
priority: asNumber(rule.priority),
|
|
109
|
-
healthCheckPath: asString(rule.healthCheckPath),
|
|
110
|
-
}));
|
|
111
|
-
}
|
|
112
|
-
if (!isParsedObject(routingVal))
|
|
113
|
-
return undefined;
|
|
114
|
-
return {
|
|
115
|
-
path: asString(routingVal.path),
|
|
116
|
-
host: asString(routingVal.host),
|
|
117
|
-
priority: asNumber(routingVal.priority),
|
|
118
|
-
healthCheckPath: asString(routingVal.healthCheckPath),
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const SCALING_TYPES = ["CPU", "MEMORY"];
|
|
122
|
-
const AMI_HARDWARE_TYPES = ["ARM", "STANDARD"];
|
|
123
|
-
function parseServiceScaling(scalingVal) {
|
|
124
|
-
if (scalingVal === false)
|
|
125
|
-
return false;
|
|
126
|
-
if (!isParsedObject(scalingVal))
|
|
127
|
-
return undefined;
|
|
128
|
-
return {
|
|
129
|
-
minCapacity: asNumber(scalingVal.minCapacity),
|
|
130
|
-
maxCapacity: asNumber(scalingVal.maxCapacity),
|
|
131
|
-
desiredCount: asNumber(scalingVal.desiredCount),
|
|
132
|
-
scalingType: asStringUnion(scalingVal.scalingType, SCALING_TYPES),
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
function parseServiceEc2Config(ec2ConfigVal) {
|
|
136
|
-
if (!isParsedObject(ec2ConfigVal))
|
|
137
|
-
return undefined;
|
|
138
|
-
const warmPoolVal = ec2ConfigVal.warmPool;
|
|
139
|
-
const warmPool = isParsedObject(warmPoolVal)
|
|
140
|
-
? {
|
|
141
|
-
minSize: asNumber(warmPoolVal.minSize),
|
|
142
|
-
reuseOnScaleIn: asBoolean(warmPoolVal.reuseOnScaleIn),
|
|
143
|
-
}
|
|
144
|
-
: undefined;
|
|
145
|
-
return {
|
|
146
|
-
instanceType: asString(ec2ConfigVal.instanceType),
|
|
147
|
-
amiHardwareType: asStringUnion(ec2ConfigVal.amiHardwareType, AMI_HARDWARE_TYPES),
|
|
148
|
-
minCapacity: asNumber(ec2ConfigVal.minCapacity),
|
|
149
|
-
maxCapacity: asNumber(ec2ConfigVal.maxCapacity),
|
|
150
|
-
memoryLimitMiB: asNumber(ec2ConfigVal.memoryLimitMiB),
|
|
151
|
-
warmPool,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
/** Resolve connected database names from AST connection references */
|
|
155
|
-
function resolveConnectedDatabaseNames(connections, databaseResources) {
|
|
156
|
-
if (!Array.isArray(connections))
|
|
157
|
-
return [];
|
|
158
|
-
return connections
|
|
159
|
-
.filter(isIdentifierRef)
|
|
160
|
-
.map((conn) => databaseResources.find((db) => db.variableName === conn.__identifier))
|
|
161
|
-
.filter((db) => db !== undefined)
|
|
162
|
-
.map((db) => db.resourceName);
|
|
163
|
-
}
|
|
164
|
-
/** Resolve connected storage names from AST connection references */
|
|
165
|
-
function resolveConnectedStorageNames(connections, s3Resources) {
|
|
166
|
-
if (!Array.isArray(connections))
|
|
167
|
-
return [];
|
|
168
|
-
return connections
|
|
169
|
-
.filter(isIdentifierRef)
|
|
170
|
-
.map((conn) => s3Resources.find((s3) => s3.variableName === conn.__identifier))
|
|
171
|
-
.filter((s3) => s3 !== undefined)
|
|
172
|
-
.map((s3) => s3.resourceName);
|
|
173
|
-
}
|
|
174
|
-
/** Infer database connections from environment variables in ECS containers */
|
|
175
|
-
function inferDatabaseConnectionsFromEnv(computePlan, servicesVal, databasePlans) {
|
|
176
|
-
if (!Array.isArray(servicesVal) || servicesVal.length === 0)
|
|
177
|
-
return;
|
|
178
|
-
const firstService = servicesVal[0];
|
|
179
|
-
if (!isParsedObject(firstService))
|
|
180
|
-
return;
|
|
181
|
-
const containersVal = firstService.containers;
|
|
182
|
-
if (!Array.isArray(containersVal) || containersVal.length === 0)
|
|
183
|
-
return;
|
|
184
|
-
const firstContainer = containersVal[0];
|
|
185
|
-
if (!isParsedObject(firstContainer) ||
|
|
186
|
-
!isParsedObject(firstContainer.environment)) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
const env = firstContainer.environment;
|
|
190
|
-
if (env.DATABASE_HOST || env.DATABASE_PORT || env.DATABASE_NAME) {
|
|
191
|
-
computePlan.needsConnection = true;
|
|
192
|
-
if (databasePlans.length > 0 &&
|
|
193
|
-
(computePlan.connectedDatabase ?? []).length === 0) {
|
|
194
|
-
computePlan.connectedDatabase = [databasePlans[0].name];
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
for (let i = 1; i <= MAX_DATABASE_CONNECTION_INDICES; i++) {
|
|
198
|
-
if (env[`DATABASE_HOST_${i}`] ||
|
|
199
|
-
env[`DATABASE_PORT_${i}`] ||
|
|
200
|
-
env[`DATABASE_NAME_${i}`]) {
|
|
201
|
-
computePlan.needsConnection = true;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
/** Infer storage connections from environment variables in ECS containers */
|
|
206
|
-
function inferStorageConnectionsFromEnv(computePlan, servicesVal, s3Plans) {
|
|
207
|
-
if (!Array.isArray(servicesVal) || servicesVal.length === 0)
|
|
208
|
-
return;
|
|
209
|
-
const firstService = servicesVal[0];
|
|
210
|
-
if (!isParsedObject(firstService))
|
|
211
|
-
return;
|
|
212
|
-
const containersVal = firstService.containers;
|
|
213
|
-
if (!Array.isArray(containersVal) || containersVal.length === 0)
|
|
214
|
-
return;
|
|
215
|
-
const firstContainer = containersVal[0];
|
|
216
|
-
if (!isParsedObject(firstContainer) ||
|
|
217
|
-
!isParsedObject(firstContainer.environment)) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
const env = firstContainer.environment;
|
|
221
|
-
if (env.BUCKET_NAME) {
|
|
222
|
-
if (s3Plans.length > 0 &&
|
|
223
|
-
(computePlan.connectedStorage ?? []).length === 0) {
|
|
224
|
-
computePlan.connectedStorage = [s3Plans[0].name];
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
function extractClusterConfig(cluster) {
|
|
229
|
-
if (!isParsedObject(cluster))
|
|
230
|
-
return undefined;
|
|
231
|
-
const loadBalancerVal = cluster.loadBalancer;
|
|
232
|
-
return {
|
|
233
|
-
domain: asString(cluster.domain),
|
|
234
|
-
loadBalancer: loadBalancerVal === false
|
|
235
|
-
? false
|
|
236
|
-
: asStringUnion(loadBalancerVal, LOAD_BALANCER_TYPES),
|
|
237
|
-
directAccess: asBoolean(cluster.directAccess),
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
function parseEcsService(service) {
|
|
241
|
-
const containersVal = service.containers;
|
|
242
|
-
const containers = Array.isArray(containersVal)
|
|
243
|
-
? containersVal.filter(isParsedObject).map(parseServiceContainer)
|
|
244
|
-
: undefined;
|
|
245
|
-
const ECS_SERVICE_KNOWN_KEYS = new Set([
|
|
246
|
-
"name",
|
|
247
|
-
"image",
|
|
248
|
-
"dockerfilePath",
|
|
249
|
-
"dockerTarget",
|
|
250
|
-
"ssmSecretsPath",
|
|
251
|
-
"containers",
|
|
252
|
-
"routing",
|
|
253
|
-
"connections",
|
|
254
|
-
"cpu",
|
|
255
|
-
"memoryLimitMiB",
|
|
256
|
-
"desiredCount",
|
|
257
|
-
"scaling",
|
|
258
|
-
"capacityProvider",
|
|
259
|
-
"ec2Config",
|
|
260
|
-
]);
|
|
261
|
-
const extras = captureExtraProperties(service, ECS_SERVICE_KNOWN_KEYS);
|
|
262
|
-
return {
|
|
263
|
-
name: asString(service.name) ?? "",
|
|
264
|
-
image: asString(service.image),
|
|
265
|
-
dockerfilePath: asString(service.dockerfilePath),
|
|
266
|
-
dockerTarget: asString(service.dockerTarget),
|
|
267
|
-
ssmSecretsPath: asString(service.ssmSecretsPath),
|
|
268
|
-
containers,
|
|
269
|
-
routing: parseServiceRouting(service.routing),
|
|
270
|
-
cpu: asNumber(service.cpu),
|
|
271
|
-
memoryLimitMiB: asNumber(service.memoryLimitMiB),
|
|
272
|
-
desiredCount: asNumber(service.desiredCount),
|
|
273
|
-
scaling: parseServiceScaling(service.scaling),
|
|
274
|
-
capacityProvider: asStringUnion(service.capacityProvider, ECS_CAPACITY_PROVIDERS) ??
|
|
275
|
-
"FARGATE",
|
|
276
|
-
ec2Config: parseServiceEc2Config(service.ec2Config),
|
|
277
|
-
...(extras.length > 0 && { extraProperties: extras }),
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
function assignIfDefined(target, key, value) {
|
|
281
|
-
if (value !== undefined)
|
|
282
|
-
target[key] = value;
|
|
283
|
-
}
|
|
284
|
-
function convertEcsCompute(compute, computePlan) {
|
|
285
|
-
assignIfDefined(computePlan, "dockerfilePath", asString(compute.config.dockerfilePath));
|
|
286
|
-
const cluster = compute.config.cluster;
|
|
287
|
-
if (cluster !== undefined) {
|
|
288
|
-
computePlan.cluster = extractClusterConfig(cluster);
|
|
289
|
-
}
|
|
290
|
-
const services = compute.config.services;
|
|
291
|
-
if (services !== undefined && Array.isArray(services)) {
|
|
292
|
-
computePlan.services = services
|
|
293
|
-
.filter((s) => isParsedObject(s))
|
|
294
|
-
.map(parseEcsService);
|
|
295
|
-
}
|
|
296
|
-
const ECS_KNOWN_KEYS = new Set([
|
|
297
|
-
"type",
|
|
298
|
-
"ecrRepository",
|
|
299
|
-
"dockerfilePath",
|
|
300
|
-
"cluster",
|
|
301
|
-
"services",
|
|
302
|
-
"connections",
|
|
303
|
-
]);
|
|
304
|
-
const extras = captureExtraProperties(compute.config, ECS_KNOWN_KEYS);
|
|
305
|
-
if (extras.length > 0)
|
|
306
|
-
computePlan.extraProperties = extras;
|
|
307
|
-
}
|
|
308
|
-
/** Extract a string from a literal or an expression like `Prefix.VALUE` -> "VALUE" */
|
|
309
|
-
function extractEnumString(value, prefix) {
|
|
310
|
-
const str = asString(value);
|
|
311
|
-
if (str)
|
|
312
|
-
return str;
|
|
313
|
-
if (isExpressionRef(value) && value.__expression.startsWith(prefix + ".")) {
|
|
314
|
-
return value.__expression.slice(prefix.length + 1);
|
|
315
|
-
}
|
|
316
|
-
return undefined;
|
|
317
|
-
}
|
|
318
|
-
/** Extract a string argument from a call expression like `Code.fromAsset("./path")` */
|
|
319
|
-
function extractCallStringArg(value) {
|
|
320
|
-
if (!isCallRef(value))
|
|
321
|
-
return undefined;
|
|
322
|
-
const match = value.__call.match(/\(\s*"([^"]+)"\s*\)/);
|
|
323
|
-
return match?.[1];
|
|
324
|
-
}
|
|
325
|
-
function convertLambdaCompute(compute, computePlan) {
|
|
326
|
-
assignIfDefined(computePlan, "deployment", asStringUnion(compute.config.deployment, DEPLOYMENT_TYPES));
|
|
327
|
-
assignIfDefined(computePlan, "timeout", asNumber(compute.config.timeout));
|
|
328
|
-
// Code gen emits `memorySize` but plan field is `memory` -- handle both keys
|
|
329
|
-
assignIfDefined(computePlan, "memory", asNumber(compute.config.memorySize) ?? asNumber(compute.config.memory));
|
|
330
|
-
assignIfDefined(computePlan, "handler", asString(compute.config.handler));
|
|
331
|
-
// Code gen emits `runtime: Runtime.NODEJS_20_X` -- extract enum value from expression
|
|
332
|
-
assignIfDefined(computePlan, "runtime", extractEnumString(compute.config.runtime, "Runtime"));
|
|
333
|
-
if (isEnvironmentRecord(compute.config.environment)) {
|
|
334
|
-
computePlan.environment = compute.config.environment;
|
|
335
|
-
}
|
|
336
|
-
// secrets can be EnvironmentRecord (Secrets Manager) or string[] (SSM secrets)
|
|
337
|
-
if (isEnvironmentRecord(compute.config.secrets)) {
|
|
338
|
-
computePlan.secrets = compute.config.secrets;
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
const ssmSecrets = asStringArray(compute.config.secrets);
|
|
342
|
-
if (ssmSecrets)
|
|
343
|
-
computePlan.ssmSecrets = ssmSecrets;
|
|
344
|
-
}
|
|
345
|
-
// Extract functionUrl: { authType: FunctionUrlAuthType.NONE }
|
|
346
|
-
const functionUrlVal = compute.config.functionUrl;
|
|
347
|
-
if (isParsedObject(functionUrlVal)) {
|
|
348
|
-
const authType = extractEnumString(functionUrlVal.authType, "FunctionUrlAuthType");
|
|
349
|
-
if (authType === "NONE" || authType === "AWS_IAM") {
|
|
350
|
-
computePlan.functionUrl = { authType };
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
// Extract codePath from `code: Code.fromAsset("./path")`
|
|
354
|
-
const codeVal = compute.config.code;
|
|
355
|
-
if (codeVal !== undefined) {
|
|
356
|
-
const codePath = extractCallStringArg(codeVal);
|
|
357
|
-
if (codePath) {
|
|
358
|
-
computePlan.codePath = codePath;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
// CDK prop is `lambdaDescription` -- plan stores as `description`
|
|
362
|
-
assignIfDefined(computePlan, "description", asString(compute.config.lambdaDescription));
|
|
363
|
-
assignIfDefined(computePlan, "scheduleExpression", asString(compute.config.scheduleExpression));
|
|
364
|
-
assignIfDefined(computePlan, "architecture", extractEnumString(compute.config.architecture, "Architecture"));
|
|
365
|
-
assignIfDefined(computePlan, "ephemeralStorageSize", asNumber(compute.config.ephemeralStorageSize));
|
|
366
|
-
assignIfDefined(computePlan, "functionName", asString(compute.config.functionName));
|
|
367
|
-
assignIfDefined(computePlan, "ssmSecretsPath", asString(compute.config.ssmSecretsPath));
|
|
368
|
-
const LAMBDA_KNOWN_KEYS = new Set([
|
|
369
|
-
"type",
|
|
370
|
-
"deployment",
|
|
371
|
-
"timeout",
|
|
372
|
-
"memorySize",
|
|
373
|
-
"memory",
|
|
374
|
-
"handler",
|
|
375
|
-
"runtime",
|
|
376
|
-
"environment",
|
|
377
|
-
"secrets",
|
|
378
|
-
"functionUrl",
|
|
379
|
-
"code",
|
|
380
|
-
"connections",
|
|
381
|
-
"ecrRepository",
|
|
382
|
-
"containerSecretsImport",
|
|
383
|
-
"lambdaDescription",
|
|
384
|
-
"scheduleExpression",
|
|
385
|
-
"architecture",
|
|
386
|
-
"ephemeralStorageSize",
|
|
387
|
-
"functionName",
|
|
388
|
-
"ssmSecretsPath",
|
|
389
|
-
]);
|
|
390
|
-
const extras = captureExtraProperties(compute.config, LAMBDA_KNOWN_KEYS);
|
|
391
|
-
if (extras.length > 0)
|
|
392
|
-
computePlan.extraProperties = extras;
|
|
393
|
-
}
|
|
394
|
-
function convertEc2Compute(compute, computePlan) {
|
|
395
|
-
assignIfDefined(computePlan, "instanceType", asStringUnion(compute.config.instanceType, EC2_INSTANCE_TYPES));
|
|
396
|
-
// Code gen emits `ssh: {}` or `ssh: false` -- map to enableSSH boolean.
|
|
397
|
-
// Also accept `enableSSH: true/false` for manually-written code.
|
|
398
|
-
const sshVal = compute.config.ssh;
|
|
399
|
-
if (sshVal === false) {
|
|
400
|
-
computePlan.enableSSH = false;
|
|
401
|
-
}
|
|
402
|
-
else if (sshVal !== undefined && isParsedObject(sshVal)) {
|
|
403
|
-
computePlan.enableSSH = true;
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
assignIfDefined(computePlan, "enableSSH", asBoolean(compute.config.enableSSH));
|
|
407
|
-
}
|
|
408
|
-
assignIfDefined(computePlan, "keyName", asString(compute.config.keyName));
|
|
409
|
-
assignIfDefined(computePlan, "userData", asString(compute.config.userData));
|
|
410
|
-
if (compute.config.securityGroups !== undefined) {
|
|
411
|
-
computePlan.securityGroups = asStringArray(compute.config.securityGroups);
|
|
412
|
-
}
|
|
413
|
-
const EC2_KNOWN_KEYS = new Set([
|
|
414
|
-
"type",
|
|
415
|
-
"instanceType",
|
|
416
|
-
"ssh",
|
|
417
|
-
"enableSSH",
|
|
418
|
-
"keyName",
|
|
419
|
-
"userData",
|
|
420
|
-
"securityGroups",
|
|
421
|
-
"connections",
|
|
422
|
-
]);
|
|
423
|
-
const extras = captureExtraProperties(compute.config, EC2_KNOWN_KEYS);
|
|
424
|
-
if (extras.length > 0)
|
|
425
|
-
computePlan.extraProperties = extras;
|
|
426
|
-
}
|
|
427
|
-
function applyConnectionConfig(computePlan, compute, databaseResources, s3Resources) {
|
|
428
|
-
// Check top-level connections first, then service-level (ECS generated format)
|
|
429
|
-
let connections = compute.config.connections;
|
|
430
|
-
if (!connections && Array.isArray(compute.config.services)) {
|
|
431
|
-
const firstService = compute.config.services[0];
|
|
432
|
-
if (isParsedObject(firstService)) {
|
|
433
|
-
connections = firstService.connections;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
if (!connections)
|
|
437
|
-
return;
|
|
438
|
-
const connectedDbNames = resolveConnectedDatabaseNames(connections, databaseResources);
|
|
439
|
-
if (connectedDbNames.length > 0) {
|
|
440
|
-
computePlan.needsConnection = true;
|
|
441
|
-
computePlan.connectedDatabase = connectedDbNames;
|
|
442
|
-
}
|
|
443
|
-
const connectedStorageNames = resolveConnectedStorageNames(connections, s3Resources);
|
|
444
|
-
if (connectedStorageNames.length > 0) {
|
|
445
|
-
computePlan.connectedStorage = connectedStorageNames;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
function applyTypeSpecificConfig(computePlan, compute) {
|
|
449
|
-
const TYPE_CONVERTERS = {
|
|
450
|
-
ecs: convertEcsCompute,
|
|
451
|
-
lambda: convertLambdaCompute,
|
|
452
|
-
ec2: convertEc2Compute,
|
|
453
|
-
};
|
|
454
|
-
TYPE_CONVERTERS[computePlan.type]?.(compute, computePlan);
|
|
455
|
-
}
|
|
456
|
-
/** Convert parsed compute resources to plan format */
|
|
457
|
-
export function convertComputeResources(computeResources, databaseResources, s3Resources, plan) {
|
|
458
|
-
return computeResources.map((compute) => {
|
|
459
|
-
const computeType = asStringUnion(compute.config.type, COMPUTE_TYPES) ?? "ecs";
|
|
460
|
-
const computePlan = {
|
|
461
|
-
name: compute.resourceName,
|
|
462
|
-
type: computeType,
|
|
463
|
-
needsConnection: false,
|
|
464
|
-
connectedDatabase: [],
|
|
465
|
-
...(compute.variableName && { variableName: compute.variableName }),
|
|
466
|
-
};
|
|
467
|
-
applyConnectionConfig(computePlan, compute, databaseResources, s3Resources);
|
|
468
|
-
applyTypeSpecificConfig(computePlan, compute);
|
|
469
|
-
inferDatabaseConnectionsFromEnv(computePlan, compute.config.services, plan.database);
|
|
470
|
-
inferStorageConnectionsFromEnv(computePlan, compute.config.services, plan.s3);
|
|
471
|
-
return computePlan;
|
|
472
|
-
});
|
|
473
|
-
}
|
|
1
|
+
import*as S from"typescript";import{asString as a,asNumber as f,asBoolean as v,asStringArray as E,asStringUnion as d,captureExtraProperties as l,collectFromAst as C,extractVariableName as u,isFactoryBuildCall as m,isFactoryMethodCall as b,isParsedObject as g,parseObjectLiteral as x}from"./astCommonParser.js";import{COMPUTE_TYPES as T,DEPLOYMENT_TYPES as A,EC2_INSTANCE_TYPES as D}from"../schemas/constants.js";import{assignIfDefined as o,extractCallStringArg as _,extractClusterConfig as O,extractEnumString as y,isEnvironmentRecord as N,parseEcsService as R}from"./astComputeParserHelpers.js";import{inferDatabaseConnectionsFromEnv as Y,inferStorageConnectionsFromEnv as F,resolveConnectedDatabaseNames as U,resolveConnectedStorageNames as k}from"./astComputeConnectionParser.js";function K(e){if(e.arguments.length<2)return null;const n=e.arguments[0],i=e.arguments[1];if(!S.isStringLiteral(n)||!S.isObjectLiteralExpression(i))return null;const t=n.text,r=x(i);return{resourceName:t,type:a(r.type)??"ecs",config:r,node:e}}function w(e){return C(e,n=>{if(!S.isCallExpression(n)||!b(n,"addCompute"))return null;const i=n.arguments[0];if(!m(i,"ComputeFactory"))return null;const t=K(i);if(t){const r=u(n);r&&(t.variableName=r)}return t})}function L(e,n){o(n,"dockerfilePath",a(e.config.dockerfilePath));const i=e.config.cluster;i!==void 0&&(n.cluster=O(i));const t=e.config.services;t!==void 0&&Array.isArray(t)&&(n.services=t.filter(s=>g(s)).map(R));const r=new Set(["type","ecrRepository","dockerfilePath","cluster","services","connections"]),c=l(e.config,r);c.length>0&&(n.extraProperties=c)}function V(e,n){if(o(n,"deployment",d(e.config.deployment,A)),o(n,"timeout",f(e.config.timeout)),o(n,"memory",f(e.config.memorySize)??f(e.config.memory)),o(n,"handler",a(e.config.handler)),o(n,"runtime",y(e.config.runtime,"Runtime")),N(e.config.environment)&&(n.environment=e.config.environment),N(e.config.secrets))n.secrets=e.config.secrets;else{const s=E(e.config.secrets);s&&(n.ssmSecrets=s)}const i=e.config.functionUrl;if(g(i)){const s=y(i.authType,"FunctionUrlAuthType");(s==="NONE"||s==="AWS_IAM")&&(n.functionUrl={authType:s})}const t=e.config.code;if(t!==void 0){const s=_(t);s&&(n.codePath=s)}o(n,"description",a(e.config.lambdaDescription)),o(n,"scheduleExpression",a(e.config.scheduleExpression)),o(n,"architecture",y(e.config.architecture,"Architecture")),o(n,"ephemeralStorageSize",f(e.config.ephemeralStorageSize)),o(n,"functionName",a(e.config.functionName)),o(n,"ssmSecretsPath",a(e.config.ssmSecretsPath));const r=new Set(["type","deployment","timeout","memorySize","memory","handler","runtime","environment","secrets","functionUrl","code","connections","ecrRepository","containerSecretsImport","lambdaDescription","scheduleExpression","architecture","ephemeralStorageSize","functionName","ssmSecretsPath"]),c=l(e.config,r);c.length>0&&(n.extraProperties=c)}function z(e,n){o(n,"instanceType",d(e.config.instanceType,D));const i=e.config.ssh;i===!1?n.enableSSH=!1:i!==void 0&&g(i)?n.enableSSH=!0:o(n,"enableSSH",v(e.config.enableSSH)),o(n,"keyName",a(e.config.keyName)),o(n,"userData",a(e.config.userData)),e.config.securityGroups!==void 0&&(n.securityGroups=E(e.config.securityGroups));const t=new Set(["type","instanceType","ssh","enableSSH","keyName","userData","securityGroups","connections"]),r=l(e.config,t);r.length>0&&(n.extraProperties=r)}function H(e,n,i,t){let r=n.config.connections;if(!r&&Array.isArray(n.config.services)){const h=n.config.services[0];g(h)&&(r=h.connections)}if(!r)return;const c=U(r,i);c.length>0&&(e.needsConnection=!0,e.connectedDatabase=c);const s=k(r,t);s.length>0&&(e.connectedStorage=s)}function M(e,n){({ecs:L,lambda:V,ec2:z})[e.type]?.(n,e)}function B(e,n,i,t){return e.map(r=>{const c=d(r.config.type,T)??"ecs",s={name:r.resourceName,type:c,needsConnection:!1,connectedDatabase:[],...r.variableName&&{variableName:r.variableName}};return H(s,r,n,i),M(s,r),Y(s,r.config.services,t.database),F(s,r.config.services,t.s3),s})}export{B as convertComputeResources,w as findComputeResources};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only AST parsing helpers for compute resources. Split out of
|
|
3
|
+
* astComputeParser.ts to keep both files within the 400-line budget. Used
|
|
4
|
+
* only by astComputeParser.ts. Write paths live in src/codemod/. Do not add
|
|
5
|
+
* mutation helpers here.
|
|
6
|
+
*/
|
|
7
|
+
import { type ParsedValue, type ParsedObject, type IdentifierRef } from "./astCommonParser.js";
|
|
8
|
+
import { type ComputeResourcePlan } from "../schemas/resourceSchemas.js";
|
|
9
|
+
export type EnvironmentRecord = Record<string, string | number | boolean | IdentifierRef | {
|
|
10
|
+
__expression: string;
|
|
11
|
+
} | {
|
|
12
|
+
__call: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function isEnvironmentRecord(value: ParsedValue | undefined): value is EnvironmentRecord;
|
|
15
|
+
export declare function extractClusterConfig(cluster: ParsedValue): ComputeResourcePlan["cluster"];
|
|
16
|
+
export declare function parseEcsService(service: ParsedObject): NonNullable<ComputeResourcePlan["services"]>[number];
|
|
17
|
+
/** Extract a string from a literal or an expression like `Prefix.VALUE` -> "VALUE" */
|
|
18
|
+
export declare function extractEnumString(value: ParsedValue, prefix: string): string | undefined;
|
|
19
|
+
/** Extract a string argument from a call expression like `Code.fromAsset("./path")` */
|
|
20
|
+
export declare function extractCallStringArg(value: ParsedValue): string | undefined;
|
|
21
|
+
export declare function assignIfDefined<K extends keyof ComputeResourcePlan>(target: ComputeResourcePlan, key: K, value: ComputeResourcePlan[K] | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isPlainObject as u,isParsedObject as a,isExpressionRef as S,isCallRef as y,asString as n,asNumber as r,asBoolean as d,asStringArray as c,asStringUnion as m,captureExtraProperties as p}from"./astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as h}from"../schemas/constants.js";const C=["public","internal"];function P(e){return e!==void 0&&u(e)}function E(e){if(!a(e))return;const t={};for(const[i,o]of Object.entries(e))if(a(o)){const s=n(o.id),f=n(o.name);s&&f&&(t[i]={id:s,name:f,field:n(o.field)})}return Object.keys(t).length>0?t:void 0}function A(e){if(!a(e))return;const t=c(e.command);if(!(!t||t.length===0))return{command:t,interval:r(e.interval),timeout:r(e.timeout),retries:r(e.retries),startPeriod:r(e.startPeriod)}}function _(e){const i=p(e,new Set(["name","image","port","environment","essential","command","entryPoint","secretsImport","secrets","healthCheck"]));return{name:n(e.name),image:n(e.image),port:r(e.port),environment:P(e.environment)?e.environment:void 0,essential:d(e.essential),command:c(e.command),entryPoint:c(e.entryPoint),secretsImport:E(e.secretsImport),ssmSecrets:c(e.secrets),healthCheck:A(e.healthCheck),extraProperties:i.length>0?i:void 0}}function x(e){if(Array.isArray(e))return e.filter(a).map(t=>({path:n(t.path),host:n(t.host),priority:r(t.priority),healthCheckPath:n(t.healthCheckPath)}));if(a(e))return{path:n(e.path),host:n(e.host),priority:r(e.priority),healthCheckPath:n(e.healthCheckPath)}}const g=["CPU","MEMORY"],l=["ARM","STANDARD"];function R(e){if(e===!1)return!1;if(a(e))return{minCapacity:r(e.minCapacity),maxCapacity:r(e.maxCapacity),desiredCount:r(e.desiredCount),scalingType:m(e.scalingType,g)}}function T(e){if(!a(e))return;const t=e.warmPool,i=a(t)?{minSize:r(t.minSize),reuseOnScaleIn:d(t.reuseOnScaleIn)}:void 0;return{instanceType:n(e.instanceType),amiHardwareType:m(e.amiHardwareType,l),minCapacity:r(e.minCapacity),maxCapacity:r(e.maxCapacity),memoryLimitMiB:r(e.memoryLimitMiB),warmPool:i}}function I(e){if(!a(e))return;const t=e.loadBalancer;return{domain:n(e.domain),loadBalancer:t===!1?!1:m(t,C),directAccess:d(e.directAccess)}}function k(e){const t=e.containers,i=Array.isArray(t)?t.filter(a).map(_):void 0,s=p(e,new Set(["name","image","dockerfilePath","dockerTarget","ssmSecretsPath","containers","routing","connections","cpu","memoryLimitMiB","desiredCount","scaling","capacityProvider","ec2Config"]));return{name:n(e.name)??"",image:n(e.image),dockerfilePath:n(e.dockerfilePath),dockerTarget:n(e.dockerTarget),ssmSecretsPath:n(e.ssmSecretsPath),containers:i,routing:x(e.routing),cpu:r(e.cpu),memoryLimitMiB:r(e.memoryLimitMiB),desiredCount:r(e.desiredCount),scaling:R(e.scaling),capacityProvider:m(e.capacityProvider,h)??"FARGATE",ec2Config:T(e.ec2Config),...s.length>0&&{extraProperties:s}}}function B(e,t){const i=n(e);if(i)return i;if(S(e)&&e.__expression.startsWith(t+"."))return e.__expression.slice(t.length+1)}function M(e){return y(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}function Y(e,t,i){i!==void 0&&(e[t]=i)}export{Y as assignIfDefined,M as extractCallStringArg,I as extractClusterConfig,B as extractEnumString,P as isEnvironmentRecord,k as parseEcsService};
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only AST parser for the database section of infrastructure.ts
|
|
3
|
+
* (RDS Instance, Aurora, GlobalAurora). DynamoDB tables are handled in
|
|
4
|
+
* astDynamoDBParser.ts. Used by fjall list and by the deploy-worker's
|
|
5
|
+
* convertToResourcePlan. Write paths live in src/codemod/. Do not add
|
|
6
|
+
* mutation helpers here.
|
|
7
|
+
*/
|
|
1
8
|
import * as ts from "typescript";
|
|
2
9
|
import type { ApplicationResourcePlan, ExtraProperty } from "../schemas/resourceSchemas.js";
|
|
10
|
+
import { type ParsedDynamoDBResource } from "./astDynamoDBParser.js";
|
|
11
|
+
export { type ParsedDynamoDBResource, convertDynamoDBResources, } from "./astDynamoDBParser.js";
|
|
3
12
|
interface ParsedProxyConfig {
|
|
4
13
|
maxConnections?: number;
|
|
5
14
|
maxIdleConnections?: number;
|
|
@@ -69,27 +78,6 @@ export interface ParsedDatabaseResource {
|
|
|
69
78
|
extraProperties?: ExtraProperty[];
|
|
70
79
|
node: ts.Node;
|
|
71
80
|
}
|
|
72
|
-
declare const DYNAMODB_KEY_TYPES: readonly ["S", "N", "B"];
|
|
73
|
-
type DynamoDBKeyType = (typeof DYNAMODB_KEY_TYPES)[number];
|
|
74
|
-
interface DynamoDBKey {
|
|
75
|
-
name: string;
|
|
76
|
-
type: DynamoDBKeyType;
|
|
77
|
-
}
|
|
78
|
-
export interface ParsedDynamoDBResource {
|
|
79
|
-
variableName?: string;
|
|
80
|
-
resourceName: string;
|
|
81
|
-
partitionKey: DynamoDBKey;
|
|
82
|
-
sortKey?: DynamoDBKey;
|
|
83
|
-
globalSecondaryIndexes?: Array<{
|
|
84
|
-
indexName: string;
|
|
85
|
-
partitionKey: DynamoDBKey;
|
|
86
|
-
sortKey?: DynamoDBKey;
|
|
87
|
-
}>;
|
|
88
|
-
ttlAttribute?: string;
|
|
89
|
-
stream?: boolean;
|
|
90
|
-
extraProperties?: ExtraProperty[];
|
|
91
|
-
node: ts.Node;
|
|
92
|
-
}
|
|
93
81
|
/** Find all database resources (including DynamoDB) from addDatabase calls */
|
|
94
82
|
export declare function findDatabaseResources(sourceFile: ts.SourceFile): ParsedDatabaseResource[];
|
|
95
83
|
/** Split DynamoDB resources (type: "DynamoDB") from regular database resources */
|
|
@@ -99,6 +87,3 @@ export declare function splitDynamoDBFromDatabases(allResources: ParsedDatabaseR
|
|
|
99
87
|
};
|
|
100
88
|
/** Convert parsed database resources to plan format */
|
|
101
89
|
export declare function convertDatabaseResources(databaseResources: ParsedDatabaseResource[]): ApplicationResourcePlan["database"];
|
|
102
|
-
/** Convert parsed DynamoDB resources to plan format */
|
|
103
|
-
export declare function convertDynamoDBResources(dynamodbResources: ParsedDynamoDBResource[]): ApplicationResourcePlan["dynamodb"];
|
|
104
|
-
export {};
|