@fjall/generator 0.88.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/dist/src/ast/astComputeParser.d.ts +4 -0
- package/dist/src/ast/astComputeParser.js +427 -0
- package/dist/src/ast/astInfrastructureParser.d.ts +357 -0
- package/dist/src/ast/astInfrastructureParser.js +1925 -0
- package/dist/src/ast/astSurgicalModification.d.ts +47 -0
- package/dist/src/ast/astSurgicalModification.js +400 -0
- package/dist/src/ast/index.d.ts +2 -0
- package/dist/src/ast/index.js +2 -0
- package/dist/src/aws/regions.d.ts +30 -0
- package/dist/src/aws/regions.js +254 -0
- package/dist/src/generation/common.d.ts +86 -0
- package/dist/src/generation/common.js +187 -0
- package/dist/src/generation/compute.d.ts +6 -0
- package/dist/src/generation/compute.js +547 -0
- package/dist/src/generation/database.d.ts +54 -0
- package/dist/src/generation/database.js +201 -0
- package/dist/src/generation/index.d.ts +12 -0
- package/dist/src/generation/index.js +18 -0
- package/dist/src/generation/infrastructure.d.ts +44 -0
- package/dist/src/generation/infrastructure.js +389 -0
- package/dist/src/generation/storage.d.ts +23 -0
- package/dist/src/generation/storage.js +174 -0
- package/dist/src/generation/storageConnections.d.ts +37 -0
- package/dist/src/generation/storageConnections.js +71 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +19 -0
- package/dist/src/planning/index.d.ts +1 -0
- package/dist/src/planning/index.js +1 -0
- package/dist/src/planning/resourcePlanning.d.ts +58 -0
- package/dist/src/planning/resourcePlanning.js +216 -0
- package/dist/src/presets/index.d.ts +3 -0
- package/dist/src/presets/index.js +3 -0
- package/dist/src/presets/patternTierPresets.d.ts +93 -0
- package/dist/src/presets/patternTierPresets.js +131 -0
- package/dist/src/presets/storagePresets.d.ts +11 -0
- package/dist/src/presets/storagePresets.js +36 -0
- package/dist/src/presets/tierPresets.d.ts +59 -0
- package/dist/src/presets/tierPresets.js +384 -0
- package/dist/src/presets/tierTypes.d.ts +301 -0
- package/dist/src/presets/tierTypes.js +7 -0
- package/dist/src/schemas/constants.d.ts +74 -0
- package/dist/src/schemas/constants.js +208 -0
- package/dist/src/schemas/index.d.ts +3 -0
- package/dist/src/schemas/index.js +3 -0
- package/dist/src/schemas/instanceTypeArchitecture.d.ts +35 -0
- package/dist/src/schemas/instanceTypeArchitecture.js +75 -0
- package/dist/src/schemas/resourceSchemas.d.ts +3534 -0
- package/dist/src/schemas/resourceSchemas.js +2015 -0
- package/dist/src/types/Result.d.ts +19 -0
- package/dist/src/types/Result.js +31 -0
- package/dist/src/util/errorUtils.d.ts +2 -0
- package/dist/src/util/errorUtils.js +15 -0
- package/dist/src/validation/patterns.d.ts +300 -0
- package/dist/src/validation/patterns.js +360 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
export const DEFAULT_REGION = "us-east-2";
|
|
2
|
+
export const regions = Object.freeze([
|
|
3
|
+
"us-east-2",
|
|
4
|
+
"us-west-2",
|
|
5
|
+
"us-east-1",
|
|
6
|
+
"eu-west-1",
|
|
7
|
+
"eu-central-1",
|
|
8
|
+
"ap-southeast-1",
|
|
9
|
+
"ap-northeast-1",
|
|
10
|
+
"ap-southeast-2",
|
|
11
|
+
"us-west-1",
|
|
12
|
+
"ca-central-1",
|
|
13
|
+
"af-south-1",
|
|
14
|
+
"ap-east-1",
|
|
15
|
+
"ap-northeast-2",
|
|
16
|
+
"ap-northeast-3",
|
|
17
|
+
"ap-south-1",
|
|
18
|
+
"ap-south-2",
|
|
19
|
+
"ap-southeast-3",
|
|
20
|
+
"ap-southeast-4",
|
|
21
|
+
"eu-central-2",
|
|
22
|
+
"eu-north-1",
|
|
23
|
+
"eu-south-1",
|
|
24
|
+
"eu-south-2",
|
|
25
|
+
"eu-west-2",
|
|
26
|
+
"eu-west-3",
|
|
27
|
+
"me-central-1",
|
|
28
|
+
"me-south-1",
|
|
29
|
+
"sa-east-1",
|
|
30
|
+
]);
|
|
31
|
+
export const AWS_REGIONS_METADATA = Object.freeze([
|
|
32
|
+
{ code: "us-east-2", name: "US East", city: "Ohio", country: "USA" },
|
|
33
|
+
{ code: "us-west-2", name: "US West", city: "Oregon", country: "USA" },
|
|
34
|
+
{ code: "us-east-1", name: "US East", city: "N. Virginia", country: "USA" },
|
|
35
|
+
{ code: "eu-west-1", name: "EU West", city: "Ireland", country: "Ireland" },
|
|
36
|
+
{
|
|
37
|
+
code: "eu-central-1",
|
|
38
|
+
name: "EU Central",
|
|
39
|
+
city: "Frankfurt",
|
|
40
|
+
country: "Germany",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
code: "ap-southeast-1",
|
|
44
|
+
name: "Asia Pacific",
|
|
45
|
+
city: "Singapore",
|
|
46
|
+
country: "Singapore",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
code: "ap-northeast-1",
|
|
50
|
+
name: "Asia Pacific",
|
|
51
|
+
city: "Tokyo",
|
|
52
|
+
country: "Japan",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
code: "ap-southeast-2",
|
|
56
|
+
name: "Asia Pacific",
|
|
57
|
+
city: "Sydney",
|
|
58
|
+
country: "Australia",
|
|
59
|
+
},
|
|
60
|
+
{ code: "us-west-1", name: "US West", city: "N. California", country: "USA" },
|
|
61
|
+
{ code: "ca-central-1", name: "Canada", city: "Central", country: "Canada" },
|
|
62
|
+
{
|
|
63
|
+
code: "af-south-1",
|
|
64
|
+
name: "Africa",
|
|
65
|
+
city: "Cape Town",
|
|
66
|
+
country: "South Africa",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
code: "ap-east-1",
|
|
70
|
+
name: "Asia Pacific",
|
|
71
|
+
city: "Hong Kong",
|
|
72
|
+
country: "China",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
code: "ap-northeast-2",
|
|
76
|
+
name: "Asia Pacific",
|
|
77
|
+
city: "Seoul",
|
|
78
|
+
country: "South Korea",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
code: "ap-northeast-3",
|
|
82
|
+
name: "Asia Pacific",
|
|
83
|
+
city: "Osaka",
|
|
84
|
+
country: "Japan",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
code: "ap-south-1",
|
|
88
|
+
name: "Asia Pacific",
|
|
89
|
+
city: "Mumbai",
|
|
90
|
+
country: "India",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
code: "ap-south-2",
|
|
94
|
+
name: "Asia Pacific",
|
|
95
|
+
city: "Hyderabad",
|
|
96
|
+
country: "India",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
code: "ap-southeast-3",
|
|
100
|
+
name: "Asia Pacific",
|
|
101
|
+
city: "Jakarta",
|
|
102
|
+
country: "Indonesia",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
code: "ap-southeast-4",
|
|
106
|
+
name: "Asia Pacific",
|
|
107
|
+
city: "Melbourne",
|
|
108
|
+
country: "Australia",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
code: "eu-central-2",
|
|
112
|
+
name: "EU Central",
|
|
113
|
+
city: "Zurich",
|
|
114
|
+
country: "Switzerland",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
code: "eu-north-1",
|
|
118
|
+
name: "EU North",
|
|
119
|
+
city: "Stockholm",
|
|
120
|
+
country: "Sweden",
|
|
121
|
+
},
|
|
122
|
+
{ code: "eu-south-1", name: "EU South", city: "Milan", country: "Italy" },
|
|
123
|
+
{ code: "eu-south-2", name: "EU South", city: "Spain", country: "Spain" },
|
|
124
|
+
{ code: "eu-west-2", name: "EU West", city: "London", country: "UK" },
|
|
125
|
+
{ code: "eu-west-3", name: "EU West", city: "Paris", country: "France" },
|
|
126
|
+
{ code: "me-central-1", name: "Middle East", city: "UAE", country: "UAE" },
|
|
127
|
+
{
|
|
128
|
+
code: "me-south-1",
|
|
129
|
+
name: "Middle East",
|
|
130
|
+
city: "Bahrain",
|
|
131
|
+
country: "Bahrain",
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
code: "sa-east-1",
|
|
135
|
+
name: "South America",
|
|
136
|
+
city: "S\u00e3o Paulo",
|
|
137
|
+
country: "Brazil",
|
|
138
|
+
},
|
|
139
|
+
]);
|
|
140
|
+
export const topRegions = Object.freeze([
|
|
141
|
+
{ code: "us-east-2", name: "US East", city: "Ohio", country: "USA" },
|
|
142
|
+
{ code: "us-west-2", name: "US West", city: "Oregon", country: "USA" },
|
|
143
|
+
{ code: "us-east-1", name: "US East", city: "N. Virginia", country: "USA" },
|
|
144
|
+
{ code: "eu-west-1", name: "EU West", city: "Ireland", country: "Ireland" },
|
|
145
|
+
{
|
|
146
|
+
code: "eu-central-1",
|
|
147
|
+
name: "EU Central",
|
|
148
|
+
city: "Frankfurt",
|
|
149
|
+
country: "Germany",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
code: "ap-southeast-1",
|
|
153
|
+
name: "Asia Pacific",
|
|
154
|
+
city: "Singapore",
|
|
155
|
+
country: "Singapore",
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
export const commonRegions = Object.freeze([
|
|
159
|
+
"us-east-2",
|
|
160
|
+
"us-west-2",
|
|
161
|
+
"us-east-1",
|
|
162
|
+
"eu-west-1",
|
|
163
|
+
"ap-southeast-1",
|
|
164
|
+
]);
|
|
165
|
+
export function parseRegionList(value) {
|
|
166
|
+
if (!value)
|
|
167
|
+
return [];
|
|
168
|
+
return value
|
|
169
|
+
.split(",")
|
|
170
|
+
.map((region) => region.trim())
|
|
171
|
+
.filter(Boolean);
|
|
172
|
+
}
|
|
173
|
+
export function isValidRegion(region) {
|
|
174
|
+
return regions.includes(region);
|
|
175
|
+
}
|
|
176
|
+
export function isValidRegionFormat(region) {
|
|
177
|
+
// AWS region format pattern
|
|
178
|
+
const regionRegex = /^[a-z]{2}-[a-z]+-[1-9]$/;
|
|
179
|
+
return regionRegex.test(region);
|
|
180
|
+
}
|
|
181
|
+
export function getSuggestions(input) {
|
|
182
|
+
// Return common regions if input is empty
|
|
183
|
+
if (!input) {
|
|
184
|
+
return commonRegions.slice(0, 3);
|
|
185
|
+
}
|
|
186
|
+
// Get prefix and direction from input
|
|
187
|
+
const parts = input.toLowerCase().split("-");
|
|
188
|
+
const prefix = parts[0];
|
|
189
|
+
const direction = parts.length > 1 ? parts[1] : "";
|
|
190
|
+
// First try to match both prefix and direction
|
|
191
|
+
let matches = [];
|
|
192
|
+
if (prefix && direction) {
|
|
193
|
+
matches = regions.filter((region) => region.startsWith(`${prefix}-${direction}`));
|
|
194
|
+
}
|
|
195
|
+
// If no matches, try just the prefix
|
|
196
|
+
if (matches.length === 0 && prefix) {
|
|
197
|
+
matches = regions.filter((region) => region.startsWith(`${prefix}-`));
|
|
198
|
+
}
|
|
199
|
+
// If still no matches, return common regions
|
|
200
|
+
return matches.length > 0 ? matches.slice(0, 3) : commonRegions.slice(0, 3);
|
|
201
|
+
}
|
|
202
|
+
export function validateRegion(region) {
|
|
203
|
+
// Check if the region is valid
|
|
204
|
+
if (isValidRegion(region)) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
// Get suggestions for invalid region
|
|
208
|
+
const suggestions = getSuggestions(region);
|
|
209
|
+
// If format is invalid, return format error
|
|
210
|
+
if (!isValidRegionFormat(region)) {
|
|
211
|
+
return `Invalid format. Try: ${suggestions.join(", ")}`;
|
|
212
|
+
}
|
|
213
|
+
// If format is valid but region not recognized
|
|
214
|
+
return `Unknown region. Try: ${suggestions.join(", ")}`;
|
|
215
|
+
}
|
|
216
|
+
export function validateRegionList(value) {
|
|
217
|
+
if (!value || value.trim() === "")
|
|
218
|
+
return true;
|
|
219
|
+
const regionsList = parseRegionList(value);
|
|
220
|
+
for (const region of regionsList) {
|
|
221
|
+
const regionValidation = validateRegion(region);
|
|
222
|
+
if (regionValidation !== true) {
|
|
223
|
+
return regionValidation;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
export function filterDuplicateRegions(regions, primaryRegion) {
|
|
229
|
+
return regions.filter((region) => region !== primaryRegion);
|
|
230
|
+
}
|
|
231
|
+
export function getRegionOptions() {
|
|
232
|
+
return AWS_REGIONS_METADATA.map((region) => ({
|
|
233
|
+
label: region.city,
|
|
234
|
+
value: region.code,
|
|
235
|
+
description: region.code,
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
export function getRegionOptionsExcluding(excludeCode) {
|
|
239
|
+
return AWS_REGIONS_METADATA.filter((region) => region.code !== excludeCode).map((region) => ({
|
|
240
|
+
label: region.city,
|
|
241
|
+
value: region.code,
|
|
242
|
+
description: region.code,
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
export function getRegionName(code) {
|
|
246
|
+
const region = AWS_REGIONS_METADATA.find((r) => r.code === code);
|
|
247
|
+
return region ? region.city : code;
|
|
248
|
+
}
|
|
249
|
+
export function createRegionFormatter(primaryRegion) {
|
|
250
|
+
return (value) => {
|
|
251
|
+
const secondaryRegions = parseRegionList(value);
|
|
252
|
+
return filterDuplicateRegions(secondaryRegions, primaryRegion);
|
|
253
|
+
};
|
|
254
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Utilities for Code Generation
|
|
3
|
+
*
|
|
4
|
+
* Shared helper functions used across all generation modules.
|
|
5
|
+
*/
|
|
6
|
+
import type { IdentifierValue, ExpressionValue, CallValue, SpecialValue } from "../schemas/resourceSchemas.js";
|
|
7
|
+
export type { IdentifierValue, ExpressionValue, CallValue, SpecialValue };
|
|
8
|
+
/**
|
|
9
|
+
* Type guard to check if a value is a special code generation value
|
|
10
|
+
*/
|
|
11
|
+
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
|
+
/**
|
|
29
|
+
* Convert resource names to camelCase variable names
|
|
30
|
+
*/
|
|
31
|
+
export declare function toVariableName(name: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Get the variable name for a resource, preferring preserved variableName
|
|
34
|
+
* from round-trip parsing over the generated default.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getVariableName(resource: {
|
|
37
|
+
name: string;
|
|
38
|
+
variableName?: string;
|
|
39
|
+
}): string;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the variable name for a resource by name, looking up across all
|
|
42
|
+
* resource arrays in the plan. Used for cross-resource references (e.g.,
|
|
43
|
+
* compute → database connection variable names).
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveResourceVariable(plan: {
|
|
46
|
+
database: Array<{
|
|
47
|
+
name: string;
|
|
48
|
+
variableName?: string;
|
|
49
|
+
}>;
|
|
50
|
+
s3: Array<{
|
|
51
|
+
name: string;
|
|
52
|
+
variableName?: string;
|
|
53
|
+
}>;
|
|
54
|
+
compute: Array<{
|
|
55
|
+
name: string;
|
|
56
|
+
variableName?: string;
|
|
57
|
+
}>;
|
|
58
|
+
dynamodb?: Array<{
|
|
59
|
+
name: string;
|
|
60
|
+
variableName?: string;
|
|
61
|
+
}>;
|
|
62
|
+
sqs?: Array<{
|
|
63
|
+
name: string;
|
|
64
|
+
variableName?: string;
|
|
65
|
+
}>;
|
|
66
|
+
}, resourceName: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Format values for code generation, handling complex types.
|
|
69
|
+
* Simple objects (few primitive values) are kept on one line.
|
|
70
|
+
*/
|
|
71
|
+
export declare function formatValue(value: unknown, baseIndent?: string): string;
|
|
72
|
+
type PropertyFormat = "raw" | "string" | "object" | "boolean-or-object";
|
|
73
|
+
/**
|
|
74
|
+
* Build a property string for code generation.
|
|
75
|
+
* Handles different value formats: raw (numbers/booleans), string (quoted),
|
|
76
|
+
* object (using formatValue), and boolean-or-object (special false handling).
|
|
77
|
+
*/
|
|
78
|
+
export declare function buildProperty(condition: boolean, name: string, value: unknown, format?: PropertyFormat): string;
|
|
79
|
+
/**
|
|
80
|
+
* Emit extra properties preserved verbatim during round-trip.
|
|
81
|
+
* Each property is emitted as `key: sourceText,` at the given indentation.
|
|
82
|
+
*/
|
|
83
|
+
export declare function emitExtraProperties(extraProperties: Array<{
|
|
84
|
+
key: string;
|
|
85
|
+
sourceText: string;
|
|
86
|
+
}> | undefined, indent?: string): string;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Utilities for Code Generation
|
|
3
|
+
*
|
|
4
|
+
* Shared helper functions used across all generation modules.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Type guard to check if a value is a special code generation value
|
|
8
|
+
*/
|
|
9
|
+
export function isSpecialValue(value) {
|
|
10
|
+
if (typeof value !== "object" || value === null) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const obj = value;
|
|
14
|
+
return (typeof obj.__identifier === "string" ||
|
|
15
|
+
typeof obj.__expression === "string" ||
|
|
16
|
+
typeof obj.__call === "string");
|
|
17
|
+
}
|
|
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
|
+
/**
|
|
47
|
+
* Convert resource names to camelCase variable names
|
|
48
|
+
*/
|
|
49
|
+
export function toVariableName(name) {
|
|
50
|
+
return name
|
|
51
|
+
.replace(/[^a-zA-Z0-9]/g, " ")
|
|
52
|
+
.split(" ")
|
|
53
|
+
.map((word, index) => index === 0
|
|
54
|
+
? word.charAt(0).toLowerCase() + word.slice(1)
|
|
55
|
+
: word.charAt(0).toUpperCase() + word.slice(1))
|
|
56
|
+
.join("");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the variable name for a resource, preferring preserved variableName
|
|
60
|
+
* from round-trip parsing over the generated default.
|
|
61
|
+
*/
|
|
62
|
+
export function getVariableName(resource) {
|
|
63
|
+
return resource.variableName ?? toVariableName(resource.name);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolve the variable name for a resource by name, looking up across all
|
|
67
|
+
* resource arrays in the plan. Used for cross-resource references (e.g.,
|
|
68
|
+
* compute → database connection variable names).
|
|
69
|
+
*/
|
|
70
|
+
export function resolveResourceVariable(plan, resourceName) {
|
|
71
|
+
for (const db of plan.database) {
|
|
72
|
+
if (db.name === resourceName && db.variableName)
|
|
73
|
+
return db.variableName;
|
|
74
|
+
}
|
|
75
|
+
for (const s3 of plan.s3) {
|
|
76
|
+
if (s3.name === resourceName && s3.variableName)
|
|
77
|
+
return s3.variableName;
|
|
78
|
+
}
|
|
79
|
+
for (const c of plan.compute) {
|
|
80
|
+
if (c.name === resourceName && c.variableName)
|
|
81
|
+
return c.variableName;
|
|
82
|
+
}
|
|
83
|
+
for (const ddb of plan.dynamodb ?? []) {
|
|
84
|
+
if (ddb.name === resourceName && ddb.variableName)
|
|
85
|
+
return ddb.variableName;
|
|
86
|
+
}
|
|
87
|
+
for (const sqs of plan.sqs ?? []) {
|
|
88
|
+
if (sqs.name === resourceName && sqs.variableName)
|
|
89
|
+
return sqs.variableName;
|
|
90
|
+
}
|
|
91
|
+
return toVariableName(resourceName);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if an object is simple enough to format inline (single line).
|
|
95
|
+
* Simple = no nested objects/arrays and few primitive values.
|
|
96
|
+
*/
|
|
97
|
+
function isSimpleObject(value) {
|
|
98
|
+
const entries = Object.entries(value);
|
|
99
|
+
if (entries.length === 0)
|
|
100
|
+
return true;
|
|
101
|
+
if (entries.length > 1)
|
|
102
|
+
return false;
|
|
103
|
+
return entries.every(([, v]) => typeof v === "string" ||
|
|
104
|
+
typeof v === "number" ||
|
|
105
|
+
typeof v === "boolean" ||
|
|
106
|
+
v === null);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Format values for code generation, handling complex types.
|
|
110
|
+
* Simple objects (few primitive values) are kept on one line.
|
|
111
|
+
*/
|
|
112
|
+
export function formatValue(value, baseIndent = " ") {
|
|
113
|
+
if (value === undefined || value === null) {
|
|
114
|
+
return "undefined";
|
|
115
|
+
}
|
|
116
|
+
if (typeof value === "string") {
|
|
117
|
+
return JSON.stringify(value);
|
|
118
|
+
}
|
|
119
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
120
|
+
return String(value);
|
|
121
|
+
}
|
|
122
|
+
if (isSpecialValue(value)) {
|
|
123
|
+
if ("__identifier" in value)
|
|
124
|
+
return value.__identifier;
|
|
125
|
+
if ("__expression" in value)
|
|
126
|
+
return value.__expression;
|
|
127
|
+
if ("__call" in value)
|
|
128
|
+
return value.__call;
|
|
129
|
+
}
|
|
130
|
+
if (Array.isArray(value)) {
|
|
131
|
+
return `[${value.map((v) => formatValue(v, baseIndent)).join(", ")}]`;
|
|
132
|
+
}
|
|
133
|
+
if (typeof value === "object") {
|
|
134
|
+
// Filter out undefined values — prevents emitting `key: undefined` in generated code
|
|
135
|
+
const definedEntries = Object.entries(value).filter(([, v]) => v !== undefined);
|
|
136
|
+
// Simple objects stay on one line
|
|
137
|
+
if (isSimpleObject(value)) {
|
|
138
|
+
const formatted = definedEntries
|
|
139
|
+
.map(([k, v]) => `${k}: ${formatValue(v, baseIndent)}`)
|
|
140
|
+
.join(", ");
|
|
141
|
+
return formatted ? `{ ${formatted} }` : "{}";
|
|
142
|
+
}
|
|
143
|
+
// Complex objects get multi-line formatting
|
|
144
|
+
const innerIndent = baseIndent + " ";
|
|
145
|
+
const formatted = definedEntries
|
|
146
|
+
.map(([k, v]) => `${innerIndent}${k}: ${formatValue(v, innerIndent)}`)
|
|
147
|
+
.join(",\n");
|
|
148
|
+
return formatted ? `{\n${formatted}\n${baseIndent}}` : "{}";
|
|
149
|
+
}
|
|
150
|
+
return JSON.stringify(value);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Build a property string for code generation.
|
|
154
|
+
* Handles different value formats: raw (numbers/booleans), string (quoted),
|
|
155
|
+
* object (using formatValue), and boolean-or-object (special false handling).
|
|
156
|
+
*/
|
|
157
|
+
export function buildProperty(condition, name, value, format = "raw") {
|
|
158
|
+
if (!condition)
|
|
159
|
+
return "";
|
|
160
|
+
let formattedValue;
|
|
161
|
+
switch (format) {
|
|
162
|
+
case "string":
|
|
163
|
+
formattedValue = `"${value}"`;
|
|
164
|
+
break;
|
|
165
|
+
case "object":
|
|
166
|
+
formattedValue = formatValue(value);
|
|
167
|
+
break;
|
|
168
|
+
case "boolean-or-object":
|
|
169
|
+
formattedValue = value === false ? "false" : formatValue(value);
|
|
170
|
+
break;
|
|
171
|
+
default:
|
|
172
|
+
formattedValue = String(value);
|
|
173
|
+
}
|
|
174
|
+
return `
|
|
175
|
+
${name}: ${formattedValue},`;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Emit extra properties preserved verbatim during round-trip.
|
|
179
|
+
* Each property is emitted as `key: sourceText,` at the given indentation.
|
|
180
|
+
*/
|
|
181
|
+
export function emitExtraProperties(extraProperties, indent = " ") {
|
|
182
|
+
if (!extraProperties?.length)
|
|
183
|
+
return "";
|
|
184
|
+
return extraProperties
|
|
185
|
+
.map((prop) => `\n${indent}${prop.key}: ${prop.sourceText},`)
|
|
186
|
+
.join("");
|
|
187
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ApplicationResourcePlan, ComputeResourcePlan } from "../schemas/resourceSchemas.js";
|
|
2
|
+
export declare function generateLambdaCode(compute: ComputeResourcePlan, _plan: ApplicationResourcePlan): string;
|
|
3
|
+
export declare function generateLambdaConnectionsCode(compute: ComputeResourcePlan, plan: ApplicationResourcePlan): string;
|
|
4
|
+
export declare function generateEc2Code(compute: ComputeResourcePlan): string;
|
|
5
|
+
export declare function generateEcsCode(compute: ComputeResourcePlan, plan: ApplicationResourcePlan): string;
|
|
6
|
+
export declare function generateComputeCode(plan: ApplicationResourcePlan, cdnReferencedResources: Set<string>): string;
|