@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,219 +1 @@
1
- import * as ts from "typescript";
2
- import { constIncludes, BACKUP_VAULT_TIERS } from "../schemas/constants.js";
3
- import { asNumber, asString, collectFromAst, extractVariableName, findFirstInAst, isAppGetAppCall, isFactoryBuildCall, isFactoryMethodCall, isNamedProperty, isParsedObject, omitUndefined, parseObjectLiteral, parseBooleanOrConfig, } from "./astCommonParser.js";
4
- // ---- Flow log destination ----
5
- const FLOW_LOG_DESTINATIONS = ["cloudwatch", "s3"];
6
- function asFlowLogDestination(value) {
7
- if (value === undefined)
8
- return undefined;
9
- return FLOW_LOG_DESTINATIONS.includes(value)
10
- ? value
11
- : undefined;
12
- }
13
- // ---- Network config parsing ----
14
- function parseNetworkConfigFields(parsed) {
15
- return {
16
- maxAzs: asNumber(parsed.maxAzs),
17
- natGateways: parseBooleanOrConfig(parsed.natGateways, (v) => ({
18
- count: asNumber(v.count),
19
- })),
20
- flowLogs: parseBooleanOrConfig(parsed.flowLogs, (v) => ({
21
- destination: asString(v.destination),
22
- retentionDays: asNumber(v.retentionDays),
23
- })),
24
- vpcEndpoints: isParsedObject(parsed.vpcEndpoints)
25
- ? parsed.vpcEndpoints
26
- : undefined,
27
- };
28
- }
29
- // ---- Extraction helpers ----
30
- function extractNetworkResource(addNetworkCall, buildCall) {
31
- if (buildCall.arguments.length < 2)
32
- return null;
33
- const nameArg = buildCall.arguments[0];
34
- const configArg = buildCall.arguments[1];
35
- if (!ts.isStringLiteral(nameArg))
36
- return null;
37
- const name = nameArg.text;
38
- const parsed = ts.isObjectLiteralExpression(configArg)
39
- ? parseObjectLiteral(configArg)
40
- : {};
41
- const networkFields = parseNetworkConfigFields(parsed);
42
- const resource = {
43
- name,
44
- config: omitUndefined({ ...networkFields }),
45
- node: addNetworkCall,
46
- };
47
- const varName = extractVariableName(addNetworkCall);
48
- if (varName)
49
- resource.variableName = varName;
50
- return resource;
51
- }
52
- // ---- Public API ----
53
- /** Find VPC ID from App.getApp() network.useExisting option */
54
- export function findVpcId(sourceFile) {
55
- return findFirstInAst(sourceFile, (node) => {
56
- if (!isAppGetAppCall(node) || node.arguments.length <= 1)
57
- return undefined;
58
- const optionsArg = node.arguments[1];
59
- if (!ts.isObjectLiteralExpression(optionsArg))
60
- return undefined;
61
- for (const prop of optionsArg.properties) {
62
- if (isNamedProperty(prop, "network") &&
63
- ts.isObjectLiteralExpression(prop.initializer)) {
64
- for (const networkProp of prop.initializer.properties) {
65
- if (isNamedProperty(networkProp, "useExisting") &&
66
- ts.isStringLiteral(networkProp.initializer)) {
67
- return networkProp.initializer.text;
68
- }
69
- }
70
- }
71
- }
72
- return undefined;
73
- });
74
- }
75
- /** Extract the network configuration from App.getApp() options */
76
- export function findNetworkConfig(sourceFile) {
77
- return findFirstInAst(sourceFile, (node) => {
78
- if (!isAppGetAppCall(node) || node.arguments.length <= 1)
79
- return undefined;
80
- const optionsArg = node.arguments[1];
81
- if (!ts.isObjectLiteralExpression(optionsArg))
82
- return undefined;
83
- for (const prop of optionsArg.properties) {
84
- if (isNamedProperty(prop, "network")) {
85
- if (prop.initializer.kind === ts.SyntaxKind.FalseKeyword)
86
- return undefined;
87
- if (ts.isObjectLiteralExpression(prop.initializer)) {
88
- const hasUseExisting = prop.initializer.properties.some((p) => isNamedProperty(p, "useExisting"));
89
- if (!hasUseExisting) {
90
- const parsed = parseObjectLiteral(prop.initializer);
91
- return parseNetworkConfigFields(parsed);
92
- }
93
- }
94
- }
95
- }
96
- return undefined;
97
- });
98
- }
99
- /** Extract the backup configuration from App.getApp() options */
100
- export function findBackupConfig(sourceFile) {
101
- return findFirstInAst(sourceFile, (node) => {
102
- if (!isAppGetAppCall(node) || node.arguments.length <= 1)
103
- return undefined;
104
- const optionsArg = node.arguments[1];
105
- if (!ts.isObjectLiteralExpression(optionsArg))
106
- return undefined;
107
- for (const prop of optionsArg.properties) {
108
- if (isNamedProperty(prop, "backup")) {
109
- if (prop.initializer.kind === ts.SyntaxKind.FalseKeyword)
110
- return false;
111
- if (ts.isObjectLiteralExpression(prop.initializer)) {
112
- const parsed = parseObjectLiteral(prop.initializer);
113
- const tier = asString(parsed.tier);
114
- if (tier)
115
- return { tier };
116
- }
117
- }
118
- }
119
- return undefined;
120
- });
121
- }
122
- /** Extract the tunnel configuration from App.getApp() options */
123
- export function findTunnelConfig(sourceFile) {
124
- return findFirstInAst(sourceFile, (node) => {
125
- if (!isAppGetAppCall(node) || node.arguments.length <= 1)
126
- return undefined;
127
- const optionsArg = node.arguments[1];
128
- if (!ts.isObjectLiteralExpression(optionsArg))
129
- return undefined;
130
- for (const prop of optionsArg.properties) {
131
- if (isNamedProperty(prop, "tunnel")) {
132
- if (prop.initializer.kind === ts.SyntaxKind.FalseKeyword)
133
- return false;
134
- if (prop.initializer.kind === ts.SyntaxKind.TrueKeyword)
135
- return true;
136
- if (ts.isObjectLiteralExpression(prop.initializer)) {
137
- const parsed = parseObjectLiteral(prop.initializer);
138
- const instanceType = asString(parsed.instanceType);
139
- if (instanceType)
140
- return { instanceType };
141
- return {};
142
- }
143
- }
144
- }
145
- return undefined;
146
- });
147
- }
148
- /** Find all app.addNetwork() calls and extract their configuration */
149
- export function findNetworkResources(sourceFile) {
150
- return collectFromAst(sourceFile, (node) => {
151
- if (!ts.isCallExpression(node) || !isFactoryMethodCall(node, "addNetwork"))
152
- return null;
153
- const networkArg = node.arguments[0];
154
- if (!isFactoryBuildCall(networkArg, "NetworkFactory"))
155
- return null;
156
- return extractNetworkResource(node, networkArg);
157
- });
158
- }
159
- // ---- Plan conversion ----
160
- /** Builds the conditional spread fields shared by primary and additional network configs */
161
- export function buildNetworkFields(config) {
162
- const flowLogs = config.flowLogs;
163
- return {
164
- ...omitUndefined({
165
- maxAzs: config.maxAzs,
166
- natGateways: config.natGateways,
167
- vpcEndpoints: config.vpcEndpoints,
168
- }),
169
- ...(flowLogs !== undefined && {
170
- flowLogs: flowLogs === false
171
- ? false
172
- : omitUndefined({
173
- destination: asFlowLogDestination(flowLogs.destination),
174
- retentionDays: flowLogs.retentionDays,
175
- }),
176
- }),
177
- };
178
- }
179
- /** Convert network config to plan format */
180
- export function convertNetworkConfig(network) {
181
- if (!network)
182
- return undefined;
183
- return buildNetworkFields(network);
184
- }
185
- /** Convert backup config to plan format */
186
- export function convertBackupConfig(backup) {
187
- if (backup === undefined)
188
- return undefined;
189
- if (backup === false)
190
- return false;
191
- const tier = backup.tier;
192
- if (constIncludes(BACKUP_VAULT_TIERS, tier)) {
193
- return { tier: tier };
194
- }
195
- return undefined;
196
- }
197
- /** Convert tunnel config to plan format */
198
- export function convertTunnelConfig(tunnel) {
199
- if (tunnel === undefined)
200
- return undefined;
201
- if (tunnel === false)
202
- return false;
203
- if (tunnel === true)
204
- return {};
205
- const result = {};
206
- if (tunnel.instanceType) {
207
- result.instanceType = tunnel.instanceType;
208
- }
209
- return result;
210
- }
211
- /** Convert additional network resources to plan format */
212
- export function convertAdditionalNetworks(networkResources) {
213
- if (!networkResources || networkResources.length === 0)
214
- return undefined;
215
- return networkResources.map((network) => ({
216
- name: network.name,
217
- ...buildNetworkFields(network.config),
218
- }));
219
- }
1
+ import*as r from"typescript";import{constIncludes as L,BACKUP_VAULT_TIERS as z}from"../schemas/constants.js";import{asNumber as d,asString as p,collectFromAst as A,extractVariableName as N,findFirstInAst as a,isAppGetAppCall as u,isFactoryBuildCall as O,isFactoryMethodCall as k,isNamedProperty as f,isParsedObject as F,omitUndefined as l,parseObjectLiteral as c,parseBooleanOrConfig as m}from"./astCommonParser.js";const b=["cloudwatch","s3"];function T(n){if(n!==void 0)return b.includes(n)?n:void 0}function y(n){return{maxAzs:d(n.maxAzs),natGateways:m(n.natGateways,e=>({count:d(e.count)})),flowLogs:m(n.flowLogs,e=>({destination:p(e.destination),retentionDays:d(e.retentionDays)})),vpcEndpoints:F(n.vpcEndpoints)?n.vpcEndpoints:void 0}}function j(n,e){if(e.arguments.length<2)return null;const t=e.arguments[0],i=e.arguments[1];if(!r.isStringLiteral(t))return null;const o=t.text,s=r.isObjectLiteralExpression(i)?c(i):{},E=y(s),g={name:o,config:l({...E}),node:n},x=N(n);return x&&(g.variableName=x),g}function S(n){return a(n,e=>{if(!u(e)||e.arguments.length<=1)return;const t=e.arguments[1];if(r.isObjectLiteralExpression(t)){for(const i of t.properties)if(f(i,"network")&&r.isObjectLiteralExpression(i.initializer)){for(const o of i.initializer.properties)if(f(o,"useExisting")&&r.isStringLiteral(o.initializer))return o.initializer.text}}})}function K(n){return a(n,e=>{if(!u(e)||e.arguments.length<=1)return;const t=e.arguments[1];if(r.isObjectLiteralExpression(t)){for(const i of t.properties)if(f(i,"network")){if(i.initializer.kind===r.SyntaxKind.FalseKeyword)return;if(r.isObjectLiteralExpression(i.initializer)&&!i.initializer.properties.some(s=>f(s,"useExisting"))){const s=c(i.initializer);return y(s)}}}})}function v(n){return a(n,e=>{if(!u(e)||e.arguments.length<=1)return;const t=e.arguments[1];if(r.isObjectLiteralExpression(t)){for(const i of t.properties)if(f(i,"backup")){if(i.initializer.kind===r.SyntaxKind.FalseKeyword)return!1;if(r.isObjectLiteralExpression(i.initializer)){const o=c(i.initializer),s=p(o.tier);if(s)return{tier:s}}}}})}function D(n){return a(n,e=>{if(!u(e)||e.arguments.length<=1)return;const t=e.arguments[1];if(r.isObjectLiteralExpression(t)){for(const i of t.properties)if(f(i,"tunnel")){if(i.initializer.kind===r.SyntaxKind.FalseKeyword)return!1;if(i.initializer.kind===r.SyntaxKind.TrueKeyword)return!0;if(r.isObjectLiteralExpression(i.initializer)){const o=c(i.initializer),s=p(o.instanceType);return s?{instanceType:s}:{}}}}})}function G(n){return A(n,e=>{if(!r.isCallExpression(e)||!k(e,"addNetwork"))return null;const t=e.arguments[0];return O(t,"NetworkFactory")?j(e,t):null})}function w(n){const e=n.flowLogs;return{...l({maxAzs:n.maxAzs,natGateways:n.natGateways,vpcEndpoints:n.vpcEndpoints}),...e!==void 0&&{flowLogs:e===!1?!1:l({destination:T(e.destination),retentionDays:e.retentionDays})}}}function I(n){if(n)return w(n)}function B(n){if(n===void 0)return;if(n===!1)return!1;const e=n.tier;if(L(z,e))return{tier:e}}function U(n){if(n===void 0)return;if(n===!1)return!1;if(n===!0)return{};const e={};return n.instanceType&&(e.instanceType=n.instanceType),e}function P(n){if(!(!n||n.length===0))return n.map(e=>({name:e.name,...w(e.config)}))}export{w as buildNetworkFields,P as convertAdditionalNetworks,B as convertBackupConfig,I as convertNetworkConfig,U as convertTunnelConfig,v as findBackupConfig,K as findNetworkConfig,G as findNetworkResources,D as findTunnelConfig,S as findVpcId};
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Read-only AST parser for the pattern section of infrastructure.ts (payload
3
+ * and nextjs). Used by fjall list and by the deploy-worker's
4
+ * convertToResourcePlan. Write paths live in src/codemod/. Do not add mutation
5
+ * helpers here.
6
+ */
1
7
  import * as ts from "typescript";
