@fjall/generator 0.89.4 → 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
package/dist/src/aws/regions.js
CHANGED
|
@@ -1,254 +1 @@
|
|
|
1
|
-
|
|
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
|
-
}
|
|
1
|
+
const f="us-east-2",i=Object.freeze(["us-east-2","us-west-2","us-east-1","eu-west-1","eu-central-1","ap-southeast-1","ap-northeast-1","ap-southeast-2","us-west-1","ca-central-1","af-south-1","ap-east-1","ap-northeast-2","ap-northeast-3","ap-south-1","ap-south-2","ap-southeast-3","ap-southeast-4","eu-central-2","eu-north-1","eu-south-1","eu-south-2","eu-west-2","eu-west-3","me-central-1","me-south-1","sa-east-1"]),r=Object.freeze([{code:"us-east-2",name:"US East",city:"Ohio",country:"USA"},{code:"us-west-2",name:"US West",city:"Oregon",country:"USA"},{code:"us-east-1",name:"US East",city:"N. Virginia",country:"USA"},{code:"eu-west-1",name:"EU West",city:"Ireland",country:"Ireland"},{code:"eu-central-1",name:"EU Central",city:"Frankfurt",country:"Germany"},{code:"ap-southeast-1",name:"Asia Pacific",city:"Singapore",country:"Singapore"},{code:"ap-northeast-1",name:"Asia Pacific",city:"Tokyo",country:"Japan"},{code:"ap-southeast-2",name:"Asia Pacific",city:"Sydney",country:"Australia"},{code:"us-west-1",name:"US West",city:"N. California",country:"USA"},{code:"ca-central-1",name:"Canada",city:"Central",country:"Canada"},{code:"af-south-1",name:"Africa",city:"Cape Town",country:"South Africa"},{code:"ap-east-1",name:"Asia Pacific",city:"Hong Kong",country:"China"},{code:"ap-northeast-2",name:"Asia Pacific",city:"Seoul",country:"South Korea"},{code:"ap-northeast-3",name:"Asia Pacific",city:"Osaka",country:"Japan"},{code:"ap-south-1",name:"Asia Pacific",city:"Mumbai",country:"India"},{code:"ap-south-2",name:"Asia Pacific",city:"Hyderabad",country:"India"},{code:"ap-southeast-3",name:"Asia Pacific",city:"Jakarta",country:"Indonesia"},{code:"ap-southeast-4",name:"Asia Pacific",city:"Melbourne",country:"Australia"},{code:"eu-central-2",name:"EU Central",city:"Zurich",country:"Switzerland"},{code:"eu-north-1",name:"EU North",city:"Stockholm",country:"Sweden"},{code:"eu-south-1",name:"EU South",city:"Milan",country:"Italy"},{code:"eu-south-2",name:"EU South",city:"Spain",country:"Spain"},{code:"eu-west-2",name:"EU West",city:"London",country:"UK"},{code:"eu-west-3",name:"EU West",city:"Paris",country:"France"},{code:"me-central-1",name:"Middle East",city:"UAE",country:"UAE"},{code:"me-south-1",name:"Middle East",city:"Bahrain",country:"Bahrain"},{code:"sa-east-1",name:"South America",city:"S\xE3o Paulo",country:"Brazil"}]),h=Object.freeze([{code:"us-east-2",name:"US East",city:"Ohio",country:"USA"},{code:"us-west-2",name:"US West",city:"Oregon",country:"USA"},{code:"us-east-1",name:"US East",city:"N. Virginia",country:"USA"},{code:"eu-west-1",name:"EU West",city:"Ireland",country:"Ireland"},{code:"eu-central-1",name:"EU Central",city:"Frankfurt",country:"Germany"},{code:"ap-southeast-1",name:"Asia Pacific",city:"Singapore",country:"Singapore"}]),s=Object.freeze(["us-east-2","us-west-2","us-east-1","eu-west-1","ap-southeast-1"]);function u(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function y(t){return i.includes(t)}function d(t){return/^[a-z]{2}-[a-z]+-[1-9]$/.test(t)}function p(t){if(!t)return s.slice(0,3);const e=t.toLowerCase().split("-"),a=e[0],n=e.length>1?e[1]:"";let o=[];return a&&n&&(o=i.filter(c=>c.startsWith(`${a}-${n}`))),o.length===0&&a&&(o=i.filter(c=>c.startsWith(`${a}-`))),o.length>0?o.slice(0,3):s.slice(0,3)}function l(t){if(y(t))return!0;const e=p(t);return d(t)?`Unknown region. Try: ${e.join(", ")}`:`Invalid format. Try: ${e.join(", ")}`}function g(t){if(!t||t.trim()==="")return!0;const e=u(t);for(const a of e){const n=l(a);if(n!==!0)return n}return!0}function m(t,e){return t.filter(a=>a!==e)}function S(){return r.map(t=>({label:t.city,value:t.code,description:t.code}))}function A(t){return r.filter(e=>e.code!==t).map(e=>({label:e.city,value:e.code,description:e.code}))}function U(t){const e=r.find(a=>a.code===t);return e?e.city:t}function E(t){return e=>{const a=u(e);return m(a,t)}}export{r as AWS_REGIONS_METADATA,f as DEFAULT_REGION,s as commonRegions,E as createRegionFormatter,m as filterDuplicateRegions,U as getRegionName,S as getRegionOptions,A as getRegionOptionsExcluding,p as getSuggestions,y as isValidRegion,d as isValidRegionFormat,u as parseRegionList,i as regions,h as topRegions,l as validateRegion,g as validateRegionList};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LinesChanged } from "./types.js";
|
|
2
|
+
export declare const DEFAULT_FILE_PATH = "/__codemod__/input.ts";
|
|
3
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
4
|
+
export declare function extractProgramBody<T>(file: unknown): T[] | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Bidirectional line-count delta between `before` and `after`. The source's
|
|
7
|
+
* dominant line terminator is detected once; positive deltas map to
|
|
8
|
+
* `added`, negative deltas to `removed`. Add-only orchestrators never
|
|
9
|
+
* observe a negative delta in practice, but the bidirectional form keeps
|
|
10
|
+
* the contract honest for `removeResource` and `modifyResource`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function computeLinesDelta(before: string, after: string): LinesChanged;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{detectLineTerminator as i}from"./fileRewriter/index.js";const c="/__codemod__/input.ts";function o(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function f(r){if(!o(r))return;const t=r.program;if(!o(t))return;const e=t.body;if(Array.isArray(e)&&e.every(n=>o(n)))return e}function d(r,t){return r.length===0?0:r.split(t).length}function a(r,t){const e=i(r),n=d(t,e)-d(r,e);return n>=0?{added:n,removed:0}:{added:0,removed:-n}}export{c as DEFAULT_FILE_PATH,a as computeLinesDelta,f as extractProgramBody,o as isRecord};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { StatementType } from "../../types.js";
|
|
2
|
+
import type { ImportInfo, InsertionStatementType, ResourceLocation } from "../findInsertionPosition.js";
|
|
3
|
+
export interface StatementNodeLike {
|
|
4
|
+
type: string;
|
|
5
|
+
start?: number | null;
|
|
6
|
+
end?: number | null;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface BodyAnchor {
|
|
10
|
+
index: number;
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
type: InsertionStatementType | undefined;
|
|
14
|
+
}
|
|
15
|
+
export interface IndexedBody {
|
|
16
|
+
anchors: BodyAnchor[];
|
|
17
|
+
importInfos: ImportInfo[];
|
|
18
|
+
appInitLocations: ResourceLocation[];
|
|
19
|
+
programEnd: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function indexBody(body: StatementNodeLike[], source: string, factoryIdentifierByType: Record<StatementType, string>): IndexedBody;
|
|
22
|
+
export declare function buildResourceLocations(anchors: BodyAnchor[], shapes: Array<{
|
|
23
|
+
start: number;
|
|
24
|
+
length: number;
|
|
25
|
+
type: StatementType;
|
|
26
|
+
}>): ResourceLocation[];
|
|
27
|
+
export declare function orderByEndPos(locations: ResourceLocation[]): ResourceLocation[];
|
|
28
|
+
/**
|
|
29
|
+
* Translate an insertion byte-offset into a body-array index. The offset
|
|
30
|
+
* is the end byte of the anchor that should come BEFORE the new
|
|
31
|
+
* statement. If no anchor matches (empty body or offset equals program
|
|
32
|
+
* end), append at the end — the legacy algorithm's EOF fallback.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveInsertIndex(anchors: BodyAnchor[], offset: number): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isRecord as u}from"../../_internal.js";function x(n,r,t){const e=[],o=[],i=[];let s=r.length;for(let c=0;c<n.length;c+=1){const f=n[c];if(f===void 0)continue;const a=typeof f.start=="number"?f.start:0,p=typeof f.end=="number"?f.end:a;p>s&&(s=p);const d=y(f,t);e.push({index:c,start:a,end:p,type:d}),d==="import"?o.push({endPos:p}):(d==="app-init"||d==="tags")&&i.push({endPos:p,type:d})}return{anchors:e,importInfos:o,appInitLocations:i,programEnd:s}}function y(n,r){if(n.type==="ImportDeclaration")return"import";if(n.type!=="ExpressionStatement")return;const t=n.expression;if(!u(t)||t.type!=="CallExpression")return;const e=t.callee;if(!u(e)||e.type!=="MemberExpression")return;const o=e.object,i=e.property;if(!u(o)||o.type!=="Identifier"||!u(i)||i.type!=="Identifier"||i.name!=="build")return;const s=o.name;if(typeof s=="string")return s==="AppFactory"?"app-init":l(s,r)}function l(n,r){for(const[t,e]of Object.entries(r))if(e===n)return t}function h(n,r){const t=[];for(const e of r){const o=n.find(i=>i.start<=e.start&&i.end>=e.start+e.length);o!==void 0&&t.push({endPos:o.end,type:e.type})}return t}function I(n){return[...n].sort((r,t)=>r.endPos-t.endPos)}function b(n,r){const t=n.find(e=>e.end===r);return t!==void 0?t.index+1:n.length}export{h as buildResourceLocations,x as indexBody,I as orderByEndPos,b as resolveInsertIndex};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type namedTypes as n } from "ast-types";
|
|
2
|
+
import { type Result } from "../../../types/Result.js";
|
|
3
|
+
import type { ObjectPropertyInput, QuoteStyle } from "../../fileRewriter/index.js";
|
|
4
|
+
import type { InvalidPropertyError } from "../../types.js";
|
|
5
|
+
export declare function buildPropertyInputs(properties: Record<string, unknown>, quoteStyle: QuoteStyle): Result<ObjectPropertyInput[], InvalidPropertyError>;
|
|
6
|
+
export declare function toAstValue(value: unknown, quoteStyle: QuoteStyle): n.Property["value"] | undefined;
|
|
7
|
+
export declare function makeStringLiteral(value: string, quote: QuoteStyle): n.StringLiteral;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{builders as o}from"ast-types";import{failure as p,success as u}from"../../../types/Result.js";function d(r,e){const n=[];for(const[t,i]of Object.entries(r)){const s=a(i,e);if(s===void 0)return p({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (Phase 1 accepts string/number/boolean/null only).`});n.push({key:t,value:s})}return u(n)}function a(r,e){if(typeof r=="string")return l(r,e);if(typeof r=="number"&&Number.isFinite(r))return o.numericLiteral(r);if(typeof r=="boolean")return o.booleanLiteral(r);if(r===null)return o.nullLiteral()}function l(r,e){const n=e==="single"?"'":'"',t=e==="single"?r.replace(/\\/g,"\\\\").replace(/'/g,"\\'"):r.replace(/\\/g,"\\\\").replace(/"/g,'\\"'),i=`${n}${t}${n}`;return o.stringLiteral.from({value:r,extra:{rawValue:r,raw:i}})}export{d as buildPropertyInputs,l as makeStringLiteral,a as toAstValue};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Result } from "../../types/Result.js";
|
|
2
|
+
import type { AddOptions, DuplicateResourceError, InvalidPropertyError, LinesChanged, ParseError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
|
|
3
|
+
export type { AddOptions, LinesChanged } from "../types.js";
|
|
4
|
+
export type AddResourceError = ParseError | TemplateLiteralNameError | DuplicateResourceError | InvalidPropertyError | SemanticQueryError;
|
|
5
|
+
export interface AddResourceSuccess {
|
|
6
|
+
content: string;
|
|
7
|
+
linesChanged: LinesChanged;
|
|
8
|
+
}
|
|
9
|
+
export declare function addResource(content: string, options: AddOptions): Result<AddResourceSuccess, AddResourceError>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{failure as o,success as L}from"../../types/Result.js";import{DEFAULT_FILE_PATH as h,computeLinesDelta as P,extractProgramBody as k,isRecord as D}from"../_internal.js";import{appendSpecifier as R,buildFactoryStatement as T,buildImportDeclaration as b,detectQuoteStyle as _,parse as x,printFile as C}from"../fileRewriter/index.js";import{locateAllShapes as A,locateByShape as B}from"../semanticIndex/index.js";import{buildResourceLocations as O,indexBody as w,orderByEndPos as N,resolveInsertIndex as Q}from"./addResource/bodyIndex.js";import{buildPropertyInputs as Y}from"./addResource/propertyBuilder.js";import{findInsertionPosition as U}from"./findInsertionPosition.js";const f="@fjall/components-infrastructure",l={database:"DatabaseFactory",storage:"StorageFactory",compute:"ComputeFactory",messaging:"MessagingFactory",cdn:"CdnFactory",network:"NetworkFactory",pattern:"PatternFactory"};function K(t,r){const c=r.filePath??h,a=x(t,c);if(!a.success)return o(a.error);const e=B(t,{type:r.type,name:r.name},c);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?o(e.error):o({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data!==void 0)return o({kind:"DuplicateResourceError",type:r.type,name:r.name});const n=_(a.data),d=Y(r.properties,n);if(!d.success)return o(d.error);const m=l[r.type],y=T({factory:m,name:r.name,properties:d.data,quoteStyle:n}),u=k(a.data);if(u===void 0)return o({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const i=w(u,t,l),s=A(t,c);if(!s.success)return s.error.kind==="TemplateLiteralNameError"?o(s.error):o({kind:"SemanticQueryError",reason:s.error.reason,cause:s.error.cause});const F=O(i.anchors,s.data),E=N([...i.appInitLocations,...F]),I=U(i.importInfos,E,r.type,i.programEnd),S=Q(i.anchors,I);u.splice(S,0,y),v(u,m,n);const p=C(a.data,t),g=P(t,p);return L({content:p,linesChanged:g})}function v(t,r,c){for(const e of t){if(e.type!=="ImportDeclaration")continue;const n=e.source;if(!(!D(n)||n.type!=="StringLiteral")&&n.value===f){R(e,r);return}}const a=b([r],f,c);t.unshift(a)}export{K as addResource};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type * as recast from "recast";
|
|
2
|
+
import { type Result } from "../../types/Result.js";
|
|
3
|
+
import type { SemanticQueryError } from "../types.js";
|
|
4
|
+
type ParsedFile = ReturnType<typeof recast.parse>;
|
|
5
|
+
export interface EnsureImportsAddition {
|
|
6
|
+
module: string;
|
|
7
|
+
specifiers: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface EnsureImportsSuccess {
|
|
10
|
+
mutated: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type EnsureImportsError = SemanticQueryError;
|
|
13
|
+
/**
|
|
14
|
+
* Ensure every `(module, specifiers[])` addition is represented as a
|
|
15
|
+
* named import in the recast-parsed `file`. Mutates `file` in place.
|
|
16
|
+
*
|
|
17
|
+
* Dedupes by the IMPORTED identifier (not the local alias): `import { a
|
|
18
|
+
* as b }` + requested `a` is a no-op. New specifiers append to the END
|
|
19
|
+
* of the existing clause — no alphabetical sort. New declarations land
|
|
20
|
+
* immediately after the last existing import, or at body[0] when the
|
|
21
|
+
* file has none.
|
|
22
|
+
*
|
|
23
|
+
* Never throws — every failure path returns `failure(EnsureImportsError)`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function ensureImports(file: ParsedFile, additions: EnsureImportsAddition[]): Result<EnsureImportsSuccess, EnsureImportsError>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{failure as m,success as f}from"../../types/Result.js";import{extractProgramBody as l,isRecord as d}from"../_internal.js";import{appendSpecifier as y,buildImportDeclaration as I,detectQuoteStyle as g}from"../fileRewriter/index.js";function L(t,r){const e=l(t);if(e===void 0)return m({kind:"SemanticQueryError",reason:"recast File is missing program.body"});if(r.length===0)return f({mutated:!1});const n=g(t);let o=!1;for(const i of r){const s=S(e,i.module);if(s!==void 0){for(const p of i.specifiers){const a=c(s);y(s,p),c(s)>a&&(o=!0)}continue}if(i.specifiers.length===0)continue;const u=I(i.specifiers,i.module,n);x(e,u),o=!0}return f({mutated:o})}function S(t,r){for(const e of t){if(e.type!=="ImportDeclaration")continue;const n=e.source;if(d(n)&&!(n.type!=="StringLiteral"&&n.type!=="Literal")&&n.value===r)return e}}function x(t,r){let e=-1;for(let o=0;o<t.length;o+=1){const i=t[o];i!==void 0&&i.type==="ImportDeclaration"&&(e=o)}const n=e===-1?0:e+1;t.splice(n,0,r)}function c(t){if(!Array.isArray(t.specifiers))return 0;let r=0;for(const e of t.specifiers)e!==null&&typeof e=="object"&&"type"in e&&e.type==="ImportSpecifier"&&(r+=1);return r}export{L as ensureImports};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { StatementType } from "../types.js";
|
|
2
|
+
/** Byte range of a classified statement, tagged with its type. */
|
|
3
|
+
export interface ResourceLocation {
|
|
4
|
+
/** Byte offset where the statement ends (exclusive). */
|
|
5
|
+
endPos: number;
|
|
6
|
+
/** Statement kind relevant to the insertion-order algorithm. */
|
|
7
|
+
type: InsertionStatementType;
|
|
8
|
+
}
|
|
9
|
+
/** Byte range of an import declaration. */
|
|
10
|
+
export interface ImportInfo {
|
|
11
|
+
/** Byte offset where the import declaration ends (exclusive). */
|
|
12
|
+
endPos: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Ordering superset of {@link StatementType}. The codemod engine only
|
|
16
|
+
* manipulates the 7 factory-call kinds declared in `StatementType`, but
|
|
17
|
+
* the legacy algorithm also recognises `import`, `app-init`, and `tags`
|
|
18
|
+
* as positioning anchors. Callers pass `import` entries via the
|
|
19
|
+
* dedicated {@link ImportInfo} list; `app-init` and `tags` are currently
|
|
20
|
+
* unreachable in Phase 1 (no managed-statement detection for them) and
|
|
21
|
+
* retained here purely so the ordering matches the legacy source.
|
|
22
|
+
*/
|
|
23
|
+
export type InsertionStatementType = StatementType | "import" | "app-init" | "tags";
|
|
24
|
+
/**
|
|
25
|
+
* Returns the byte offset at which a new statement of `newType` should
|
|
26
|
+
* be inserted. Mirrors legacy `findInsertionPositionByType` verbatim.
|
|
27
|
+
*
|
|
28
|
+
* Algorithm (unchanged from the legacy port):
|
|
29
|
+
* 1. Look up `newType`'s index in the canonical order.
|
|
30
|
+
* 2. Walk `existingImports` and `existingResources` in document order.
|
|
31
|
+
* Track the last entry whose type index is <= the target index.
|
|
32
|
+
* 3. If found, return its `endPos`.
|
|
33
|
+
* 4. Otherwise fall back to `fileEnd` (end-of-file offset).
|
|
34
|
+
*
|
|
35
|
+
* Callers supply `fileEnd` explicitly because this helper does not see
|
|
36
|
+
* the source text — pure-data boundary. The orchestrator computes it
|
|
37
|
+
* from the parsed AST (typically `ast.program.end`).
|
|
38
|
+
*/
|
|
39
|
+
export declare function findInsertionPosition(existingImports: readonly ImportInfo[], existingResources: readonly ResourceLocation[], newType: StatementType, fileEnd: number): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s=["import","app-init","tags","database","storage","messaging","compute","network","cdn","pattern"];function d(i,a,c,r){const t=s.indexOf(c);if(t===-1)return r;let e;for(const n of i)s.indexOf("import")<=t&&(e=n.endPos);for(const n of a){const o=s.indexOf(n.type);o!==-1&&o<=t&&(e=n.endPos)}return e??r}export{d as findInsertionPosition};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { SCHEMA_FRAGMENTS } from "./schemaFragments.js";
|
|
2
|
+
export { addResource, type AddOptions, type AddResourceError, type AddResourceSuccess, } from "./addResource.js";
|
|
3
|
+
export { findInsertionPosition, type ImportInfo, type InsertionStatementType, type ResourceLocation, } from "./findInsertionPosition.js";
|
|
4
|
+
export { removeResource, type LinesChanged, type RemoveOptions, type RemoveResourceError, type RemoveResourceSuccess, } from "./removeResource.js";
|
|
5
|
+
export { modifyResource, type ModifyOptions, type ModifyResourceError, type ModifyResourceSuccess, } from "./modifyResource.js";
|
|
6
|
+
export { ensureImports, type EnsureImportsAddition, type EnsureImportsError, type EnsureImportsSuccess, } from "./ensureImports.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SCHEMA_FRAGMENTS as e}from"./schemaFragments.js";import{addResource as t}from"./addResource.js";import{findInsertionPosition as p}from"./findInsertionPosition.js";import{removeResource as x}from"./removeResource.js";import{modifyResource as n}from"./modifyResource.js";import{ensureImports as u}from"./ensureImports.js";export{e as SCHEMA_FRAGMENTS,t as addResource,u as ensureImports,p as findInsertionPosition,n as modifyResource,x as removeResource};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface NodeShapeLike {
|
|
2
|
+
type: string;
|
|
3
|
+
start?: number | null;
|
|
4
|
+
end?: number | null;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface PropertyNodeLike extends NodeShapeLike {
|
|
8
|
+
type: string;
|
|
9
|
+
key?: NodeShapeLike;
|
|
10
|
+
value?: NodeShapeLike;
|
|
11
|
+
shorthand?: boolean;
|
|
12
|
+
computed?: boolean;
|
|
13
|
+
extra?: {
|
|
14
|
+
trailingComma?: boolean;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface ObjectExpressionNodeLike extends NodeShapeLike {
|
|
19
|
+
type: "ObjectExpression";
|
|
20
|
+
properties: PropertyNodeLike[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Sentinel distinct from `null`/`undefined` so callers can distinguish
|
|
24
|
+
* "literal null" from "not a literal".
|
|
25
|
+
*/
|
|
26
|
+
export declare const NON_LITERAL: unique symbol;
|
|
27
|
+
export type LiteralValue = unknown;
|
|
28
|
+
/**
|
|
29
|
+
* Build a literal shadow of `configObject` for fragment validation.
|
|
30
|
+
* Non-literal expressions in the existing object are skipped so
|
|
31
|
+
* `.strict()` does not reject real call sites that pass runtime handles
|
|
32
|
+
* (`vpc: app.getVpc()`).
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildMergedLiteral(configObject: ObjectExpressionNodeLike, requestedProperties: Record<string, unknown>): Record<string, unknown>;
|
|
35
|
+
export declare function astToLiteral(node: NodeShapeLike): LiteralValue | typeof NON_LITERAL;
|
|
36
|
+
export declare function readKeyName(key: NodeShapeLike | undefined): string | undefined;
|
|
37
|
+
export declare function isNodeShape(value: unknown): value is NodeShapeLike;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n=Symbol("non-literal");function y(e,r){const o={};for(const t of e.properties){if(t.type!=="Property"&&t.type!=="ObjectProperty"||t.shorthand===!0||t.computed===!0)continue;const i=f(t.key);if(i===void 0||t.value===void 0)continue;const u=a(t.value);u!==n&&(o[i]=u)}return{...o,...r}}function a(e){const r=e.value;switch(e.type){case"StringLiteral":return typeof r=="string"?r:n;case"NumericLiteral":return typeof r=="number"?r:n;case"BooleanLiteral":return typeof r=="boolean"?r:n;case"NullLiteral":return null;case"ArrayExpression":return p(e);case"ObjectExpression":return l(e);default:return n}}function p(e){const r=e.elements;if(!Array.isArray(r))return n;const o=[];for(const t of r){if(!c(t))return n;const i=a(t);if(i===n)return n;o.push(i)}return o}function l(e){const r=e.properties;if(!Array.isArray(r))return n;const o={};for(const t of r){if(!c(t)||t.type!=="Property"&&t.type!=="ObjectProperty")return n;const i=f(t.key),u=t.value;if(i===void 0||u===void 0)return n;const s=a(u);if(s===n)return n;o[i]=s}return o}function f(e){if(e===void 0)return;const r=e;if(e.type==="Identifier"&&typeof r.name=="string")return r.name;if(e.type==="StringLiteral"&&typeof r.value=="string")return r.value}function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&typeof e.type=="string"}export{n as NON_LITERAL,a as astToLiteral,y as buildMergedLiteral,c as isNodeShape,f as readKeyName};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Result } from "../../types/Result.js";
|
|
2
|
+
import type { InvalidPropertyError, LinesChanged, ModifyOptions, ParseError, ResourceNotFoundError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
|
|
3
|
+
export type { LinesChanged, ModifyOptions } from "../types.js";
|
|
4
|
+
export type ModifyResourceError = ParseError | ResourceNotFoundError | InvalidPropertyError | TemplateLiteralNameError | SemanticQueryError;
|
|
5
|
+
export interface ModifyResourceSuccess {
|
|
6
|
+
content: string;
|
|
7
|
+
linesChanged: LinesChanged;
|
|
8
|
+
}
|
|
9
|
+
export declare function modifyResource(content: string, options: ModifyOptions): Result<ModifyResourceSuccess, ModifyResourceError>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{failure as c,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as g,computeLinesDelta as k,extractProgramBody as E,isRecord as d}from"../_internal.js";import{buildObjectProperty as b,detectQuoteStyle as P,parse as S,printFile as v}from"../fileRewriter/index.js";import{locateAllShapes as A,locateByShape as x}from"../semanticIndex/index.js";import{toAstValue as N}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as C,isNodeShape as h,readKeyName as L}from"./modifyResource/literalConversion.js";import{SCHEMA_FRAGMENTS as j}from"./schemaFragments.js";function H(o,e){const t=e.filePath??g,n=S(o,t);if(!n.success)return c(n.error);const r=x(o,{type:e.type,name:e.name},t);if(!r.success)return r.error.kind==="TemplateLiteralNameError"?c(r.error):c({kind:"SemanticQueryError",reason:r.error.reason,cause:r.error.cause});if(r.data===void 0)return c({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:R(o,e.type,t)});const s=E(n.data);if(s===void 0)return c({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const i=w(s,r.data);if(i===void 0)return c({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const a=P(n.data),u=C(i,e.properties),l=j[e.type].safeParse(u);if(!l.success){const f=l.error.issues[0];return c({kind:"InvalidPropertyError",property:f!==void 0&&f.path.length>0?String(f.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:f?.message??"Schema validation failed"})}const p=F(i,e.properties,a);if(!p.success)return c(p.error);const m=v(n.data,o);return y({content:m,linesChanged:k(o,m)})}function w(o,e){const t=e.start+e.length;let n;const r=s=>{if(n!==void 0||s.type!=="CallExpression")return;const i=s.arguments;if(!Array.isArray(i)||i.length<2)return;const a=i[0];if(!h(a)||a.type!=="StringLiteral"||a.start!==e.start||a.end!==t)return;const u=i[1];h(u)&&u.type==="ObjectExpression"&&(n=u)};for(const s of o)if(Q(s,r),n!==void 0)break;return n}function F(o,e,t){const n=T(o);for(const[r,s]of Object.entries(e)){const i=N(s,t);if(i===void 0)return c({kind:"InvalidPropertyError",property:r,reason:`Unsupported property value for "${r}" (Phase 1 accepts string/number/boolean/null only).`});const a=O(o,r);if(a!==void 0){a.value=i;continue}const u=b(r,i,t);n&&(u.extra={...u.extra??{},trailingComma:!0}),o.properties.push(u)}return y(void 0)}function O(o,e){return o.properties.find(t=>(t.type==="Property"||t.type==="ObjectProperty")&&t.shorthand!==!0&&t.computed!==!0&&L(t.key)===e)}function T(o){return o.properties[o.properties.length-1]?.extra?.trailingComma===!0}function R(o,e,t){const n=A(o,t);return n.success?n.data.filter(r=>r.type===e).map(r=>r.symbolName):[]}function Q(o,e){const t=[o];for(;t.length>0;){const n=t.pop();if(d(n)){typeof n.type=="string"&&e(n);for(const r of Object.keys(n)){if(r==="loc"||r==="comments"||r==="tokens")continue;const s=n[r];if(Array.isArray(s))for(const i of s)d(i)&&t.push(i);else d(s)&&t.push(s)}}}}export{H as modifyResource};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface StatementNodeLike {
|
|
2
|
+
type: string;
|
|
3
|
+
start?: number | null;
|
|
4
|
+
end?: number | null;
|
|
5
|
+
comments?: CommentNodeLike[] | null;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface CommentNodeLike {
|
|
9
|
+
type: string;
|
|
10
|
+
value: string;
|
|
11
|
+
leading?: boolean;
|
|
12
|
+
trailing?: boolean;
|
|
13
|
+
start?: number | null;
|
|
14
|
+
end?: number | null;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface ClassifiedComments {
|
|
18
|
+
preserved: CommentNodeLike[];
|
|
19
|
+
adjacent: CommentNodeLike[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Partition leading comments on `statement` into:
|
|
23
|
+
* - adjacent: <2 newlines between comment.end and statement.start
|
|
24
|
+
* (comment belongs to the statement, removed alongside it).
|
|
25
|
+
* - preserved: >=2 newlines (spatially independent, caller migrates
|
|
26
|
+
* onto the next surviving statement).
|
|
27
|
+
*
|
|
28
|
+
* Trailing comments are not classified — they always drop with the
|
|
29
|
+
* statement.
|
|
30
|
+
*/
|
|
31
|
+
export declare function classifyLeadingComments(statement: StatementNodeLike, source: string): ClassifiedComments;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function a(n,e){const t=[],r=[],i=n.comments;if(!Array.isArray(i)||typeof n.start!="number")return{preserved:t,adjacent:r};for(const o of i){if(!f(o)||o.leading!==!0||typeof o.end!="number")continue;const s=e.slice(o.end,n.start);c(s)>=2?t.push(o):r.push(o)}return{preserved:t,adjacent:r}}function c(n){let e=0;for(let t=0;t<n.length;t+=1)n.charCodeAt(t)===10&&(e+=1);return e}function f(n){if(typeof n!="object"||n===null||Array.isArray(n))return!1;const e=n;return typeof e.type=="string"&&typeof e.value=="string"}export{a as classifyLeadingComments};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { StatementNodeLike } from "./commentHeuristic.js";
|
|
2
|
+
/**
|
|
3
|
+
* Walk `body` for Identifier usage counts (excluding ImportSpecifier
|
|
4
|
+
* descendants so specifiers never self-reference) and drop any named
|
|
5
|
+
* ImportSpecifier whose local name is no longer referenced. An
|
|
6
|
+
* ImportDeclaration left with zero specifiers is removed entirely.
|
|
7
|
+
*/
|
|
8
|
+
export declare function pruneUnusedImports(body: StatementNodeLike[]): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isRecord as f}from"../../_internal.js";function m(e){const r=p(e);for(let n=e.length-1;n>=0;n-=1){const t=e[n];if(t===void 0||t.type!=="ImportDeclaration")continue;const i=t.specifiers;if(!Array.isArray(i))continue;const o=i.filter(s=>{if(!u(s))return!0;const c=a(s);return(r.get(c)??0)>0});if(o.length!==i.length){if(o.length===0){e.splice(n,1);continue}t.specifiers=o}}}function p(e){const r=new Map,n=[...e];for(;n.length>0;){const t=n.pop();if(!(!f(t)||typeof t.type!="string")&&t.type!=="ImportDeclaration"){if(t.type==="Identifier"){const i=t.name;typeof i=="string"&&r.set(i,(r.get(i)??0)+1);continue}for(const i of Object.keys(t)){if(i==="loc"||i==="comments"||i==="tokens")continue;const o=t[i];if(Array.isArray(o))for(const s of o)f(s)&&typeof s.type=="string"&&n.push(s);else f(o)&&typeof o.type=="string"&&n.push(o)}}}return r}function a(e){const r=e.local;if(f(r)){const t=r.name;if(typeof t=="string")return t}const n=e.imported;if(f(n)){const t=n.name;if(typeof t=="string")return t}return""}function u(e){if(!f(e)||e.type!=="ImportSpecifier")return!1;const r=e.imported;return f(r)&&typeof r.name=="string"}export{m as pruneUnusedImports};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Result } from "../../types/Result.js";
|
|
2
|
+
import type { LinesChanged, ParseError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceNotFoundError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
|
|
3
|
+
export type { LinesChanged, RemoveOptions } from "../types.js";
|
|
4
|
+
export type RemoveResourceError = ParseError | TemplateLiteralNameError | ResourceNotFoundError | ReferencesRemainError | SemanticQueryError;
|
|
5
|
+
export interface RemoveResourceSuccess {
|
|
6
|
+
content: string;
|
|
7
|
+
linesChanged: LinesChanged;
|
|
8
|
+
references: ReferenceLocation[];
|
|
9
|
+
}
|
|
10
|
+
export declare function removeResource(content: string, options: RemoveOptions): Result<RemoveResourceSuccess, RemoveResourceError>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{failure as c,success as u}from"../../types/Result.js";import{DEFAULT_FILE_PATH as l,computeLinesDelta as p,extractProgramBody as y,isRecord as d}from"../_internal.js";import{parse as g,printFile as h}from"../fileRewriter/index.js";import{findReferences as b,locateAllShapes as E,locateByShape as v}from"../semanticIndex/index.js";import{classifyLeadingComments as k}from"./removeResource/commentHeuristic.js";import{pruneUnusedImports as S}from"./removeResource/importPruning.js";function U(n,r){const a=r.filePath??l,t=g(n,a);if(!t.success)return c(t.error);const e=v(n,{type:r.type,name:r.name},a);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?c(e.error):c({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data===void 0)return c({kind:"ResourceNotFoundError",type:r.type,name:r.name,knownNames:F(n,r.type,a)});const i=y(t.data);if(i===void 0)return c({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const o=N(i,e.data);if(o===void 0)return c({kind:"SemanticQueryError",reason:"Unable to resolve enclosing statement for the located resource."});const s=R(n,o.statement,a);if(!s.success)return c(s.error);if(s.data.locations.length>0&&r.force!==!0)return c({kind:"ReferencesRemainError",variable:s.data.variable??r.name,references:s.data.locations});A(i,o.index,n),S(i);const f=h(t.data,n),m=p(n,f);return u({content:f,linesChanged:m,references:s.data.locations})}function N(n,r){const a=r.start+r.length;for(let t=0;t<n.length;t+=1){const e=n[t];if(e!==void 0&&!(typeof e.start!="number"||typeof e.end!="number")&&e.start<=r.start&&e.end>=a)return{index:t,statement:e}}}function R(n,r,a){const t=D(r);if(t===void 0)return u({variable:void 0,locations:[]});const e=b(n,t.location,a);return e.success?u({variable:t.name,locations:e.data}):c({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause})}function D(n){let r=n;if(n.type==="ExportNamedDeclaration"){const f=n.declaration;if(!d(f)||f.type!=="VariableDeclaration")return;r=f}if(r.type!=="VariableDeclaration")return;const a=r.declarations;if(!Array.isArray(a)||a.length!==1)return;const t=a[0];if(!d(t))return;const e=t.id;if(!d(e)||e.type!=="Identifier")return;const i=e.name,o=e.start,s=e.end;if(!(typeof i!="string"||typeof o!="number"||typeof s!="number"))return{name:i,location:{filePath:l,start:o,length:s-o,symbolName:i}}}function A(n,r,a){const t=n[r];if(t===void 0)return;const{preserved:e}=k(t,a);if(e.length>0){const i=n[r+1];if(i!==void 0){const o=e.map(s=>({...s,leading:!0,trailing:!1}));i.comments=[...o,...i.comments??[]]}else{const o=n[r-1];if(o!==void 0){const s=e.map(f=>({...f,leading:!1,trailing:!0}));o.comments=[...o.comments??[],...s]}}}n.splice(r,1)}function F(n,r,a){const t=E(n,a);if(!t.success)return[];const e=[];for(const i of t.data)i.type===r&&e.push(i.symbolName);return e}export{U as removeResource};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type StatementType } from "../semanticIndex/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Map from `StatementType` → Zod fragment validating the config-object
|
|
5
|
+
* portion of an `XFactory.build("Name", { ... })` call. Every fragment
|
|
6
|
+
* is `.strict()` (Pitfall 3) so unknown property names fail loudly
|
|
7
|
+
* instead of being silently stripped.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SCHEMA_FRAGMENTS: Record<StatementType, z.ZodObject>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as n}from"zod";import{CDNResourcePlanSchema as c,ComputeResourcePlanSchema as s,DatabaseResourcePlanSchema as m,NetworkResourcePlanSchema as p,NextJSPatternConfigSchema as g,PayloadPatternConfigSchema as S,S3ResourcePlanSchema as i,SQSResourcePlanSchema as u}from"../../schemas/index.js";function e(a){const{name:t,...r}=a.shape;return n.object(r).partial().strict()}const h=e(m),l=e(i),P=(()=>{const{name:a,...t}=s.shape;return n.object(t).partial().strict()})(),F=e(u),f=e(c),R=e(p),b=(()=>{const{name:a,...t}=S.shape,{name:r,...o}=g.shape;return n.object({...t,...o}).partial().strict()})(),_={database:h,storage:l,compute:P,messaging:F,cdn:f,network:R,pattern:b};export{_ as SCHEMA_FRAGMENTS};
|