@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.
Files changed (168) hide show
  1. package/LICENSE +50 -21
  2. package/README.md +28 -0
  3. package/dist/.minified +1 -0
  4. package/dist/src/ast/astCdnParser.d.ts +5 -0
  5. package/dist/src/ast/astCdnParser.js +1 -114
  6. package/dist/src/ast/astCommonParser.d.ts +6 -17
  7. package/dist/src/ast/astCommonParser.js +1 -351
  8. package/dist/src/ast/astComputeConnectionParser.d.ts +18 -0
  9. package/dist/src/ast/astComputeConnectionParser.js +1 -0
  10. package/dist/src/ast/astComputeParser.d.ts +6 -0
  11. package/dist/src/ast/astComputeParser.js +1 -473
  12. package/dist/src/ast/astComputeParserHelpers.d.ts +21 -0
  13. package/dist/src/ast/astComputeParserHelpers.js +1 -0
  14. package/dist/src/ast/astDatabaseParser.d.ts +9 -24
  15. package/dist/src/ast/astDatabaseParser.js +1 -275
  16. package/dist/src/ast/astDomainParser.d.ts +139 -0
  17. package/dist/src/ast/astDomainParser.js +1 -0
  18. package/dist/src/ast/astDynamoDBParser.d.ts +35 -0
  19. package/dist/src/ast/astDynamoDBParser.js +1 -0
  20. package/dist/src/ast/astExpressionEvaluator.d.ts +23 -0
  21. package/dist/src/ast/astExpressionEvaluator.js +1 -0
  22. package/dist/src/ast/astInfrastructureParser.d.ts +12 -49
  23. package/dist/src/ast/astInfrastructureParser.js +1 -552
  24. package/dist/src/ast/astMessagingParser.d.ts +5 -0
  25. package/dist/src/ast/astMessagingParser.js +1 -78
  26. package/dist/src/ast/astNetworkParser.d.ts +6 -0
  27. package/dist/src/ast/astNetworkParser.js +1 -219
  28. package/dist/src/ast/astPatternParser.d.ts +6 -0
  29. package/dist/src/ast/astPatternParser.js +1 -155
  30. package/dist/src/ast/astPlanConverter.d.ts +11 -0
  31. package/dist/src/ast/astPlanConverter.js +2 -0
  32. package/dist/src/ast/astStatementClassifier.d.ts +24 -0
  33. package/dist/src/ast/astStatementClassifier.js +1 -0
  34. package/dist/src/ast/astStatementQueries.d.ts +21 -0
  35. package/dist/src/ast/astStatementQueries.js +3 -0
  36. package/dist/src/ast/astStorageParser.d.ts +5 -0
  37. package/dist/src/ast/astStorageParser.js +1 -164
  38. package/dist/src/ast/astSurgicalModification.js +19 -400
  39. package/dist/src/ast/astTestHelpers.d.ts +635 -0
  40. package/dist/src/ast/astTestHelpers.js +1 -0
  41. package/dist/src/ast/index.d.ts +1 -0
  42. package/dist/src/ast/index.js +1 -6
  43. package/dist/src/aws/regions.js +1 -254
  44. package/dist/src/codemod/_internal.d.ts +12 -0
  45. package/dist/src/codemod/_internal.js +1 -0
  46. package/dist/src/codemod/edits/addResource/bodyIndex.d.ts +34 -0
  47. package/dist/src/codemod/edits/addResource/bodyIndex.js +1 -0
  48. package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +7 -0
  49. package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -0
  50. package/dist/src/codemod/edits/addResource.d.ts +9 -0
  51. package/dist/src/codemod/edits/addResource.js +1 -0
  52. package/dist/src/codemod/edits/ensureImports.d.ts +26 -0
  53. package/dist/src/codemod/edits/ensureImports.js +1 -0
  54. package/dist/src/codemod/edits/findInsertionPosition.d.ts +39 -0
  55. package/dist/src/codemod/edits/findInsertionPosition.js +1 -0
  56. package/dist/src/codemod/edits/index.d.ts +6 -0
  57. package/dist/src/codemod/edits/index.js +1 -0
  58. package/dist/src/codemod/edits/modifyResource/literalConversion.d.ts +37 -0
  59. package/dist/src/codemod/edits/modifyResource/literalConversion.js +1 -0
  60. package/dist/src/codemod/edits/modifyResource.d.ts +9 -0
  61. package/dist/src/codemod/edits/modifyResource.js +1 -0
  62. package/dist/src/codemod/edits/removeResource/commentHeuristic.d.ts +31 -0
  63. package/dist/src/codemod/edits/removeResource/commentHeuristic.js +1 -0
  64. package/dist/src/codemod/edits/removeResource/importPruning.d.ts +8 -0
  65. package/dist/src/codemod/edits/removeResource/importPruning.js +1 -0
  66. package/dist/src/codemod/edits/removeResource.d.ts +10 -0
  67. package/dist/src/codemod/edits/removeResource.js +1 -0
  68. package/dist/src/codemod/edits/schemaFragments.d.ts +9 -0
  69. package/dist/src/codemod/edits/schemaFragments.js +1 -0
  70. package/dist/src/codemod/fileRewriter/builders.d.ts +57 -0
  71. package/dist/src/codemod/fileRewriter/builders.js +1 -0
  72. package/dist/src/codemod/fileRewriter/index.d.ts +4 -0
  73. package/dist/src/codemod/fileRewriter/index.js +1 -0
  74. package/dist/src/codemod/fileRewriter/locateByRange.d.ts +65 -0
  75. package/dist/src/codemod/fileRewriter/locateByRange.js +1 -0
  76. package/dist/src/codemod/fileRewriter/parse.d.ts +18 -0
  77. package/dist/src/codemod/fileRewriter/parse.js +2 -0
  78. package/dist/src/codemod/fileRewriter/print.d.ts +46 -0
  79. package/dist/src/codemod/fileRewriter/print.js +4 -0
  80. package/dist/src/codemod/historyPaths.d.ts +2 -0
  81. package/dist/src/codemod/historyPaths.js +1 -0
  82. package/dist/src/codemod/index.d.ts +7 -0
  83. package/dist/src/codemod/index.js +1 -0
  84. package/dist/src/codemod/listResources.d.ts +4 -0
  85. package/dist/src/codemod/listResources.js +1 -0
  86. package/dist/src/codemod/semanticIndex/findReferences.d.ts +15 -0
  87. package/dist/src/codemod/semanticIndex/findReferences.js +2 -0
  88. package/dist/src/codemod/semanticIndex/index.d.ts +4 -0
  89. package/dist/src/codemod/semanticIndex/index.js +1 -0
  90. package/dist/src/codemod/semanticIndex/listImports.d.ts +24 -0
  91. package/dist/src/codemod/semanticIndex/listImports.js +1 -0
  92. package/dist/src/codemod/semanticIndex/locateByShape.d.ts +28 -0
  93. package/dist/src/codemod/semanticIndex/locateByShape.js +1 -0
  94. package/dist/src/codemod/semanticIndex/projectCache.d.ts +14 -0
  95. package/dist/src/codemod/semanticIndex/projectCache.js +1 -0
  96. package/dist/src/codemod/types.d.ts +172 -0
  97. package/dist/src/codemod/types.js +1 -0
  98. package/dist/src/dns/bindParser.js +2 -224
  99. package/dist/src/dns/bindWriter.js +3 -52
  100. package/dist/src/dns/domainFileGenerator.d.ts +20 -0
  101. package/dist/src/dns/domainFileGenerator.js +207 -0
  102. package/dist/src/dns/domainRecords.d.ts +164 -0
  103. package/dist/src/dns/domainRecords.js +1 -0
  104. package/dist/src/dns/index.d.ts +2 -1
  105. package/dist/src/dns/index.js +1 -4
  106. package/dist/src/dns/types.js +1 -52
  107. package/dist/src/generation/common.js +6 -161
  108. package/dist/src/generation/compute.js +82 -590
  109. package/dist/src/generation/database.js +12 -198
  110. package/dist/src/generation/generatePatternCode.d.ts +58 -0
  111. package/dist/src/generation/generatePatternCode.js +33 -0
  112. package/dist/src/generation/index.js +1 -20
  113. package/dist/src/generation/infrastructure.d.ts +1 -5
  114. package/dist/src/generation/infrastructure.js +35 -377
  115. package/dist/src/generation/messagingConnections.js +1 -73
  116. package/dist/src/generation/storage.d.ts +0 -15
  117. package/dist/src/generation/storage.js +35 -168
  118. package/dist/src/generation/storageConnections.js +1 -75
  119. package/dist/src/planning/generateResourceChange.d.ts +21 -0
  120. package/dist/src/planning/generateResourceChange.js +1 -0
  121. package/dist/src/planning/index.d.ts +3 -0
  122. package/dist/src/planning/index.js +1 -1
  123. package/dist/src/planning/resourceAddition.d.ts +154 -0
  124. package/dist/src/planning/resourceAddition.js +1 -0
  125. package/dist/src/planning/resourceConnections.d.ts +19 -0
  126. package/dist/src/planning/resourceConnections.js +1 -0
  127. package/dist/src/planning/resourcePlanning.js +1 -214
  128. package/dist/src/presets/index.js +1 -3
  129. package/dist/src/presets/patternTierPresets.js +1 -131
  130. package/dist/src/presets/storagePresets.js +1 -36
  131. package/dist/src/presets/tierPresets.d.ts +5 -8
  132. package/dist/src/presets/tierPresets.js +1 -384
  133. package/dist/src/presets/tierTypes.d.ts +1 -1
  134. package/dist/src/presets/tierTypes.js +0 -7
  135. package/dist/src/schemas/alarmSchemas.d.ts +19 -0
  136. package/dist/src/schemas/alarmSchemas.js +1 -0
  137. package/dist/src/schemas/applicationSchemas.d.ts +22 -6
  138. package/dist/src/schemas/applicationSchemas.js +1 -80
  139. package/dist/src/schemas/baseSchemas.d.ts +8 -3
  140. package/dist/src/schemas/baseSchemas.js +2 -248
  141. package/dist/src/schemas/cdnSchemas.js +1 -62
  142. package/dist/src/schemas/computeSchemas.d.ts +25 -3
  143. package/dist/src/schemas/computeSchemas.js +1 -727
  144. package/dist/src/schemas/constants.d.ts +5 -7
  145. package/dist/src/schemas/constants.js +1 -218
  146. package/dist/src/schemas/databaseSchemas.d.ts +6 -1
  147. package/dist/src/schemas/databaseSchemas.js +1 -366
  148. package/dist/src/schemas/index.js +1 -3
  149. package/dist/src/schemas/instanceTypeArchitecture.js +1 -75
  150. package/dist/src/schemas/messagingSchemas.js +1 -29
  151. package/dist/src/schemas/networkSchemas.js +1 -125
  152. package/dist/src/schemas/patternSchemas.d.ts +1 -1
  153. package/dist/src/schemas/patternSchemas.js +1 -294
  154. package/dist/src/schemas/resourceSchemas.d.ts +1 -0
  155. package/dist/src/schemas/resourceSchemas.js +1 -28
  156. package/dist/src/schemas/sharedTypes.d.ts +18 -0
  157. package/dist/src/schemas/sharedTypes.js +1 -0
  158. package/dist/src/schemas/storageSchemas.d.ts +1 -0
  159. package/dist/src/schemas/storageSchemas.js +1 -119
  160. package/dist/src/types/Result.js +1 -31
  161. package/dist/src/util/errorUtils.js +1 -1
  162. package/dist/src/validation/patterns.d.ts +9 -0
  163. package/dist/src/validation/patterns.js +1 -369
  164. package/dist/src/version.d.ts +1 -1
  165. package/dist/src/version.js +1 -1
  166. package/package.json +29 -9
  167. package/dist/src/dns/infrastructureWriter.d.ts +0 -2
  168. package/dist/src/dns/infrastructureWriter.js +0 -58
@@ -1,254 +1 @@
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
- }
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};