2
8
  import type { ApplicationResourcePlan } from "../schemas/resourceSchemas.js";
3
9
  /** Parsed Lambda function configuration */
@@ -1,155 +1 @@
1
- import * as ts from "typescript";
2
- import { asBoolean, asNumber, asString, asStringArray, asStringUnion, asObjectOrFalse, collectFromAst, extractSubConfig, extractVariableName, isFactoryBuildCall, isFactoryMethodCall, isParsedObject, parseObjectLiteral, parseOptionalConfig, typed, } from "./astCommonParser.js";
3
- import { parseDeadLetterQueueConfig } from "./astMessagingParser.js";
4
- // ---- Internal helpers ----
5
- const VALID_NON_GLOBAL_DB_TYPES = ["Instance", "Aurora"];
6
- const VALID_DB_ENGINES = ["postgresql", "mysql"];
7
- function parseLambdaConfig(obj) {
8
- if (!isParsedObject(obj))
9
- return undefined;
10
- const config = {
11
- ...(obj.memorySize !== undefined && {
12
- memorySize: asNumber(obj.memorySize),
13
- }),
14
- ...(obj.timeout !== undefined && { timeout: asNumber(obj.timeout) }),
15
- ...(obj.ephemeralStorageSize !== undefined && {
16
- ephemeralStorageSize: asNumber(obj.ephemeralStorageSize),
17
- }),
18
- };
19
- return Object.keys(config).length > 0 ? config : undefined;
20
- }
21
- function extractPatternDatabaseConfig(rawConfig) {
22
- return extractSubConfig(rawConfig, "database", (db) => ({
23
- type: asStringUnion(db.type, VALID_NON_GLOBAL_DB_TYPES),
24
- databaseName: asString(db.databaseName),
25
- databaseEngine: asStringUnion(db.databaseEngine, VALID_DB_ENGINES),
26
- deletionProtection: asBoolean(db.deletionProtection),
27
- backupRetention: asNumber(db.backupRetention),
28
- port: asNumber(db.port),
29
- publiclyAccessible: asBoolean(db.publiclyAccessible),
30
- allowedIpCidr: asString(db.allowedIpCidr),
31
- instanceType: asString(db.instanceType),
32
- allocatedStorage: asNumber(db.allocatedStorage),
33
- multiAz: asBoolean(db.multiAz),
34
- allowVpcAccess: asBoolean(db.allowVpcAccess),
35
- monitoringInterval: asNumber(db.monitoringInterval),
36
- preferredMaintenanceWindow: asString(db.preferredMaintenanceWindow),
37
- snapshotIdentifier: asString(db.snapshotIdentifier),
38
- snapshotUsername: asString(db.snapshotUsername),
39
- readReplica: asObjectOrFalse(db.readReplica),
40
- writer: parseOptionalConfig(db.writer, typed()),
41
- readers: asObjectOrFalse(db.readers),
42
- databaseInsights: asObjectOrFalse(db.databaseInsights),
43
- proxy: asObjectOrFalse(db.proxy),
44
- credentials: parseOptionalConfig(db.credentials, typed()),
45
- encryption: parseOptionalConfig(db.encryption, typed()),
46
- }));
47
- }
48
- function extractPatternComputeConfig(rawConfig) {
49
- return extractSubConfig(rawConfig, "compute", (compute) => ({
50
- server: parseOptionalConfig(compute.server, parseLambdaConfig),
51
- imageOptimisation: parseOptionalConfig(compute.imageOptimisation, parseLambdaConfig),
52
- revalidation: parseOptionalConfig(compute.revalidation, parseLambdaConfig),
53
- }));
54
- }
55
- function extractPatternStorageConfig(rawConfig) {
56
- const parseVersionedConfig = (obj) => ({
57
- versioned: asBoolean(obj.versioned),
58
- });
59
- return extractSubConfig(rawConfig, "storage", (storage) => ({
60
- assets: parseOptionalConfig(storage.assets, parseVersionedConfig),
61
- cache: parseOptionalConfig(storage.cache, parseVersionedConfig),
62
- media: parseOptionalConfig(storage.media, parseVersionedConfig),
63
- }));
64
- }
65
- function extractPatternMessagingConfig(rawConfig) {
66
- return extractSubConfig(rawConfig, "messaging", (messaging) => ({
67
- revalidationQueue: parseOptionalConfig(messaging.revalidationQueue, (queue) => ({
68
- visibilityTimeout: asNumber(queue.visibilityTimeout),
69
- messageRetentionPeriod: asNumber(queue.messageRetentionPeriod),
70
- maxMessageSize: asNumber(queue.maxMessageSize),
71
- deadLetterQueue: parseDeadLetterQueueConfig(queue.deadLetterQueue),
72
- })),
73
- }));
74
- }
75
- function extractPatternCdnConfig(rawConfig) {
76
- return extractSubConfig(rawConfig, "cdn", (cdn) => ({
77
- domainNames: asStringArray(cdn.domainNames),
78
- certificateArn: asString(cdn.certificateArn),
79
- }));
80
- }
81
- function extractPatternEnvironmentConfig(rawConfig) {
82
- return extractSubConfig(rawConfig, "environment", (env) => {
83
- const environment = Object.fromEntries(Object.entries(env).filter((entry) => typeof entry[1] === "string"));
84
- return Object.keys(environment).length > 0 ? environment : undefined;
85
- });
86
- }
87
- function extractPatternResource(buildCall, addPatternCall) {
88
- if (buildCall.arguments.length < 2)
89
- return null;
90
- const constructIdArg = buildCall.arguments[0];
91
- const configArg = buildCall.arguments[1];
92
- if (!ts.isStringLiteral(constructIdArg) ||
93
- !ts.isObjectLiteralExpression(configArg)) {
94
- return null;
95
- }
96
- const constructId = constructIdArg.text;
97
- const rawConfig = parseObjectLiteral(configArg);
98
- const patternType = rawConfig.type;
99
- if (patternType !== "payload" && patternType !== "nextjs") {
100
- return null;
101
- }
102
- const variableName = extractVariableName(addPatternCall);
103
- const name = asString(rawConfig.name);
104
- if (!name) {
105
- return null;
106
- }
107
- return {
108
- variableName,
109
- constructId,
110
- type: patternType,
111
- config: {
112
- name,
113
- domain: asString(rawConfig.domain),
114
- database: extractPatternDatabaseConfig(rawConfig),
115
- compute: extractPatternComputeConfig(rawConfig),
116
- storage: extractPatternStorageConfig(rawConfig),
117
- messaging: extractPatternMessagingConfig(rawConfig),
118
- cdn: extractPatternCdnConfig(rawConfig),
119
- environment: extractPatternEnvironmentConfig(rawConfig),
120
- },
121
- node: buildCall,
122
- };
123
- }
124
- // ---- Public API ----
125
- /** Find pattern resources from app.addPattern(PatternFactory.build(...)) calls */
126
- export function findPatternResources(sourceFile) {
127
- return collectFromAst(sourceFile, (node) => {
128
- if (!ts.isCallExpression(node) || !isFactoryMethodCall(node, "addPattern"))
129
- return null;
130
- const patternArg = node.arguments[0];
131
- if (!isFactoryBuildCall(patternArg, "PatternFactory"))
132
- return null;
133
- return extractPatternResource(patternArg, node);
134
- });
135
- }
136
- /** Apply pattern config to plan */
137
- export function applyPatternConfig(plan, patternResources) {
138
- if (!patternResources || patternResources.length === 0)
139
- return;
140
- const patternResource = patternResources[0];
141
- if (patternResource.type !== "payload" && patternResource.type !== "nextjs")
142
- return;
143
- plan.pattern = patternResource.type;
144
- plan.patternConfig = {
145
- type: patternResource.type,
146
- name: patternResource.config.name,
147
- domain: patternResource.config.domain,
148
- database: patternResource.config.database,
149
- compute: patternResource.config.compute,
150
- storage: patternResource.config.storage,
151
- messaging: patternResource.config.messaging,
152
- cdn: patternResource.config.cdn,
153
- environment: patternResource.config.environment,
154
- };
155
- }
1
+ import*as l from"typescript";import{asBoolean as c,asNumber as r,asString as o,asStringArray as v,asStringUnion as y,asObjectOrFalse as g,collectFromAst as C,extractSubConfig as s,extractVariableName as A,isFactoryBuildCall as P,isFactoryMethodCall as h,isParsedObject as I,parseObjectLiteral as O,parseOptionalConfig as a,typed as p}from"./astCommonParser.js";import{parseDeadLetterQueueConfig as L}from"./astMessagingParser.js";const N=["Instance","Aurora"],z=["postgresql","mysql"];function f(n){if(!I(n))return;const e={...n.memorySize!==void 0&&{memorySize:r(n.memorySize)},...n.timeout!==void 0&&{timeout:r(n.timeout)},...n.ephemeralStorageSize!==void 0&&{ephemeralStorageSize:r(n.ephemeralStorageSize)}};return Object.keys(e).length>0?e:void 0}function w(n){return s(n,"database",e=>({type:y(e.type,N),databaseName:o(e.databaseName),databaseEngine:y(e.databaseEngine,z),deletionProtection:c(e.deletionProtection),backupRetention:r(e.backupRetention),port:r(e.port),publiclyAccessible:c(e.publiclyAccessible),allowedIpCidr:o(e.allowedIpCidr),instanceType:o(e.instanceType),allocatedStorage:r(e.allocatedStorage),multiAz:c(e.multiAz),allowVpcAccess:c(e.allowVpcAccess),monitoringInterval:r(e.monitoringInterval),preferredMaintenanceWindow:o(e.preferredMaintenanceWindow),snapshotIdentifier:o(e.snapshotIdentifier),snapshotUsername:o(e.snapshotUsername),readReplica:g(e.readReplica),writer:a(e.writer,p()),readers:g(e.readers),databaseInsights:g(e.databaseInsights),proxy:g(e.proxy),credentials:a(e.credentials,p()),encryption:a(e.encryption,p())}))}function E(n){return s(n,"compute",e=>({server:a(e.server,f),imageOptimisation:a(e.imageOptimisation,f),revalidation:a(e.revalidation,f)}))}function R(n){const e=t=>({versioned:c(t.versioned)});return s(n,"storage",t=>({assets:a(t.assets,e),cache:a(t.cache,e),media:a(t.media,e)}))}function D(n){return s(n,"messaging",e=>({revalidationQueue:a(e.revalidationQueue,t=>({visibilityTimeout:r(t.visibilityTimeout),messageRetentionPeriod:r(t.messageRetentionPeriod),maxMessageSize:r(t.maxMessageSize),deadLetterQueue:L(t.deadLetterQueue)}))}))}function M(n){return s(n,"cdn",e=>({domainNames:v(e.domainNames),certificateArn:o(e.certificateArn)}))}function T(n){return s(n,"environment",e=>{const t=Object.fromEntries(Object.entries(e).filter(m=>typeof m[1]=="string"));return Object.keys(t).length>0?t:void 0})}function V(n,e){if(n.arguments.length<2)return null;const t=n.arguments[0],m=n.arguments[1];if(!l.isStringLiteral(t)||!l.isObjectLiteralExpression(m))return null;const S=t.text,i=O(m),u=i.type;if(u!=="payload"&&u!=="nextjs")return null;const x=A(e),d=o(i.name);return d?{variableName:x,constructId:S,type:u,config:{name:d,domain:o(i.domain),database:w(i),compute:E(i),storage:R(i),messaging:D(i),cdn:M(i),environment:T(i)},node:n}:null}function F(n){return C(n,e=>{if(!l.isCallExpression(e)||!h(e,"addPattern"))return null;const t=e.arguments[0];return P(t,"PatternFactory")?V(t,e):null})}function Q(n,e){if(!e||e.length===0)return;const t=e[0];t.type!=="payload"&&t.type!=="nextjs"||(n.pattern=t.type,n.patternConfig={type:t.type,name:t.config.name,domain:t.config.domain,database:t.config.database,compute:t.config.compute,storage:t.config.storage,messaging:t.config.messaging,cdn:t.config.cdn,environment:t.config.environment})}export{Q as applyPatternConfig,F as findPatternResources};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Read-only converter from ParsedInfrastructure to ApplicationResourcePlan.
3
+ * Split out of astInfrastructureParser.ts to keep both files within the
4
+ * 400-line budget. Used by fjall list and by the deploy-worker. Write paths
5
+ * live in src/codemod/. Do not add mutation helpers here.
6
+ */
7
+ import { type ApplicationResourcePlan } from "../schemas/resourceSchemas.js";
8
+ import type { ParsedInfrastructure } from "./astInfrastructureParser.js";
9
+ export declare function convertToResourcePlan(parsed: ParsedInfrastructure, appName: string, options?: {
10
+ skipValidation?: boolean;
11
+ }): ApplicationResourcePlan;
@@ -0,0 +1,2 @@
1
+ import{ApplicationResourcePlanSchema as s,getZodErrorMessage as u}from"../schemas/resourceSchemas.js";import{z as m}from"zod";import{COST_ALLOCATION_TAG as c}from"../generation/infrastructure.js";import{convertDatabaseResources as a,convertDynamoDBResources as f}from"./astDatabaseParser.js";import{convertS3Resources as p}from"./astStorageParser.js";import{convertComputeResources as l}from"./astComputeParser.js";import{convertSQSResources as d}from"./astMessagingParser.js";import{convertCDNResource as R}from"./astCdnParser.js";import{convertNetworkConfig as g,convertBackupConfig as v,convertTunnelConfig as I,convertAdditionalNetworks as S}from"./astNetworkParser.js";import{applyPatternConfig as h}from"./astPatternParser.js";import{KNOWN_FJALL_IMPORTS as k,isManagedModuleSpecifier as w}from"./astStatementClassifier.js";function b(o,r){Object.keys(r).length>0&&(o.tags={...r}),r[c]&&(o.owner=r[c])}function y(o){const r=[];for(const t of o)if(w(t.moduleSpecifier))if(t.moduleSpecifier==="@fjall/components-infrastructure"||t.moduleSpecifier==="@fjall/infrastructure"){const e=t.namedImports.filter(n=>!k.has(n));e.length>0&&r.push({moduleSpecifier:t.moduleSpecifier,namedImports:e,defaultImport:t.defaultImport})}else(t.namedImports.length>0||t.defaultImport)&&r.push(t);return r.length>0?r:void 0}function E(o,r,t){const e={appName:r,type:"standard",database:[],s3:[],compute:[]};if(h(e,o.patternResources),o.vpcId&&(e.vpcId=o.vpcId),e.network=g(o.network),e.backup=v(o.backup),e.tunnel=I(o.tunnel),e.additionalNetworks=S(o.networkResources),b(e,o.tags),e.database=a(o.databaseResources),e.dynamodb=f(o.dynamodbResources),e.sqs=d(o.sqsResources),e.cdn=R(o.cdnResource,o.s3Resources,o.computeResources),e.s3=p(o.s3Resources),e.compute=l(o.computeResources,o.databaseResources,o.s3Resources,e),e.additionalManagedImports=y(o.imports),t?.skipValidation)return e;try{return s.parse(e)}catch(n){if(n instanceof m.ZodError){const i=u(n);throw new Error(`Invalid infrastructure configuration:
2
+ ${i}`)}throw n}}export{E as convertToResourcePlan};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Read-only statement classifier. Classifies top-level statements in an
3
+ * infrastructure.ts file as managed (imports, app init, factory calls, tags)
4
+ * or custom (user-written code). Query helpers and custom-code-block
5
+ * extraction live in astStatementQueries.ts. Write paths live in
6
+ * src/codemod/. Do not add mutation helpers here.
7
+ */
8
+ import * as ts from "typescript";
9
+ import type { StatementType } from "../schemas/resourceSchemas.js";
10
+ /** Imports that the generator always handles -- don't preserve as "additional" */
11
+ declare const KNOWN_FJALL_IMPORTS: Set<string>;
12
+ export { KNOWN_FJALL_IMPORTS };
13
+ /** Check if a module specifier belongs to a managed (Fjall/CDK) package */
14
+ export declare function isManagedModuleSpecifier(specifier: string): boolean;
15
+ export interface ClassifiedStatement {
16
+ type: StatementType;
17
+ node: ts.Statement;
18
+ resourceName?: string;
19
+ startPos: number;
20
+ endPos: number;
21
+ isManaged: boolean;
22
+ }
23
+ /** Classify all top-level statements in an infrastructure file. */
24
+ export declare function classifyStatements(sourceFile: ts.SourceFile): ClassifiedStatement[];
@@ -0,0 +1 @@
1
+ import*as a from"typescript";import{isAppGetAppCall as p}from"./astCommonParser.js";import{S3_BUCKET_CLASSES as d}from"./astStorageParser.js";const y=new Set(["App","Architecture","DatabaseFactory","StorageFactory","ComputeFactory","getConfig","MessagingFactory","CdnFactory","Code","Runtime","FunctionUrlAuthType","NetworkFactory","PatternFactory"]);function l(r){return!!(r.startsWith("@fjall/")||r==="aws-cdk-lib"||r.startsWith("aws-cdk-lib/")||r==="constructs")}function h(r){const n=[];for(const e of r.statements){const t=e.getFullStart(),i=e.getEnd();if(a.isImportDeclaration(e)){n.push({type:"import",node:e,startPos:t,endPos:i,isManaged:g(e)});continue}if(a.isVariableStatement(e)){n.push(m(e,t,i));continue}if(a.isExpressionStatement(e)){n.push(x(e,t,i));continue}n.push({type:"custom",node:e,startPos:t,endPos:i,isManaged:!1})}return n}function g(r){return a.isStringLiteral(r.moduleSpecifier)?l(r.moduleSpecifier.text):!1}function m(r,n,e){for(const t of r.declarationList.declarations)if(t.initializer){if(p(t.initializer))return{type:"app-init",node:r,resourceName:a.isIdentifier(t.name)?t.name.text:void 0,startPos:n,endPos:e,isManaged:!0};if(a.isIdentifier(t.name)&&t.name.text==="appName"&&a.isStringLiteral(t.initializer))return{type:"app-init",node:r,startPos:n,endPos:e,isManaged:!0};if(a.isNewExpression(t.initializer)){const i=t.initializer;if(a.isIdentifier(i.expression)){const s=i.expression.text;if(d.has(s)){const c=i.arguments&&i.arguments.length>=2&&a.isStringLiteral(i.arguments[1])?i.arguments[1].text:void 0;return{type:"storage",node:r,resourceName:c,startPos:n,endPos:e,isManaged:!0}}}}if(a.isCallExpression(t.initializer)){const i=u(t.initializer,r,n,e);if(i.type!=="custom")return i}}return{type:"custom",node:r,startPos:n,endPos:e,isManaged:!1}}function x(r,n,e){const t=r.expression;return a.isCallExpression(t)?u(t,r,n,e):{type:"custom",node:r,startPos:n,endPos:e,isManaged:!1}}function u(r,n,e,t){const i=r.expression;if(a.isPropertyAccessExpression(i)&&a.isIdentifier(i.expression)){const s=i.name.text;if(s==="addTags")return{type:"tags",node:n,startPos:e,endPos:t,isManaged:!0};const o={addDatabase:{type:"database",factory:"DatabaseFactory"},addCompute:{type:"compute",factory:"ComputeFactory"},addNetwork:{type:"network",factory:"NetworkFactory"},addMessaging:{type:"messaging",factory:"MessagingFactory"},addCdn:{type:"cdn",factory:"CdnFactory"},addPattern:{type:"pattern",factory:"PatternFactory"},addStorage:{type:"storage",factory:"StorageFactory"}}[s];if(o){const f=S(r,o.factory);return{type:o.type,node:n,resourceName:f,startPos:e,endPos:t,isManaged:!0}}}return{type:"custom",node:n,startPos:e,endPos:t,isManaged:!1}}function S(r,n){if(r.arguments.length===0)return;const e=r.arguments[0];if(!a.isCallExpression(e))return;const t=e.expression;if(!a.isPropertyAccessExpression(t)||t.name.text!=="build"||!a.isIdentifier(t.expression)||t.expression.text!==n||e.arguments.length===0)return;const i=e.arguments[0];if(a.isStringLiteral(i))return i.text}export{y as KNOWN_FJALL_IMPORTS,h as classifyStatements,l as isManagedModuleSpecifier};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Read-only query and custom-code-block helpers built on top of the
3
+ * statement classifier. Split out of astStatementClassifier.ts to keep both
4
+ * files within the 400-line budget. Write paths live in src/codemod/. Do not
5
+ * add mutation helpers here.
6
+ */
7
+ import * as ts from "typescript";
8
+ import type { StatementType, CustomCodeBlock } from "../schemas/resourceSchemas.js";
9
+ import { type ClassifiedStatement } from "./astStatementClassifier.js";
10
+ /** Extract custom code blocks from an infrastructure file. */
11
+ export declare function extractCustomCodeBlocks(sourceFile: ts.SourceFile, precomputedClassifications?: ClassifiedStatement[]): CustomCodeBlock[];
12
+ /** Find the position information for a specific managed resource. */
13
+ export declare function findManagedResourcePosition(sourceFile: ts.SourceFile, resourceType: StatementType, resourceName: string, precomputedClassifications?: ClassifiedStatement[]): {
14
+ startPos: number;
15
+ endPos: number;
16
+ node: ts.Statement;
17
+ } | null;
18
+ /** Get the last managed statement of a specific type. */
19
+ export declare function getLastManagedStatementOfType(sourceFile: ts.SourceFile, type: StatementType, precomputedClassifications?: ClassifiedStatement[]): ClassifiedStatement | null;
20
+ /** Get all managed resources grouped by type. */
21
+ export declare function getManagedResourcesByType(sourceFile: ts.SourceFile, precomputedClassifications?: ClassifiedStatement[]): Record<StatementType, ClassifiedStatement[]>;
@@ -0,0 +1,3 @@
1
+ import*as p from"typescript";import{classifyStatements as a}from"./astStatementClassifier.js";const d={import:"after-imports","app-init":"after-app-init",tags:"after-tags"};function g(t){if(!t)return{position:"before-imports"};const n=d[t.type];return n?{position:n}:{position:"after-resource",afterManagedResource:{type:t.type,name:t.resourceName}}}function C(t,n){const i=n??a(t),o=[],s=t.getFullText();let e=null;for(const r of i)if(r.type==="custom"&&!r.isManaged){const{position:c,afterManagedResource:u}=g(e),m=x(s,r.node),f=y(s,r.node),l=t.getLineAndCharacterOfPosition(r.node.getStart());o.push({sourceText:m,position:c,afterManagedResource:u,originalLine:l.line+1,leadingComments:f.length>0?f:void 0})}else r.isManaged&&(e=r);return o}function x(t,n){const i=n.getFullStart(),o=n.getEnd(),e=t.slice(i,o).split(`
2
+ `),r=e.findIndex(c=>c.trim()!=="");return e.slice(r===-1?0:r).join(`
3
+ `)}function y(t,n){const i=[],o=p.getLeadingCommentRanges(t,n.getFullStart());if(o)for(const s of o){const e=t.slice(s.pos,s.end);i.push(e)}return i}function P(t,n,i,o){const s=o??a(t);for(const e of s)if(e.type===n&&e.resourceName===i)return{startPos:e.startPos,endPos:e.endPos,node:e.node};return null}function S(t,n,i){const o=i??a(t);let s=null;for(const e of o)e.type===n&&e.isManaged&&(s=e);return s}function h(t,n){const i=n??a(t),o={import:[],"app-init":[],tags:[],database:[],compute:[],storage:[],network:[],messaging:[],cdn:[],pattern:[],custom:[]};for(const s of i)o[s.type].push(s);return o}export{C as extractCustomCodeBlocks,P as findManagedResourcePosition,S as getLastManagedStatementOfType,h as getManagedResourcesByType};
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Read-only AST parser for the storage (S3) section of infrastructure.ts.
3
+ * Used by fjall list and by the deploy-worker's convertToResourcePlan. Write
4
+ * paths live in src/codemod/. Do not add mutation helpers here.
5
+ */
1
6
  import * as ts from "typescript";
2
7
  import { type ApplicationResourcePlan } from "../schemas/resourceSchemas.js";
3
8
  import { type ParsedObject } from "./astCommonParser.js";