@fjall/generator 0.95.0 → 0.99.1

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 (166) hide show
  1. package/dist/.minified +1 -1
  2. package/dist/src/ast/astClickHouseParser.d.ts +25 -0
  3. package/dist/src/ast/astClickHouseParser.js +1 -0
  4. package/dist/src/ast/astCodeInjection.d.ts +9 -0
  5. package/dist/src/ast/astCodeInjection.js +8 -0
  6. package/dist/src/ast/astComputeParser.js +1 -1
  7. package/dist/src/ast/astComputeParserHelpers.js +1 -1
  8. package/dist/src/ast/astDatabaseParser.d.ts +5 -2
  9. package/dist/src/ast/astDatabaseParser.js +1 -1
  10. package/dist/src/ast/astInfrastructureParser.d.ts +7 -1
  11. package/dist/src/ast/astInfrastructureParser.js +1 -1
  12. package/dist/src/ast/astPlanConverter.js +2 -2
  13. package/dist/src/ast/astScheduleParser.d.ts +18 -0
  14. package/dist/src/ast/astScheduleParser.js +1 -0
  15. package/dist/src/ast/astStatementClassifier.d.ts +2 -2
  16. package/dist/src/ast/astStatementClassifier.js +1 -1
  17. package/dist/src/ast/astStatementQueries.d.ts +4 -4
  18. package/dist/src/ast/astStatementQueries.js +3 -3
  19. package/dist/src/ast/astSurgicalModification.d.ts +14 -12
  20. package/dist/src/ast/astSurgicalModification.js +6 -13
  21. package/dist/src/ast/astTestHelpers.d.ts +41 -7
  22. package/dist/src/ast/index.d.ts +3 -2
  23. package/dist/src/ast/index.js +1 -1
  24. package/dist/src/codemod/_internal.d.ts +6 -1
  25. package/dist/src/codemod/_internal.js +1 -1
  26. package/dist/src/codemod/drift/detect.d.ts +11 -0
  27. package/dist/src/codemod/drift/detect.js +1 -0
  28. package/dist/src/codemod/drift/index.d.ts +4 -0
  29. package/dist/src/codemod/drift/index.js +1 -0
  30. package/dist/src/codemod/drift/merge.d.ts +19 -0
  31. package/dist/src/codemod/drift/merge.js +1 -0
  32. package/dist/src/codemod/drift/snapshot.d.ts +4 -0
  33. package/dist/src/codemod/drift/snapshot.js +1 -0
  34. package/dist/src/codemod/drift/types.d.ts +60 -0
  35. package/dist/src/codemod/drift/types.js +1 -0
  36. package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +1 -1
  37. package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -1
  38. package/dist/src/codemod/edits/addResource.d.ts +8 -3
  39. package/dist/src/codemod/edits/addResource.js +1 -1
  40. package/dist/src/codemod/edits/controlFlowPolicy.d.ts +19 -0
  41. package/dist/src/codemod/edits/controlFlowPolicy.js +1 -0
  42. package/dist/src/codemod/edits/crossPlanConnection.d.ts +20 -0
  43. package/dist/src/codemod/edits/crossPlanConnection.js +1 -0
  44. package/dist/src/codemod/edits/driftPolicy.d.ts +7 -0
  45. package/dist/src/codemod/edits/driftPolicy.js +1 -0
  46. package/dist/src/codemod/edits/findInsertionPosition.js +1 -1
  47. package/dist/src/codemod/edits/index.d.ts +3 -0
  48. package/dist/src/codemod/edits/index.js +1 -1
  49. package/dist/src/codemod/edits/modifyResource.d.ts +9 -3
  50. package/dist/src/codemod/edits/modifyResource.js +1 -1
  51. package/dist/src/codemod/edits/removeResource.d.ts +2 -2
  52. package/dist/src/codemod/edits/removeResource.js +1 -1
  53. package/dist/src/codemod/edits/vpcPeer.d.ts +24 -0
  54. package/dist/src/codemod/edits/vpcPeer.js +1 -0
  55. package/dist/src/codemod/edits/vpcPeerAccepter.d.ts +20 -0
  56. package/dist/src/codemod/edits/vpcPeerAccepter.js +1 -0
  57. package/dist/src/codemod/index.d.ts +16 -4
  58. package/dist/src/codemod/index.js +1 -1
  59. package/dist/src/codemod/llmFallback/apply.d.ts +10 -0
  60. package/dist/src/codemod/llmFallback/apply.js +1 -0
  61. package/dist/src/codemod/llmFallback/claudeTier.d.ts +6 -0
  62. package/dist/src/codemod/llmFallback/claudeTier.js +1 -0
  63. package/dist/src/codemod/llmFallback/egressGate.d.ts +5 -0
  64. package/dist/src/codemod/llmFallback/egressGate.js +1 -0
  65. package/dist/src/codemod/llmFallback/egressGate.types.d.ts +9 -0
  66. package/dist/src/codemod/llmFallback/egressGate.types.js +0 -0
  67. package/dist/src/codemod/llmFallback/index.d.ts +6 -0
  68. package/dist/src/codemod/llmFallback/index.js +1 -0
  69. package/dist/src/codemod/llmFallback/morphTier.d.ts +2 -0
  70. package/dist/src/codemod/llmFallback/morphTier.js +3 -0
  71. package/dist/src/codemod/llmFallback/prompt.d.ts +12 -0
  72. package/dist/src/codemod/llmFallback/prompt.js +36 -0
  73. package/dist/src/codemod/llmFallback/runFallback.d.ts +13 -0
  74. package/dist/src/codemod/llmFallback/runFallback.js +1 -0
  75. package/dist/src/codemod/llmFallback/shouldTryFallback.d.ts +13 -0
  76. package/dist/src/codemod/llmFallback/shouldTryFallback.js +1 -0
  77. package/dist/src/codemod/llmFallback/signals.d.ts +4 -0
  78. package/dist/src/codemod/llmFallback/signals.js +1 -0
  79. package/dist/src/codemod/llmFallback/telemetryEvents.d.ts +141 -0
  80. package/dist/src/codemod/llmFallback/telemetryEvents.js +1 -0
  81. package/dist/src/codemod/llmFallback/tierRunner.d.ts +7 -0
  82. package/dist/src/codemod/llmFallback/tierRunner.js +1 -0
  83. package/dist/src/codemod/llmFallback/types.d.ts +104 -0
  84. package/dist/src/codemod/llmFallback/types.js +1 -0
  85. package/dist/src/codemod/registry.d.ts +4 -1
  86. package/dist/src/codemod/registry.js +1 -1
  87. package/dist/src/codemod/semanticIndex/classifyControlFlow.d.ts +2 -0
  88. package/dist/src/codemod/semanticIndex/classifyControlFlow.js +1 -0
  89. package/dist/src/codemod/semanticIndex/findReferences.js +2 -2
  90. package/dist/src/codemod/telemetry/errorKinds.d.ts +2 -0
  91. package/dist/src/codemod/telemetry/errorKinds.js +1 -0
  92. package/dist/src/codemod/types.d.ts +110 -1
  93. package/dist/src/codemod/types.js +1 -1
  94. package/dist/src/codemod/validationGate/gates/classify.d.ts +2 -0
  95. package/dist/src/codemod/validationGate/gates/classify.js +1 -0
  96. package/dist/src/codemod/validationGate/gates/drift.d.ts +2 -0
  97. package/dist/src/codemod/validationGate/gates/drift.js +1 -0
  98. package/dist/src/codemod/validationGate/gates/locate.d.ts +7 -0
  99. package/dist/src/codemod/validationGate/gates/locate.js +1 -0
  100. package/dist/src/codemod/validationGate/gates/parse.d.ts +2 -0
  101. package/dist/src/codemod/validationGate/gates/parse.js +1 -0
  102. package/dist/src/codemod/validationGate/gates/schema.d.ts +2 -0
  103. package/dist/src/codemod/validationGate/gates/schema.js +1 -0
  104. package/dist/src/codemod/validationGate/index.d.ts +6 -0
  105. package/dist/src/codemod/validationGate/index.js +1 -0
  106. package/dist/src/codemod/validationGate/types.d.ts +35 -0
  107. package/dist/src/codemod/validationGate/types.js +1 -0
  108. package/dist/src/detection/index.d.ts +148 -0
  109. package/dist/src/detection/index.js +1 -0
  110. package/dist/src/generation/common.d.ts +22 -0
  111. package/dist/src/generation/common.js +5 -4
  112. package/dist/src/generation/compute/ec2.d.ts +2 -0
  113. package/dist/src/generation/compute/ec2.js +4 -0
  114. package/dist/src/generation/compute/ecs.d.ts +2 -0
  115. package/dist/src/generation/compute/ecs.js +42 -0
  116. package/dist/src/generation/compute/lambda.d.ts +3 -0
  117. package/dist/src/generation/compute/lambda.js +26 -0
  118. package/dist/src/generation/compute/shared.d.ts +22 -0
  119. package/dist/src/generation/compute/shared.js +4 -0
  120. package/dist/src/generation/compute.d.ts +4 -5
  121. package/dist/src/generation/compute.js +6 -86
  122. package/dist/src/generation/database.d.ts +11 -0
  123. package/dist/src/generation/database.js +23 -12
  124. package/dist/src/generation/index.d.ts +1 -1
  125. package/dist/src/generation/index.js +1 -1
  126. package/dist/src/generation/infrastructure.js +5 -5
  127. package/dist/src/generation/storage.js +30 -30
  128. package/dist/src/index.d.ts +1 -1
  129. package/dist/src/index.js +1 -1
  130. package/dist/src/planning/index.d.ts +2 -1
  131. package/dist/src/planning/index.js +1 -1
  132. package/dist/src/planning/openNextPlanning.d.ts +38 -0
  133. package/dist/src/planning/openNextPlanning.js +1 -0
  134. package/dist/src/planning/resourceAddition.d.ts +5 -1
  135. package/dist/src/planning/resourceAddition.js +1 -1
  136. package/dist/src/planning/resourcePlanning.d.ts +0 -46
  137. package/dist/src/planning/resourcePlanning.js +1 -1
  138. package/dist/src/presets/clickhouseTierPreset.d.ts +35 -0
  139. package/dist/src/presets/clickhouseTierPreset.js +0 -0
  140. package/dist/src/presets/tierPresets.d.ts +5 -12
  141. package/dist/src/presets/tierPresets.js +1 -1
  142. package/dist/src/presets/tierTypes.d.ts +9 -19
  143. package/dist/src/schemas/applicationSchemas.d.ts +67 -8
  144. package/dist/src/schemas/applicationSchemas.js +1 -1
  145. package/dist/src/schemas/baseSchemas.d.ts +24 -5
  146. package/dist/src/schemas/baseSchemas.js +2 -2
  147. package/dist/src/schemas/computeSchemas.d.ts +108 -14
  148. package/dist/src/schemas/computeSchemas.js +1 -1
  149. package/dist/src/schemas/constants.d.ts +14 -0
  150. package/dist/src/schemas/constants.js +1 -1
  151. package/dist/src/schemas/databaseSchemas.d.ts +80 -0
  152. package/dist/src/schemas/databaseSchemas.js +1 -1
  153. package/dist/src/schemas/networkSchemas.d.ts +126 -11
  154. package/dist/src/schemas/networkSchemas.js +1 -1
  155. package/dist/src/schemas/patternSchemas.js +1 -1
  156. package/dist/src/schemas/sharedTypes.d.ts +1 -1
  157. package/dist/src/schemas/sharedTypes.js +1 -1
  158. package/dist/src/validation/patterns.d.ts +2 -318
  159. package/dist/src/validation/patterns.js +1 -1
  160. package/dist/src/validation/validationMessages.d.ts +315 -0
  161. package/dist/src/validation/validationMessages.js +1 -0
  162. package/dist/src/validation/validationPatterns.d.ts +34 -0
  163. package/dist/src/validation/validationPatterns.js +1 -0
  164. package/dist/src/version.d.ts +1 -1
  165. package/dist/src/version.js +1 -1
  166. package/package.json +19 -13
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 93 files minified at 2026-04-21T03:05:07.650Z
1
+ 137 files minified at 2026-05-22T01:26:33.556Z
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Read-only AST parser for ClickHouse analytics databases declared via
3
+ * addDatabase with type: "ClickHouse". Split out of astDatabaseParser.ts to
4
+ * keep both files within the 400-line budget. Write paths live in
5
+ * src/codemod/. Do not add mutation helpers here.
6
+ */
7
+ import * as ts from "typescript";
8
+ import type { ApplicationResourcePlan, ExtraProperty } from "../schemas/resourceSchemas.js";
9
+ import type { ParsedDatabaseResource } from "./astDatabaseParser.js";
10
+ export interface ParsedClickHouseResource {
11
+ variableName?: string;
12
+ resourceName: string;
13
+ databaseName: string;
14
+ instanceType?: string;
15
+ coldTier?: {
16
+ mode: "s3";
17
+ } | false;
18
+ optimiseSchedule?: string | false;
19
+ backupSchedule?: string | false;
20
+ backupRetentionDays?: number;
21
+ extraProperties?: ExtraProperty[];
22
+ node: ts.Node;
23
+ }
24
+ export declare function extractClickHouseFields(resource: ParsedDatabaseResource): ParsedClickHouseResource | null;
25
+ export declare function convertClickHouseResources(clickhouseResources: ParsedClickHouseResource[]): ApplicationResourcePlan["clickhouse"];
@@ -0,0 +1 @@
1
+ import*as r from"typescript";import{asNumber as b,asString as s,captureExtraProperties as S,isParsedObject as N,omitUndefined as k,parseObjectLiteral as y}from"./astCommonParser.js";const g=new Set(["type","databaseName","instanceType","coldTier","optimiseSchedule","backupSchedule","backupRetentionDays"]);function x(t){const e=t.node;if(!r.isCallExpression(e))return null;const o=e.arguments[0];if(!r.isCallExpression(o)||o.arguments.length<2)return null;const c=o.arguments[1];if(!r.isObjectLiteralExpression(c))return null;const i=y(c),a={resourceName:t.resourceName,databaseName:t.databaseName,node:t.node};t.variableName&&(a.variableName=t.variableName);const u=s(i.instanceType);u&&(a.instanceType=u);const l=i.coldTier;l===!1?a.coldTier=!1:N(l)&&s(l.mode)==="s3"&&(a.coldTier={mode:"s3"});const d=i.optimiseSchedule;if(d===!1)a.optimiseSchedule=!1;else{const n=s(d);n&&(a.optimiseSchedule=n)}const p=i.backupSchedule;if(p===!1)a.backupSchedule=!1;else{const n=s(p);n&&(a.backupSchedule=n)}const m=b(i.backupRetentionDays);m!==void 0&&(a.backupRetentionDays=m);const f=S(i,g);return f.length>0&&(a.extraProperties=f),a}function h(t){if(t.length!==0)return t.map(e=>({name:e.resourceName,type:"ClickHouse",databaseName:e.databaseName,...k({instanceType:e.instanceType,coldTier:e.coldTier,optimiseSchedule:e.optimiseSchedule,backupSchedule:e.backupSchedule,backupRetentionDays:e.backupRetentionDays,variableName:e.variableName,extraProperties:e.extraProperties})}))}export{h as convertClickHouseResources,x as extractClickHouseFields};
@@ -0,0 +1,9 @@
1
+ import { type CustomCodeBlock } from "./astInfrastructureParser.js";
2
+ import { type SurgicalModificationResult } from "./astSurgicalModification.js";
3
+ export declare function ensureImports(content: string, requiredImports: string[]): SurgicalModificationResult;
4
+ export declare function injectCustomCodeBlocks(generatedCode: string, customBlocks: CustomCodeBlock[], resourceMapping?: Map<string, string>): SurgicalModificationResult;
5
+ export interface FileValidationResult {
6
+ valid: boolean;
7
+ errors?: string[];
8
+ }
9
+ export declare function validateModifiedFile(content: string): FileValidationResult;
@@ -0,0 +1,8 @@
1
+ import*as f from"typescript";import{classifyStatements as x}from"./astInfrastructureParser.js";import{parseSourceFile as d,insertAtPosition as m,formatLeadingNewlines as C,getContextBeforePosition as y,formatResourceId as l,createErrorResult as p,findClassification as g,findLastClassification as w}from"./astSurgicalModification.js";import{getErrorMessage as P}from"../util/errorUtils.js";function q(t,e){try{const n=d(t),o=new Set;for(const i of n.statements)f.isImportDeclaration(i)&&o.add(i.getText(n).trim());const r=[];for(const i of e){const c=i.trim();[...o].some(I=>O(I,c))||r.push(c)}if(r.length===0)return{content:t,success:!0};const s=n.statements.filter(f.isImportDeclaration).at(-1)?.getEnd()??0,u=`
2
+ `+r.join(`
3
+ `);return{content:m(t,s,u),success:!0}}catch(n){return p(n,t)}}function h(t){return new Set(t.split(",").map(e=>e.trim()).filter(Boolean))}function N(t,e){const n=h(t),o=h(e);for(const r of o)if(!n.has(r))return!1;return!0}function O(t,e){const n=t.match(R),o=e.match(R);if(!n||!o||n[1]!==o[1])return!1;const r=t.match(M),s=e.match(M);return r&&s?N(r[1],s[1]):!!r==!!s}const R=/from\s+["']([^"']+)["']/,M=/\{([^}]+)\}/,E={"before-imports":0,"after-imports":1,"after-app-init":2,"after-tags":3,"after-resource":4,"end-of-file":5};function T(t){return[...t].sort((e,n)=>{const o=E[n.position]-E[e.position];return o!==0?o:(n.originalLine??0)-(e.originalLine??0)})}function A(t,e,n,o){if(n!==null){const s=F(t,n,e);return m(t,n,s)}const r=e.afterManagedResource?`// [ORPHANED: was after ${l(e.afterManagedResource.type,e.afterManagedResource.name)}]
4
+ `:`// [ORPHANED]
5
+ `;return o.push(`Custom code from line ${e.originalLine} could not be positioned. Added at end of file.`),t+`
6
+ `+r+e.sourceText}function U(t,e,n){if(!e||e.length===0)return{content:t,success:!0};try{const o=d(t),r=x(o),s=[],u=T(e);let a=t;for(const i of u){const c=D(o,r,i,n,s);a=A(a,i,c,s)}return{content:a,success:!0,warnings:s.length>0?s:void 0}}catch(o){return p(o,t)}}function S(t,e,n,o){if(!e.afterManagedResource)return null;const r=e.afterManagedResource,s=(r.name&&n?.get(r.name))??r.name,u=t.find(i=>i.type===r.type&&i.resourceName===s);if(u)return u.endPos;const a=t.filter(i=>i.type===r.type&&i.isManaged);return a.length===1?a[0].endPos:(o&&o.push(`Resource ${l(e.afterManagedResource.type,e.afterManagedResource.name)} not found. Custom code may be orphaned.`),null)}function D(t,e,n,o,r){switch(n.position){case"before-imports":return 0;case"after-imports":return w(e,"import")?.endPos??0;case"after-app-init":return g(e,"app-init")?.endPos??null;case"after-tags":return g(e,"tags")?.endPos??null;case"after-resource":return S(e,n,o,r);case"end-of-file":return t.getEnd();default:return null}}function F(t,e,n){const o=y(t,e);let r=n.sourceText;return r=C(o,r)+r,r.endsWith(`
7
+ `)||(r+=`
8
+ `),r}function $(t){try{let o=function(r){r.kind===f.SyntaxKind.Unknown&&n.push("Unknown node found in AST - possible parse error"),f.forEachChild(r,o)};const e=d(t),n=[];return o(e),n.length>0?{valid:!1,errors:n}:{valid:!0}}catch(e){return{valid:!1,errors:[P(e)]}}}export{q as ensureImports,U as injectCustomCodeBlocks,$ as validateModifiedFile};
@@ -1 +1 @@
1
- import*as S from"typescript";import{asString as a,asNumber as f,asBoolean as v,asStringArray as E,asStringUnion as d,captureExtraProperties as l,collectFromAst as C,extractVariableName as u,isFactoryBuildCall as m,isFactoryMethodCall as b,isParsedObject as g,parseObjectLiteral as x}from"./astCommonParser.js";import{COMPUTE_TYPES as T,DEPLOYMENT_TYPES as A,EC2_INSTANCE_TYPES as D}from"../schemas/constants.js";import{assignIfDefined as o,extractCallStringArg as _,extractClusterConfig as O,extractEnumString as y,isEnvironmentRecord as N,parseEcsService as R}from"./astComputeParserHelpers.js";import{inferDatabaseConnectionsFromEnv as Y,inferStorageConnectionsFromEnv as F,resolveConnectedDatabaseNames as U,resolveConnectedStorageNames as k}from"./astComputeConnectionParser.js";function K(e){if(e.arguments.length<2)return null;const n=e.arguments[0],i=e.arguments[1];if(!S.isStringLiteral(n)||!S.isObjectLiteralExpression(i))return null;const t=n.text,r=x(i);return{resourceName:t,type:a(r.type)??"ecs",config:r,node:e}}function w(e){return C(e,n=>{if(!S.isCallExpression(n)||!b(n,"addCompute"))return null;const i=n.arguments[0];if(!m(i,"ComputeFactory"))return null;const t=K(i);if(t){const r=u(n);r&&(t.variableName=r)}return t})}function L(e,n){o(n,"dockerfilePath",a(e.config.dockerfilePath));const i=e.config.cluster;i!==void 0&&(n.cluster=O(i));const t=e.config.services;t!==void 0&&Array.isArray(t)&&(n.services=t.filter(s=>g(s)).map(R));const r=new Set(["type","ecrRepository","dockerfilePath","cluster","services","connections"]),c=l(e.config,r);c.length>0&&(n.extraProperties=c)}function V(e,n){if(o(n,"deployment",d(e.config.deployment,A)),o(n,"timeout",f(e.config.timeout)),o(n,"memory",f(e.config.memorySize)??f(e.config.memory)),o(n,"handler",a(e.config.handler)),o(n,"runtime",y(e.config.runtime,"Runtime")),N(e.config.environment)&&(n.environment=e.config.environment),N(e.config.secrets))n.secrets=e.config.secrets;else{const s=E(e.config.secrets);s&&(n.ssmSecrets=s)}const i=e.config.functionUrl;if(g(i)){const s=y(i.authType,"FunctionUrlAuthType");(s==="NONE"||s==="AWS_IAM")&&(n.functionUrl={authType:s})}const t=e.config.code;if(t!==void 0){const s=_(t);s&&(n.codePath=s)}o(n,"description",a(e.config.lambdaDescription)),o(n,"scheduleExpression",a(e.config.scheduleExpression)),o(n,"architecture",y(e.config.architecture,"Architecture")),o(n,"ephemeralStorageSize",f(e.config.ephemeralStorageSize)),o(n,"functionName",a(e.config.functionName)),o(n,"ssmSecretsPath",a(e.config.ssmSecretsPath));const r=new Set(["type","deployment","timeout","memorySize","memory","handler","runtime","environment","secrets","functionUrl","code","connections","ecrRepository","containerSecretsImport","lambdaDescription","scheduleExpression","architecture","ephemeralStorageSize","functionName","ssmSecretsPath"]),c=l(e.config,r);c.length>0&&(n.extraProperties=c)}function z(e,n){o(n,"instanceType",d(e.config.instanceType,D));const i=e.config.ssh;i===!1?n.enableSSH=!1:i!==void 0&&g(i)?n.enableSSH=!0:o(n,"enableSSH",v(e.config.enableSSH)),o(n,"keyName",a(e.config.keyName)),o(n,"userData",a(e.config.userData)),e.config.securityGroups!==void 0&&(n.securityGroups=E(e.config.securityGroups));const t=new Set(["type","instanceType","ssh","enableSSH","keyName","userData","securityGroups","connections"]),r=l(e.config,t);r.length>0&&(n.extraProperties=r)}function H(e,n,i,t){let r=n.config.connections;if(!r&&Array.isArray(n.config.services)){const h=n.config.services[0];g(h)&&(r=h.connections)}if(!r)return;const c=U(r,i);c.length>0&&(e.needsConnection=!0,e.connectedDatabase=c);const s=k(r,t);s.length>0&&(e.connectedStorage=s)}function M(e,n){({ecs:L,lambda:V,ec2:z})[e.type]?.(n,e)}function B(e,n,i,t){return e.map(r=>{const c=d(r.config.type,T)??"ecs",s={name:r.resourceName,type:c,needsConnection:!1,connectedDatabase:[],...r.variableName&&{variableName:r.variableName}};return H(s,r,n,i),M(s,r),Y(s,r.config.services,t.database),F(s,r.config.services,t.s3),s})}export{B as convertComputeResources,w as findComputeResources};
1
+ import*as l from"typescript";import{asString as a,asNumber as S,asBoolean as h,asStringArray as u,asStringUnion as g,captureExtraProperties as v,collectFromAst as m,extractVariableName as T,isFactoryBuildCall as _,isFactoryMethodCall as b,isParsedObject as d,parseObjectLiteral as A}from"./astCommonParser.js";import{COMPUTE_ARCHITECTURES as x,COMPUTE_TYPES as O,DEPLOYMENT_TYPES as D,EC2_INSTANCE_TYPES as R,FUNCTION_URL_AUTH_TYPES as Y}from"../schemas/constants.js";import{assignIfDefined as c,extractCallStringArg as K,extractClusterConfig as U,extractEnumString as E,isEnvironmentRecord as C,parseEcsService as F}from"./astComputeParserHelpers.js";import{inferDatabaseConnectionsFromEnv as L,inferStorageConnectionsFromEnv as k,resolveConnectedDatabaseNames as H,resolveConnectedStorageNames as V}from"./astComputeConnectionParser.js";function M(e){if(e.arguments.length<2)return null;const n=e.arguments[0],i=e.arguments[1];if(!l.isStringLiteral(n)||!l.isObjectLiteralExpression(i))return null;const t=n.text,r=A(i);return{resourceName:t,type:a(r.type)??"ecs",config:r,node:e}}function J(e){return m(e,n=>{if(!l.isCallExpression(n)||!b(n,"addCompute"))return null;const i=n.arguments[0];if(!_(i,"ComputeFactory"))return null;const t=M(i);if(t){const r=T(n);r&&(t.variableName=r)}return t})}function N(e,n,i){const t=v(e.config,i);t.length>0&&(n.extraProperties=t)}function W(e,n){const i=e.config.docker;if(d(i)){const o=a(i.path),f=a(i.context),y=a(i.target);(o!==void 0||f!==void 0||y!==void 0)&&(n.docker={...o!==void 0&&{path:o},...f!==void 0&&{context:f},...y!==void 0&&{target:y}})}const t=e.config.cluster;t!==void 0&&(n.cluster=U(t));const r=e.config.services;r!==void 0&&Array.isArray(r)&&(n.services=r.filter(o=>d(o)).map(F)),N(e,n,new Set(["type","ecrRepository","docker","cluster","services","connections"]))}function z(e,n){if(c(n,"deployment",g(e.config.deployment,D)),c(n,"timeout",S(e.config.timeout)),c(n,"memory",S(e.config.memorySize)??S(e.config.memory)),c(n,"handler",a(e.config.handler)),c(n,"runtime",E(e.config.runtime,"Runtime")),C(e.config.environment)&&(n.environment=e.config.environment),C(e.config.secrets))n.secrets=e.config.secrets;else{const s=u(e.config.secrets);s&&(n.ssmSecrets=s)}const i=e.config.functionUrl;if(d(i)){const s=g(E(i.authType,"FunctionUrlAuthType"),Y);s!==void 0&&(n.functionUrl={authType:s})}const t=e.config.code;if(t!==void 0){const s=K(t);s&&(n.codePath=s)}c(n,"description",a(e.config.lambdaDescription)),c(n,"architecture",g(E(e.config.architecture,"Architecture"),x)),c(n,"ephemeralStorageSize",S(e.config.ephemeralStorageSize)),c(n,"functionName",a(e.config.functionName)),c(n,"ssmSecretsPath",a(e.config.ssmSecretsPath)),N(e,n,new Set(["type","deployment","timeout","memorySize","memory","handler","runtime","environment","secrets","functionUrl","code","connections","ecrRepository","containerSecretsImport","lambdaDescription","architecture","ephemeralStorageSize","functionName","ssmSecretsPath"]))}function I(e,n){c(n,"instanceType",g(e.config.instanceType,R));const i=e.config.ssh;i===!1?n.enableSSH=!1:i!==void 0&&d(i)?n.enableSSH=!0:c(n,"enableSSH",h(e.config.enableSSH)),c(n,"keyName",a(e.config.keyName)),c(n,"userData",a(e.config.userData)),e.config.securityGroups!==void 0&&(n.securityGroups=u(e.config.securityGroups)),N(e,n,new Set(["type","instanceType","ssh","enableSSH","keyName","userData","securityGroups","connections"]))}function B(e,n,i,t){let r=n.config.connections;if(!r&&Array.isArray(n.config.services)){const f=n.config.services[0];d(f)&&(r=f.connections)}if(!r)return;const s=H(r,i);s.length>0&&(e.needsConnection=!0,e.connectedDatabase=s);const o=V(r,t);o.length>0&&(e.connectedStorage=o)}function G(e,n){({ecs:W,lambda:z,ec2:I})[e.type]?.(n,e)}function Q(e,n,i,t){return e.map(r=>{const s=g(r.config.type,O)??"ecs",o={name:r.resourceName,type:s,needsConnection:!1,connectedDatabase:[],...r.variableName&&{variableName:r.variableName}};return B(o,r,n,i),G(o,r),L(o,r.config.services,t.database),k(o,r.config.services,t.s3),o})}export{Q as convertComputeResources,J as findComputeResources};
@@ -1 +1 @@
1
- import{isPlainObject as u,isParsedObject as a,isExpressionRef as S,isCallRef as y,asString as n,asNumber as r,asBoolean as d,asStringArray as c,asStringUnion as m,captureExtraProperties as p}from"./astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as h}from"../schemas/constants.js";const C=["public","internal"];function P(e){return e!==void 0&&u(e)}function E(e){if(!a(e))return;const t={};for(const[i,o]of Object.entries(e))if(a(o)){const s=n(o.id),f=n(o.name);s&&f&&(t[i]={id:s,name:f,field:n(o.field)})}return Object.keys(t).length>0?t:void 0}function A(e){if(!a(e))return;const t=c(e.command);if(!(!t||t.length===0))return{command:t,interval:r(e.interval),timeout:r(e.timeout),retries:r(e.retries),startPeriod:r(e.startPeriod)}}function _(e){const i=p(e,new Set(["name","image","port","environment","essential","command","entryPoint","secretsImport","secrets","healthCheck"]));return{name:n(e.name),image:n(e.image),port:r(e.port),environment:P(e.environment)?e.environment:void 0,essential:d(e.essential),command:c(e.command),entryPoint:c(e.entryPoint),secretsImport:E(e.secretsImport),ssmSecrets:c(e.secrets),healthCheck:A(e.healthCheck),extraProperties:i.length>0?i:void 0}}function x(e){if(Array.isArray(e))return e.filter(a).map(t=>({path:n(t.path),host:n(t.host),priority:r(t.priority),healthCheckPath:n(t.healthCheckPath)}));if(a(e))return{path:n(e.path),host:n(e.host),priority:r(e.priority),healthCheckPath:n(e.healthCheckPath)}}const g=["CPU","MEMORY"],l=["ARM","STANDARD"];function R(e){if(e===!1)return!1;if(a(e))return{minCapacity:r(e.minCapacity),maxCapacity:r(e.maxCapacity),desiredCount:r(e.desiredCount),scalingType:m(e.scalingType,g)}}function T(e){if(!a(e))return;const t=e.warmPool,i=a(t)?{minSize:r(t.minSize),reuseOnScaleIn:d(t.reuseOnScaleIn)}:void 0;return{instanceType:n(e.instanceType),amiHardwareType:m(e.amiHardwareType,l),minCapacity:r(e.minCapacity),maxCapacity:r(e.maxCapacity),memoryLimitMiB:r(e.memoryLimitMiB),warmPool:i}}function I(e){if(!a(e))return;const t=e.loadBalancer;return{domain:n(e.domain),loadBalancer:t===!1?!1:m(t,C),directAccess:d(e.directAccess)}}function k(e){const t=e.containers,i=Array.isArray(t)?t.filter(a).map(_):void 0,s=p(e,new Set(["name","image","dockerfilePath","dockerTarget","ssmSecretsPath","containers","routing","connections","cpu","memoryLimitMiB","desiredCount","scaling","capacityProvider","ec2Config"]));return{name:n(e.name)??"",image:n(e.image),dockerfilePath:n(e.dockerfilePath),dockerTarget:n(e.dockerTarget),ssmSecretsPath:n(e.ssmSecretsPath),containers:i,routing:x(e.routing),cpu:r(e.cpu),memoryLimitMiB:r(e.memoryLimitMiB),desiredCount:r(e.desiredCount),scaling:R(e.scaling),capacityProvider:m(e.capacityProvider,h)??"FARGATE",ec2Config:T(e.ec2Config),...s.length>0&&{extraProperties:s}}}function B(e,t){const i=n(e);if(i)return i;if(S(e)&&e.__expression.startsWith(t+"."))return e.__expression.slice(t.length+1)}function M(e){return y(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}function Y(e,t,i){i!==void 0&&(e[t]=i)}export{Y as assignIfDefined,M as extractCallStringArg,I as extractClusterConfig,B as extractEnumString,P as isEnvironmentRecord,k as parseEcsService};
1
+ import{isPlainObject as u,isParsedObject as o,isExpressionRef as S,isCallRef as y,asString as r,asNumber as i,asBoolean as p,asStringArray as c,asStringUnion as m,captureExtraProperties as d}from"./astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as C,LOAD_BALANCER_TYPES as h,SCALING_TYPES as E,AMI_HARDWARE_TYPES as P}from"../schemas/constants.js";function _(e){return e!==void 0&&u(e)}function x(e){if(!o(e))return;const n={};for(const[t,a]of Object.entries(e))if(o(a)){const s=r(a.id),f=r(a.name);s&&f&&(n[t]={id:s,name:f,field:r(a.field)})}return Object.keys(n).length>0?n:void 0}function A(e){if(!o(e))return;const n=c(e.command);if(!(!n||n.length===0))return{command:n,interval:i(e.interval),timeout:i(e.timeout),retries:i(e.retries),startPeriod:i(e.startPeriod)}}function N(e){const t=d(e,new Set(["name","image","port","environment","essential","command","entryPoint","secretsImport","secrets","healthCheck"]));return{name:r(e.name),image:r(e.image),port:i(e.port),environment:_(e.environment)?e.environment:void 0,essential:p(e.essential),command:c(e.command),entryPoint:c(e.entryPoint),secretsImport:x(e.secretsImport),ssmSecrets:c(e.secrets),healthCheck:A(e.healthCheck),extraProperties:t.length>0?t:void 0}}function g(e){if(Array.isArray(e))return e.filter(o).map(n=>({path:r(n.path),host:r(n.host),priority:i(n.priority),healthCheckPath:r(n.healthCheckPath)}));if(o(e))return{path:r(e.path),host:r(e.host),priority:i(e.priority),healthCheckPath:r(e.healthCheckPath)}}function O(e){if(e===!1)return!1;if(o(e))return{minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),desiredCount:i(e.desiredCount),scalingType:m(e.scalingType,E)}}const T=new Set(["instanceType","amiHardwareType","minCapacity","maxCapacity","memoryLimitMiB","warmPool"]);function I(e){if(!o(e))return;const n=e.warmPool,t=o(n)?{minSize:i(n.minSize),reuseOnScaleIn:p(n.reuseOnScaleIn)}:void 0,a=d(e,T);return{instanceType:r(e.instanceType),amiHardwareType:m(e.amiHardwareType,P),minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),memoryLimitMiB:i(e.memoryLimitMiB),warmPool:t,extraProperties:a.length>0?a:void 0}}const R=new Set(["domain","loadBalancer","directAccess"]);function w(e){if(!o(e))return;const n=e.loadBalancer,t=d(e,R);return{domain:r(e.domain),loadBalancer:n===!1?!1:m(n,h),directAccess:p(e.directAccess),...t.length>0&&{extraProperties:t}}}function L(e){const n=e.containers,t=Array.isArray(n)?n.filter(o).map(N):void 0,s=d(e,new Set(["name","image","docker","ssmSecretsPath","containers","routing","connections","cpu","memoryLimitMiB","desiredCount","scaling","capacityProvider","ec2Config"]));return{name:r(e.name)??"",image:r(e.image),docker:l(e.docker),ssmSecretsPath:r(e.ssmSecretsPath),containers:t,routing:g(e.routing),cpu:i(e.cpu),memoryLimitMiB:i(e.memoryLimitMiB),desiredCount:i(e.desiredCount),scaling:O(e.scaling),capacityProvider:m(e.capacityProvider,C)??"FARGATE",ec2Config:I(e.ec2Config),...s.length>0&&{extraProperties:s}}}function l(e){if(!o(e))return;const n=r(e.path);if(n===void 0)return;const t=r(e.context),a=r(e.target);return{path:n,...t!==void 0&&{context:t},...a!==void 0&&{target:a}}}function Y(e,n){const t=r(e);if(t)return t;if(S(e)&&e.__expression.startsWith(n+"."))return e.__expression.slice(n.length+1)}function k(e){return y(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}function W(e,n,t){t!==void 0&&(e[n]=t)}export{W as assignIfDefined,k as extractCallStringArg,w as extractClusterConfig,Y as extractEnumString,_ as isEnvironmentRecord,L as parseEcsService};
@@ -8,7 +8,9 @@
8
8
  import * as ts from "typescript";
9
9
  import type { ApplicationResourcePlan, ExtraProperty } from "../schemas/resourceSchemas.js";
10
10
  import { type ParsedDynamoDBResource } from "./astDynamoDBParser.js";
11
+ import { type ParsedClickHouseResource } from "./astClickHouseParser.js";
11
12
  export { type ParsedDynamoDBResource, convertDynamoDBResources, } from "./astDynamoDBParser.js";
13
+ export { type ParsedClickHouseResource, convertClickHouseResources, } from "./astClickHouseParser.js";
12
14
  interface ParsedProxyConfig {
13
15
  maxConnections?: number;
14
16
  maxIdleConnections?: number;
@@ -80,10 +82,11 @@ export interface ParsedDatabaseResource {
80
82
  }
81
83
  /** Find all database resources (including DynamoDB) from addDatabase calls */
82
84
  export declare function findDatabaseResources(sourceFile: ts.SourceFile): ParsedDatabaseResource[];
83
- /** Split DynamoDB resources (type: "DynamoDB") from regular database resources */
84
- export declare function splitDynamoDBFromDatabases(allResources: ParsedDatabaseResource[]): {
85
+ /** Split non-RDS resources (DynamoDB, ClickHouse) from regular database resources */
86
+ export declare function splitDatabaseResources(allResources: ParsedDatabaseResource[]): {
85
87
  databases: ParsedDatabaseResource[];
86
88
  dynamodb: ParsedDynamoDBResource[];
89
+ clickhouse: ParsedClickHouseResource[];
87
90
  };
88
91
  /** Convert parsed database resources to plan format */
89
92
  export declare function convertDatabaseResources(databaseResources: ParsedDatabaseResource[]): ApplicationResourcePlan["database"];
@@ -1 +1 @@
1
- import*as l from"typescript";import{constIncludes as R}from"../schemas/constants.js";import{asBoolean as c,asNumber as p,asString as o,asStringArray as x,captureExtraProperties as I,collectFromAst as A,extractVariableName as S,isCallRef as f,isFactoryBuildCall as D,isFactoryMethodCall as E,omitUndefined as h,parseObjectLiteral as w,parseOptionalConfig as m,parseBooleanOrConfig as g,resolveTemplateLiteral as N,typed as a}from"./astCommonParser.js";import{extractDynamoDBFields as v}from"./astDynamoDBParser.js";import{convertDynamoDBResources as O}from"./astDynamoDBParser.js";function P(t){const e=o(t.databaseEngine);if(e==="postgresql"||e==="mysql")return e;const i=t.engine;if(f(i)){const r=String(i.__call);if(r.includes("postgres")||r.includes("auroraPostgres"))return"postgresql";if(r.includes("mysql")||r.includes("auroraMysql"))return"mysql"}}function W(t){const e=t.engine;if(f(e))return String(e.__call)}const B=new Set(["type","databaseName","databaseEngine","engine","vpc","port","deletionProtection","instanceType","multiAz","publiclyAccessible","enableSecretRotation","encryption","databaseInsights","proxy","readReplica","credentials","writer","readers","backupRetention","preferredMaintenanceWindow","primaryRegion","secondaryRegions","globalClusterIdentifier","enableGlobalWriteForwarding","snapshotIdentifier","allocatedStorage","monitoringInterval","snapshotUsername"]);function F(t,e,i){if(i.arguments.length<2)return null;const r=i.arguments[0],s=i.arguments[1];if(!l.isStringLiteral(r)&&!l.isTemplateExpression(r))return null;const b=l.isStringLiteral(r)?r.text:N(t,r);if(!l.isObjectLiteralExpression(s))return null;const n=w(s),u={resourceName:b,type:o(n.type)??"",databaseName:o(n.databaseName)??"",databaseEngine:P(n),engineExpression:W(n),port:p(n.port),deletionProtection:c(n.deletionProtection),instanceType:o(n.instanceType),multiAz:c(n.multiAz),publiclyAccessible:c(n.publiclyAccessible),enableSecretRotation:c(n.enableSecretRotation),encryption:m(n.encryption,a()),databaseInsights:g(n.databaseInsights,a()),proxy:g(n.proxy,a()),readReplica:g(n.readReplica,a()),credentials:m(n.credentials,a()),writer:m(n.writer,a()),readers:g(n.readers,a()),backupRetention:p(n.backupRetention),preferredMaintenanceWindow:o(n.preferredMaintenanceWindow),primaryRegion:o(n.primaryRegion),secondaryRegions:x(n.secondaryRegions),globalClusterIdentifier:o(n.globalClusterIdentifier),enableGlobalWriteForwarding:c(n.enableGlobalWriteForwarding),allocatedStorage:p(n.allocatedStorage),monitoringInterval:p(n.monitoringInterval),snapshotIdentifier:o(n.snapshotIdentifier),snapshotUsername:o(n.snapshotUsername),node:e},d=S(e);d&&(u.variableName=d);const y=I(n,B);return y.length>0&&(u.extraProperties=y),u}function q(t){return A(t,e=>{if(!l.isCallExpression(e)||!E(e,"addDatabase"))return null;const i=e.arguments[0];return D(i,"DatabaseFactory")?F(t,e,i):null})}function G(t){const e=[],i=[];for(const r of t)if(r.type==="DynamoDB"){const s=v(r);s&&i.push(s)}else e.push(r);return{databases:e,dynamodb:i}}const T=["Instance","Aurora","GlobalAurora"];function L(t){return t.filter(e=>e.type!=="DynamoDB").map(e=>({name:e.resourceName,type:R(T,e.type)?e.type:"Instance",databaseName:e.databaseName,...h({port:e.port,deletionProtection:e.deletionProtection,instanceType:e.instanceType,multiAz:e.multiAz,publiclyAccessible:e.publiclyAccessible,enableSecretRotation:e.enableSecretRotation,encryption:e.encryption,databaseInsights:e.databaseInsights,proxy:e.proxy,readReplica:e.readReplica,credentials:e.credentials,writer:e.writer,readers:e.readers,backupRetention:e.backupRetention,preferredMaintenanceWindow:e.preferredMaintenanceWindow,primaryRegion:e.primaryRegion,secondaryRegions:e.secondaryRegions,globalClusterIdentifier:e.globalClusterIdentifier,enableGlobalWriteForwarding:e.enableGlobalWriteForwarding,allocatedStorage:e.allocatedStorage,monitoringInterval:e.monitoringInterval,variableName:e.variableName,databaseEngine:e.databaseEngine,engineExpression:e.engineExpression,extraProperties:e.extraProperties})}))}export{L as convertDatabaseResources,O as convertDynamoDBResources,q as findDatabaseResources,G as splitDynamoDBFromDatabases};
1
+ import*as c from"typescript";import{constIncludes as R}from"../schemas/constants.js";import{asBoolean as p,asNumber as u,asString as o,asStringArray as x,captureExtraProperties as I,collectFromAst as A,extractVariableName as S,isCallRef as b,isFactoryBuildCall as h,isFactoryMethodCall as E,omitUndefined as D,parseObjectLiteral as w,parseOptionalConfig as d,parseBooleanOrConfig as g,resolveTemplateLiteral as N,typed as l}from"./astCommonParser.js";import{extractDynamoDBFields as v}from"./astDynamoDBParser.js";import{extractClickHouseFields as C}from"./astClickHouseParser.js";import{convertDynamoDBResources as H}from"./astDynamoDBParser.js";import{convertClickHouseResources as K}from"./astClickHouseParser.js";function P(r){const e=o(r.databaseEngine);if(e==="postgresql"||e==="mysql")return e;const i=r.engine;if(b(i)){const t=String(i.__call);if(t.includes("postgres")||t.includes("auroraPostgres"))return"postgresql";if(t.includes("mysql")||t.includes("auroraMysql"))return"mysql"}}function W(r){const e=r.engine;if(b(e))return String(e.__call)}const F=new Set(["type","databaseName","databaseEngine","engine","vpc","port","deletionProtection","instanceType","multiAz","publiclyAccessible","enableSecretRotation","encryption","databaseInsights","proxy","readReplica","credentials","writer","readers","backupRetention","preferredMaintenanceWindow","primaryRegion","secondaryRegions","globalClusterIdentifier","enableGlobalWriteForwarding","snapshotIdentifier","allocatedStorage","monitoringInterval","snapshotUsername"]);function T(r,e,i){if(i.arguments.length<2)return null;const t=i.arguments[0],a=i.arguments[1];if(!c.isStringLiteral(t)&&!c.isTemplateExpression(t))return null;const s=c.isStringLiteral(t)?t.text:N(r,t);if(!c.isObjectLiteralExpression(a))return null;const n=w(a),m={resourceName:s,type:o(n.type)??"",databaseName:o(n.databaseName)??"",databaseEngine:P(n),engineExpression:W(n),port:u(n.port),deletionProtection:p(n.deletionProtection),instanceType:o(n.instanceType),multiAz:p(n.multiAz),publiclyAccessible:p(n.publiclyAccessible),enableSecretRotation:p(n.enableSecretRotation),encryption:d(n.encryption,l()),databaseInsights:g(n.databaseInsights,l()),proxy:g(n.proxy,l()),readReplica:g(n.readReplica,l()),credentials:d(n.credentials,l()),writer:d(n.writer,l()),readers:g(n.readers,l()),backupRetention:u(n.backupRetention),preferredMaintenanceWindow:o(n.preferredMaintenanceWindow),primaryRegion:o(n.primaryRegion),secondaryRegions:x(n.secondaryRegions),globalClusterIdentifier:o(n.globalClusterIdentifier),enableGlobalWriteForwarding:p(n.enableGlobalWriteForwarding),allocatedStorage:u(n.allocatedStorage),monitoringInterval:u(n.monitoringInterval),snapshotIdentifier:o(n.snapshotIdentifier),snapshotUsername:o(n.snapshotUsername),node:e},y=S(e);y&&(m.variableName=y);const f=I(n,F);return f.length>0&&(m.extraProperties=f),m}function G(r){return A(r,e=>{if(!c.isCallExpression(e)||!E(e,"addDatabase"))return null;const i=e.arguments[0];return h(i,"DatabaseFactory")?T(r,e,i):null})}function L(r){const e=[],i=[],t=[];for(const a of r)if(a.type==="DynamoDB"){const s=v(a);s&&i.push(s)}else if(a.type==="ClickHouse"){const s=C(a);s&&t.push(s)}else e.push(a);return{databases:e,dynamodb:i,clickhouse:t}}const k=["Instance","Aurora","GlobalAurora"];function z(r){return r.filter(e=>e.type!=="DynamoDB").map(e=>({name:e.resourceName,type:R(k,e.type)?e.type:"Instance",databaseName:e.databaseName,...D({port:e.port,deletionProtection:e.deletionProtection,instanceType:e.instanceType,multiAz:e.multiAz,publiclyAccessible:e.publiclyAccessible,enableSecretRotation:e.enableSecretRotation,encryption:e.encryption,databaseInsights:e.databaseInsights,proxy:e.proxy,readReplica:e.readReplica,credentials:e.credentials,writer:e.writer,readers:e.readers,backupRetention:e.backupRetention,preferredMaintenanceWindow:e.preferredMaintenanceWindow,primaryRegion:e.primaryRegion,secondaryRegions:e.secondaryRegions,globalClusterIdentifier:e.globalClusterIdentifier,enableGlobalWriteForwarding:e.enableGlobalWriteForwarding,allocatedStorage:e.allocatedStorage,monitoringInterval:e.monitoringInterval,variableName:e.variableName,databaseEngine:e.databaseEngine,engineExpression:e.engineExpression,extraProperties:e.extraProperties})}))}export{K as convertClickHouseResources,z as convertDatabaseResources,H as convertDynamoDBResources,G as findDatabaseResources,L as splitDatabaseResources};
@@ -8,21 +8,25 @@ import type { CustomCodeBlock } from "../schemas/resourceSchemas.js";
8
8
  export { type IdentifierRef, type ExpressionRef, type CallRef, type ParsedValue, type ParsedObject, isPlainObject, isIdentifierRef, isExpressionRef, isCallRef, isParsedObject, asString, asNumber, asBoolean, asStringArray, asStringUnion, captureExtraProperties, } from "./astCommonParser.js";
9
9
  export { type ParsedDatabaseResource } from "./astDatabaseParser.js";
10
10
  export { type ParsedDynamoDBResource } from "./astDatabaseParser.js";
11
+ export { type ParsedClickHouseResource } from "./astDatabaseParser.js";
11
12
  export { type ParsedS3Resource } from "./astStorageParser.js";
12
13
  export { type ParsedComputeResource, findComputeResources, } from "./astComputeParser.js";
14
+ export { type ParsedScheduleCall, findSchedules } from "./astScheduleParser.js";
13
15
  export { type ParsedSQSResource } from "./astMessagingParser.js";
14
16
  export { type ParsedCDNResource } from "./astCdnParser.js";
15
17
  export { type ParsedNetworkResource } from "./astNetworkParser.js";
16
18
  export { type ParsedLambdaConfig, type ParsedPatternResource, } from "./astPatternParser.js";
17
- export { type StatementType } from "../schemas/resourceSchemas.js";
19
+ export { type AstStatementType } from "../schemas/resourceSchemas.js";
18
20
  export { type CustomCodeBlock } from "../schemas/resourceSchemas.js";
19
21
  export { type ClassifiedStatement, classifyStatements, } from "./astStatementClassifier.js";
20
22
  export { extractCustomCodeBlocks, findManagedResourcePosition, getLastManagedStatementOfType, getManagedResourcesByType, } from "./astStatementQueries.js";
21
23
  export { convertToResourcePlan } from "./astPlanConverter.js";
24
+ import { type ParsedScheduleCall } from "./astScheduleParser.js";
22
25
  import { type ParsedNetworkConfig } from "./astNetworkParser.js";
23
26
  import { type ClassifiedStatement } from "./astStatementClassifier.js";
24
27
  import type { ParsedDatabaseResource } from "./astDatabaseParser.js";
25
28
  import type { ParsedDynamoDBResource } from "./astDatabaseParser.js";
29
+ import type { ParsedClickHouseResource } from "./astDatabaseParser.js";
26
30
  import type { ParsedS3Resource } from "./astStorageParser.js";
27
31
  import type { ParsedComputeResource } from "./astComputeParser.js";
28
32
  import type { ParsedSQSResource } from "./astMessagingParser.js";
@@ -50,10 +54,12 @@ export interface ParsedInfrastructure {
50
54
  networkResources: ParsedNetworkResource[];
51
55
  databaseResources: ParsedDatabaseResource[];
52
56
  dynamodbResources: ParsedDynamoDBResource[];
57
+ clickhouseResources: ParsedClickHouseResource[];
53
58
  sqsResources: ParsedSQSResource[];
54
59
  cdnResource?: ParsedCDNResource;
55
60
  s3Resources: ParsedS3Resource[];
56
61
  computeResources: ParsedComputeResource[];
62
+ schedules: ParsedScheduleCall[];
57
63
  patternResources: ParsedPatternResource[];
58
64
  tags: Record<string, string>;
59
65
  /** Custom code blocks (user-written code) to preserve during regeneration */
@@ -1 +1 @@
1
- import*as s from"typescript";import{isPlainObject as ne,isIdentifierRef as ae,isExpressionRef as ce,isCallRef as pe,isParsedObject as me,asString as fe,asNumber as ue,asBoolean as le,asStringArray as de,asStringUnion as xe,captureExtraProperties as ge}from"./astCommonParser.js";import{findComputeResources as Ce}from"./astComputeParser.js";import{classifyStatements as be}from"./astStatementClassifier.js";import{extractCustomCodeBlocks as Ie,findManagedResourcePosition as Ne,getLastManagedStatementOfType as ke,getManagedResourcesByType as Ae}from"./astStatementQueries.js";import{convertToResourcePlan as Ee}from"./astPlanConverter.js";import{isAppGetAppCall as I,isExpressionRef as N,findFirstInAst as k,parseObjectLiteral as A,findVariableValue as B,evaluatePropertyAccess as E}from"./astCommonParser.js";import{findDatabaseResources as P,splitDynamoDBFromDatabases as T}from"./astDatabaseParser.js";import{findS3Resources as v,findS3FactoryResources as V}from"./astStorageParser.js";import{findComputeResources as h}from"./astComputeParser.js";import{findSQSResources as D}from"./astMessagingParser.js";import{findCDNResource as L}from"./astCdnParser.js";import{findVpcId as O,findNetworkConfig as j,findBackupConfig as w,findTunnelConfig as z,findNetworkResources as F}from"./astNetworkParser.js";import{findPatternResources as M}from"./astPatternParser.js";import{classifyStatements as q}from"./astStatementClassifier.js";import{extractCustomCodeBlocks as G}from"./astStatementQueries.js";function re(i,t){const e=s.createSourceFile("infrastructure.ts",i,s.ScriptTarget.Latest,!0,s.ScriptKind.TS),r=K(e),{appVariableName:o,appName:n}=U(e),c=O(e),a=j(e),m=w(e),f=z(e),u=F(e),l=P(e),{databases:d,dynamodb:x}=T(l),g=D(e),R=L(e),C=[...v(e),...V(e)],S=h(e),b=M(e),y=H(e),p={sourceFile:e,imports:r,appVariableName:o,appName:n,vpcId:c,network:a,backup:m,tunnel:f,networkResources:u,databaseResources:d,dynamodbResources:x,sqsResources:g,cdnResource:R,s3Resources:C,computeResources:S,patternResources:b,tags:y};return t?.extractCustomCode&&(p.customCodeBlocks=G(e),p.classifiedStatements=q(e)),p}function K(i){const t=[];return s.forEachChild(i,e=>{if(s.isImportDeclaration(e)){if(!s.isStringLiteral(e.moduleSpecifier))return;const o={moduleSpecifier:e.moduleSpecifier.text,namedImports:[]};e.importClause&&(e.importClause.name&&(o.defaultImport=e.importClause.name.text),e.importClause.namedBindings&&s.isNamedImports(e.importClause.namedBindings)&&(o.namedImports=e.importClause.namedBindings.elements.map(n=>n.name.text))),t.push(o)}}),t}function Q(i,t){return s.isStringLiteral(t)?t.text:s.isIdentifier(t)?B(i,t.text)??"":s.isPropertyAccessExpression(t)?E(i,t)??"":""}function U(i){return k(i,t=>{if(s.isVariableStatement(t))for(const e of t.declarationList.declarations){if(!e.initializer||!I(e.initializer))continue;const r=s.isIdentifier(e.name)?e.name.text:"",o=e.initializer.arguments.length>0?Q(i,e.initializer.arguments[0]):"";return{appVariableName:r,appName:o}}})??{appVariableName:"",appName:""}}function H(i){const t={};function e(r){if(s.isCallExpression(r)&&s.isPropertyAccessExpression(r.expression)&&r.expression.name.text==="addTags"&&s.isIdentifier(r.expression.expression)&&r.arguments.length>0){const o=r.arguments[0];if(s.isObjectLiteralExpression(o)){const n=A(o);for(const[c,a]of Object.entries(n))typeof a=="string"?t[c]=a:N(a)&&(t[c]="default-value")}}s.forEachChild(r,e)}return e(i),t}export{le as asBoolean,ue as asNumber,fe as asString,de as asStringArray,xe as asStringUnion,ge as captureExtraProperties,be as classifyStatements,Ee as convertToResourcePlan,Ie as extractCustomCodeBlocks,Ce as findComputeResources,Ne as findManagedResourcePosition,ke as getLastManagedStatementOfType,Ae as getManagedResourcesByType,pe as isCallRef,ce as isExpressionRef,ae as isIdentifierRef,me as isParsedObject,ne as isPlainObject,re as parseInfrastructure};
1
+ import*as s from"typescript";import{isPlainObject as fe,isIdentifierRef as me,isExpressionRef as ue,isCallRef as le,isParsedObject as de,asString as xe,asNumber as Re,asBoolean as ge,asStringArray as Ce,asStringUnion as Se,captureExtraProperties as be}from"./astCommonParser.js";import{findComputeResources as ye}from"./astComputeParser.js";import{findSchedules as he}from"./astScheduleParser.js";import{classifyStatements as Ae}from"./astStatementClassifier.js";import{extractCustomCodeBlocks as Ee,findManagedResourcePosition as Pe,getLastManagedStatementOfType as Te,getManagedResourcesByType as ve}from"./astStatementQueries.js";import{convertToResourcePlan as Le}from"./astPlanConverter.js";import{isAppGetAppCall as h,isExpressionRef as k,findFirstInAst as A,parseObjectLiteral as B,findVariableValue as E,evaluatePropertyAccess as P}from"./astCommonParser.js";import{findDatabaseResources as T,splitDatabaseResources as v}from"./astDatabaseParser.js";import{findS3Resources as V,findS3FactoryResources as L}from"./astStorageParser.js";import{findComputeResources as O}from"./astComputeParser.js";import{findSchedules as j}from"./astScheduleParser.js";import{findSQSResources as D}from"./astMessagingParser.js";import{findCDNResource as w}from"./astCdnParser.js";import{findVpcId as z,findNetworkConfig as F,findBackupConfig as M,findTunnelConfig as q,findNetworkResources as G}from"./astNetworkParser.js";import{findPatternResources as K}from"./astPatternParser.js";import{classifyStatements as Q}from"./astStatementClassifier.js";import{extractCustomCodeBlocks as U}from"./astStatementQueries.js";function ae(i,t){const e=s.createSourceFile("infrastructure.ts",i,s.ScriptTarget.Latest,!0,s.ScriptKind.TS),r=H(e),{appVariableName:o,appName:n}=W(e),c=z(e),a=F(e),f=M(e),m=q(e),u=G(e),l=T(e),{databases:d,dynamodb:x,clickhouse:R}=v(l),g=D(e),C=w(e),S=[...V(e),...L(e)],b=O(e),I=j(e),y=K(e),N=X(e),p={sourceFile:e,imports:r,appVariableName:o,appName:n,vpcId:c,network:a,backup:f,tunnel:m,networkResources:u,databaseResources:d,dynamodbResources:x,clickhouseResources:R,sqsResources:g,cdnResource:C,s3Resources:S,computeResources:b,schedules:I,patternResources:y,tags:N};return t?.extractCustomCode&&(p.customCodeBlocks=U(e),p.classifiedStatements=Q(e)),p}function H(i){const t=[];return s.forEachChild(i,e=>{if(s.isImportDeclaration(e)){if(!s.isStringLiteral(e.moduleSpecifier))return;const o={moduleSpecifier:e.moduleSpecifier.text,namedImports:[]};e.importClause&&(e.importClause.name&&(o.defaultImport=e.importClause.name.text),e.importClause.namedBindings&&s.isNamedImports(e.importClause.namedBindings)&&(o.namedImports=e.importClause.namedBindings.elements.map(n=>n.name.text))),t.push(o)}}),t}function J(i,t){return s.isStringLiteral(t)?t.text:s.isIdentifier(t)?E(i,t.text)??"":s.isPropertyAccessExpression(t)?P(i,t)??"":""}function W(i){return A(i,t=>{if(s.isVariableStatement(t))for(const e of t.declarationList.declarations){if(!e.initializer||!h(e.initializer))continue;const r=s.isIdentifier(e.name)?e.name.text:"",o=e.initializer.arguments.length>0?J(i,e.initializer.arguments[0]):"";return{appVariableName:r,appName:o}}})??{appVariableName:"",appName:""}}function X(i){const t={};function e(r){if(s.isCallExpression(r)&&s.isPropertyAccessExpression(r.expression)&&r.expression.name.text==="addTags"&&s.isIdentifier(r.expression.expression)&&r.arguments.length>0){const o=r.arguments[0];if(s.isObjectLiteralExpression(o)){const n=B(o);for(const[c,a]of Object.entries(n))typeof a=="string"?t[c]=a:k(a)&&(t[c]="default-value")}}s.forEachChild(r,e)}return e(i),t}export{ge as asBoolean,Re as asNumber,xe as asString,Ce as asStringArray,Se as asStringUnion,be as captureExtraProperties,Ae as classifyStatements,Le as convertToResourcePlan,Ee as extractCustomCodeBlocks,ye as findComputeResources,Pe as findManagedResourcePosition,he as findSchedules,Te as getLastManagedStatementOfType,ve as getManagedResourcesByType,le as isCallRef,ue as isExpressionRef,me as isIdentifierRef,de as isParsedObject,fe as isPlainObject,ae as parseInfrastructure};
@@ -1,2 +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};
1
+ import{ApplicationResourcePlanSchema as s,getZodErrorMessage as u}from"../schemas/resourceSchemas.js";import{z as a}from"zod";import{COST_ALLOCATION_TAG as c}from"../generation/infrastructure.js";import{convertDatabaseResources as m,convertDynamoDBResources as f,convertClickHouseResources as l}from"./astDatabaseParser.js";import{convertS3Resources as p}from"./astStorageParser.js";import{convertComputeResources as d}from"./astComputeParser.js";import{convertSQSResources as R}from"./astMessagingParser.js";import{convertCDNResource as h}from"./astCdnParser.js";import{convertNetworkConfig as v,convertBackupConfig as g,convertTunnelConfig as k,convertAdditionalNetworks as I}from"./astNetworkParser.js";import{applyPatternConfig as b}from"./astPatternParser.js";import{KNOWN_FJALL_IMPORTS as S,isManagedModuleSpecifier as w}from"./astStatementClassifier.js";function y(e,r){for(const t of r){const o=e.compute.find(n=>n.variableName===t.targetVariableName);o!==void 0&&o.type==="lambda"&&(o.scheduleExpression=t.schedule)}}function N(e,r){Object.keys(r).length>0&&(e.tags={...r}),r[c]&&(e.owner=r[c])}function C(e){const r=[];for(const t of e)if(w(t.moduleSpecifier))if(t.moduleSpecifier==="@fjall/components-infrastructure"||t.moduleSpecifier==="@fjall/infrastructure"){const o=t.namedImports.filter(n=>!S.has(n));o.length>0&&r.push({moduleSpecifier:t.moduleSpecifier,namedImports:o,defaultImport:t.defaultImport})}else(t.namedImports.length>0||t.defaultImport)&&r.push(t);return r.length>0?r:void 0}function B(e,r,t){const o={appName:r,type:"standard",database:[],s3:[],compute:[]};if(b(o,e.patternResources),e.vpcId&&(o.vpcId=e.vpcId),o.network=v(e.network),o.backup=g(e.backup),o.tunnel=k(e.tunnel),o.additionalNetworks=I(e.networkResources),N(o,e.tags),o.database=m(e.databaseResources),o.dynamodb=f(e.dynamodbResources),o.clickhouse=l(e.clickhouseResources),o.sqs=R(e.sqsResources),o.cdn=h(e.cdnResource,e.s3Resources,e.computeResources),o.s3=p(e.s3Resources),o.compute=d(e.computeResources,e.databaseResources,e.s3Resources,o),y(o,e.schedules),o.additionalManagedImports=C(e.imports),t?.skipValidation)return o;try{return s.parse(o)}catch(n){if(n instanceof a.ZodError){const i=u(n);throw new Error(`Invalid infrastructure configuration:
2
+ ${i}`)}throw n}}export{B as convertToResourcePlan};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Read-only AST parser for `app.addSchedule(...)` calls. Used by
3
+ * convertToResourcePlan to back-fill scheduleExpression onto lambda compute
4
+ * resources after they are converted. Recognises the canonical emission
5
+ * shape only — non-canonical shapes are silently skipped and round-trip as
6
+ * opaque managed-statement blocks. Write paths live in src/codemod/. Do not
7
+ * add mutation helpers here.
8
+ */
9
+ import * as ts from "typescript";
10
+ export interface ParsedScheduleCall {
11
+ /** The schedule's CDK construct id, first arg of `app.addSchedule(...)` */
12
+ id: string;
13
+ /** The schedule expression literal (e.g. `"rate(5 minutes)"`) */
14
+ schedule: string;
15
+ /** Variable name of the target const (e.g. `myLambda` from `target: myLambda`) */
16
+ targetVariableName: string;
17
+ }
18
+ export declare function findSchedules(sourceFile: ts.SourceFile): ParsedScheduleCall[];
@@ -0,0 +1 @@
1
+ import*as r from"typescript";import{asString as o,collectFromAst as c,isFactoryMethodCall as f,parseObjectLiteral as g}from"./astCommonParser.js";function p(u){return c(u,t=>{if(!r.isCallExpression(t)||!f(t,"addSchedule")||t.arguments.length<2)return null;const s=t.arguments[0],i=t.arguments[1];if(!r.isStringLiteral(s)||!r.isObjectLiteralExpression(i))return null;const a=g(i),l=o(a.schedule);if(l===void 0)return null;const e=i.properties.find(n=>r.isPropertyAssignment(n)&&r.isIdentifier(n.name)&&n.name.text==="target");return!e||!r.isPropertyAssignment(e)||!r.isIdentifier(e.initializer)?null:{id:s.text,schedule:l,targetVariableName:e.initializer.text}})}export{p as findSchedules};
@@ -6,14 +6,14 @@
6
6
  * src/codemod/. Do not add mutation helpers here.
7
7
  */
8
8
  import * as ts from "typescript";
9
- import type { StatementType } from "../schemas/resourceSchemas.js";
9
+ import type { AstStatementType } from "../schemas/resourceSchemas.js";
10
10
  /** Imports that the generator always handles -- don't preserve as "additional" */
11
11
  declare const KNOWN_FJALL_IMPORTS: Set<string>;
12
12
  export { KNOWN_FJALL_IMPORTS };
13
13
  /** Check if a module specifier belongs to a managed (Fjall/CDK) package */
14
14
  export declare function isManagedModuleSpecifier(specifier: string): boolean;
15
15
  export interface ClassifiedStatement {
16
- type: StatementType;
16
+ type: AstStatementType;
17
17
  node: ts.Statement;
18
18
  resourceName?: string;
19
19
  startPos: number;
@@ -1 +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};
1
+ import*as a from"typescript";import{isAppGetAppCall as f}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","VpcPeerFactory","VpcPeerAccepterFactory","CrossPlanConnectionFactory"]);function l(r){return!!(r.startsWith("@fjall/")||r==="aws-cdk-lib"||r.startsWith("aws-cdk-lib/")||r==="constructs")}function C(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(f(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 o=i.expression.text;if(d.has(o)){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=p(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)?p(t,r,n,e):{type:"custom",node:r,startPos:n,endPos:e,isManaged:!1}}function p(r,n,e,t){const i=r.expression;if(a.isPropertyAccessExpression(i)&&a.isIdentifier(i.expression)){const o=i.name.text;if(o==="addTags")return{type:"tags",node:n,startPos:e,endPos:t,isManaged:!0};const s={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"},addVpcPeer:{type:"vpc-peer",factory:"VpcPeerFactory"},addVpcPeerAccepter:{type:"vpc-peer-accepter",factory:"VpcPeerAccepterFactory"}}[o];if(s){const u=F(r,s.factory);return{type:s.type,node:n,resourceName:u,startPos:e,endPos:t,isManaged:!0}}}return{type:"custom",node:n,startPos:e,endPos:t,isManaged:!1}}function F(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,C as classifyStatements,l as isManagedModuleSpecifier};
@@ -5,17 +5,17 @@
5
5
  * add mutation helpers here.
6
6
  */
7
7
  import * as ts from "typescript";
8
- import type { StatementType, CustomCodeBlock } from "../schemas/resourceSchemas.js";
8
+ import type { AstStatementType, CustomCodeBlock } from "../schemas/resourceSchemas.js";
9
9
  import { type ClassifiedStatement } from "./astStatementClassifier.js";
10
10
  /** Extract custom code blocks from an infrastructure file. */
11
11
  export declare function extractCustomCodeBlocks(sourceFile: ts.SourceFile, precomputedClassifications?: ClassifiedStatement[]): CustomCodeBlock[];
12
12
  /** Find the position information for a specific managed resource. */
13
- export declare function findManagedResourcePosition(sourceFile: ts.SourceFile, resourceType: StatementType, resourceName: string, precomputedClassifications?: ClassifiedStatement[]): {
13
+ export declare function findManagedResourcePosition(sourceFile: ts.SourceFile, resourceType: AstStatementType, resourceName: string, precomputedClassifications?: ClassifiedStatement[]): {
14
14
  startPos: number;
15
15
  endPos: number;
16
16
  node: ts.Statement;
17
17
  } | null;
18
18
  /** Get the last managed statement of a specific type. */
19
- export declare function getLastManagedStatementOfType(sourceFile: ts.SourceFile, type: StatementType, precomputedClassifications?: ClassifiedStatement[]): ClassifiedStatement | null;
19
+ export declare function getLastManagedStatementOfType(sourceFile: ts.SourceFile, type: AstStatementType, precomputedClassifications?: ClassifiedStatement[]): ClassifiedStatement | null;
20
20
  /** Get all managed resources grouped by type. */
21
- export declare function getManagedResourcesByType(sourceFile: ts.SourceFile, precomputedClassifications?: ClassifiedStatement[]): Record<StatementType, ClassifiedStatement[]>;
21
+ export declare function getManagedResourcesByType(sourceFile: ts.SourceFile, precomputedClassifications?: ClassifiedStatement[]): Record<AstStatementType, ClassifiedStatement[]>;
@@ -1,3 +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
+ import*as l from"typescript";import{classifyStatements as r}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??r(t),o=[],s=t.getFullText();let e=null;for(const c of i)if(c.type==="custom"&&!c.isManaged){const{position:a,afterManagedResource:p}=g(e),u=x(s,c.node),f=y(s,c.node),m=t.getLineAndCharacterOfPosition(c.node.getStart());o.push({sourceText:u,position:a,afterManagedResource:p,originalLine:m.line+1,leadingComments:f.length>0?f:void 0})}else c.isManaged&&(e=c);return o}function x(t,n){const i=n.getFullStart(),o=n.getEnd(),e=t.slice(i,o).split(`
2
+ `),c=e.findIndex(a=>a.trim()!=="");return e.slice(c===-1?0:c).join(`
3
+ `)}function y(t,n){const i=[],o=l.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??r(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??r(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??r(t),o={import:[],"app-init":[],tags:[],database:[],compute:[],storage:[],network:[],messaging:[],cdn:[],pattern:[],"vpc-peer":[],"vpc-peer-accepter":[],"cross-plan-connection":[],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,4 +1,8 @@
1
- import { type StatementType, type CustomCodeBlock } from "./astInfrastructureParser.js";
1
+ import * as ts from "typescript";
2
+ import { type AstStatementType, type ClassifiedStatement } from "./astInfrastructureParser.js";
3
+ export declare function insertAtPosition(content: string, position: number, text: string): string;
4
+ export declare function findClassification(classifications: ClassifiedStatement[], type: AstStatementType): ClassifiedStatement | undefined;
5
+ export declare function findLastClassification(classifications: ClassifiedStatement[], type: AstStatementType): ClassifiedStatement | undefined;
2
6
  export interface SurgicalModificationResult {
3
7
  content: string;
4
8
  success: boolean;
@@ -8,20 +12,20 @@ export interface SurgicalModificationResult {
8
12
  }
9
13
  export interface InsertionOptions {
10
14
  /** The type of resource being inserted */
11
- resourceType: StatementType;
15
+ resourceType: AstStatementType;
12
16
  /** The resource name (e.g., "MyDatabase") */
13
17
  resourceName: string;
14
18
  /** The code to insert (complete statement) */
15
19
  code: string;
16
20
  /** Insert after a specific resource (by name) */
17
21
  afterResource?: {
18
- type: StatementType;
22
+ type: AstStatementType;
19
23
  name: string;
20
24
  };
21
25
  }
22
26
  export interface UpdateOptions {
23
27
  /** The type of resource being updated */
24
- resourceType: StatementType;
28
+ resourceType: AstStatementType;
25
29
  /** The resource name to update */
26
30
  resourceName: string;
27
31
  /** The new code for the resource (complete statement) */
@@ -29,19 +33,17 @@ export interface UpdateOptions {
29
33
  }
30
34
  export interface DeleteOptions {
31
35
  /** The type of resource being deleted */
32
- resourceType: StatementType;
36
+ resourceType: AstStatementType;
33
37
  /** The resource name to delete */
34
38
  resourceName: string;
35
39
  /** How to handle custom code that was after this resource */
36
40
  orphanHandling: "preserve-with-warning" | "move-to-previous" | "delete";
37
41
  }
42
+ export declare function parseSourceFile(content: string): ts.SourceFile;
43
+ export declare function formatLeadingNewlines(beforeText: string, codeToInsert: string): string;
44
+ export declare function getContextBeforePosition(content: string, position: number): string;
45
+ export declare function formatResourceId(type: string, name?: string): string;
46
+ export declare function createErrorResult(error: unknown, content: string): SurgicalModificationResult;
38
47
  export declare function addResourceSurgically(content: string, options: InsertionOptions): SurgicalModificationResult;
39
48
  export declare function updateResourceSurgically(content: string, options: UpdateOptions): SurgicalModificationResult;
40
49
  export declare function removeResourceSurgically(content: string, options: DeleteOptions): SurgicalModificationResult;
41
- export declare function ensureImports(content: string, requiredImports: string[]): SurgicalModificationResult;
42
- export declare function injectCustomCodeBlocks(generatedCode: string, customBlocks: CustomCodeBlock[], resourceMapping?: Map<string, string>): SurgicalModificationResult;
43
- export interface FileValidationResult {
44
- valid: boolean;
45
- errors?: string[];
46
- }
47
- export declare function validateModifiedFile(content: string): FileValidationResult;
@@ -1,19 +1,12 @@
1
- import*as f from"typescript";import{parseInfrastructure as D,classifyStatements as y,findManagedResourcePosition as C}from"./astInfrastructureParser.js";import{getErrorMessage as M}from"../util/errorUtils.js";function R(e,t,r){return e.slice(0,t)+r+e.slice(t)}function P(e,t){return e.find(r=>r.type===t)}function L(e,t){return e.filter(r=>r.type===t).pop()}function m(e){return f.createSourceFile("infrastructure.ts",e,f.ScriptTarget.Latest,!0,f.ScriptKind.TS)}function I(e,t){return e.endsWith(`
1
+ import*as x from"typescript";import{parseInfrastructure as F,classifyStatements as E,findManagedResourcePosition as y}from"./astInfrastructureParser.js";import{getErrorMessage as O}from"../util/errorUtils.js";function C(e,r,t){return e.slice(0,r)+t+e.slice(r)}function L(e,r){return e.find(t=>t.type===r)}function A(e,r){return e.filter(t=>t.type===r).pop()}function w(e){return x.createSourceFile("infrastructure.ts",e,x.ScriptTarget.Latest,!0,x.ScriptKind.TS)}function T(e,r){return e.endsWith(`
2
2
 
3
- `)||t.startsWith(`
3
+ `)||r.startsWith(`
4
4
  `)?"":e.endsWith(`
5
5
  `)?`
6
6
  `:`
7
7
 
8
- `}function E(e,t){return e.slice(Math.max(0,t-2),t)}function p(e,t){return t?`${e}:${t}`:e}function l(e,t){return{content:t,success:!1,error:M(e)}}function S(e,t,r,s){const n=C(e,r,s);return n||l(new Error(`Resource not found: ${p(r,s)}`),t)}function T(e){return"success"in e&&!e.success}function J(e,t){const{resourceType:r,code:s,afterResource:n}=t;try{const o=m(e);let i;if(n){const u=C(o,n.type,n.name);if(!u)return l(new Error(`Insertion target not found: ${p(n.type,n.name)}`),e);i=u.endPos}else i=$(o,r);const c=B(e,i,s);return{content:R(e,i,c),success:!0}}catch(o){return l(o,e)}}function $(e,t){const r=y(e),s=["import","app-init","tags","database","storage","messaging","compute","network","cdn","pattern"],n=s.indexOf(t);let o=null;for(const i of r)if(i.isManaged){const c=s.indexOf(i.type);c!==-1&&c<=n&&(o=i)}return o?o.endPos:e.getEnd()}function B(e,t,r){const s=E(e,t),n=e.slice(t,Math.min(e.length,t+2)),o=I(s,r),i=n.startsWith(`
8
+ `}function I(e,r){return e.slice(Math.max(0,r-2),r)}function p(e,r){return r?`${e}:${r}`:e}function f(e,r){return{content:r,success:!1,error:O(e)}}function P(e,r,t,i){const n=y(e,t,i);return n||f(new Error(`Resource not found: ${p(t,i)}`),r)}function R(e){return"success"in e&&!e.success}function B(e,r){const{resourceType:t,code:i,afterResource:n}=r;try{const s=w(e);let o;if(n){const u=y(s,n.type,n.name);if(!u)return f(new Error(`Insertion target not found: ${p(n.type,n.name)}`),e);o=u.endPos}else o=M(s,t);const c=v(e,o,i);return{content:C(e,o,c),success:!0}}catch(s){return f(s,e)}}function M(e,r){const t=E(e),i=["import","app-init","tags","database","storage","messaging","compute","network","vpc-peer","vpc-peer-accepter","cross-plan-connection","cdn","pattern"],n=i.indexOf(r);let s=null;for(const o of t)if(o.isManaged){const c=i.indexOf(o.type);c!==-1&&c<=n&&(s=o)}return s?s.endPos:e.getEnd()}function v(e,r,t){const i=I(e,r),n=e.slice(r,Math.min(e.length,r+2)),s=T(i,t),o=n.startsWith(`
9
9
  `)?"":`
10
- `;return o+r+i}function Q(e,t){const{resourceType:r,resourceName:s,newCode:n}=t;try{const o=m(e),i=S(o,e,r,s);if(T(i))return i;const c=i,a=c.node.getFullStart(),u=c.endPos,d=e.slice(a,c.node.getStart()),g=W(d);return{content:e.slice(0,a)+g+n+e.slice(u),success:!0}}catch(o){return l(o,e)}}function W(e){const t=e.match(/^[\s]*[\n\r]+[\s]*/);return t?t[0]:""}function H(e,t,r,s){let n=e,o=0;for(const i of t){const c=`// [ORPHANED: was after ${p(r,s)}]
11
- `,a=i.sourceText.trim(),u=n.indexOf(a,o);u!==-1&&(n=R(n,u,c),o=u+c.length+a.length)}return n}function V(e,t){const{resourceType:r,resourceName:s,orphanHandling:n}=t,o=[];try{const i=m(e),c=S(i,e,r,s);if(T(c))return c;const a=c,d=(D(e,{extractCustomCode:!0}).customCodeBlocks??[]).filter(x=>x.position==="after-resource"&&x.afterManagedResource?.type===r&&x.afterManagedResource?.name===s);d.length>0&&n==="preserve-with-warning"&&o.push(`Custom code after ${p(r,s)} will be orphaned. Added // [ORPHANED] marker comment.`);const g=a.node.getFullStart(),h=a.endPos,A=e[h]===`
12
- `?h+1:h;let w=e.slice(0,g)+e.slice(A);return d.length>0&&n==="preserve-with-warning"&&(w=H(w,d,r,s)),{content:w,success:!0,warnings:o.length>0?o:void 0}}catch(i){return l(i,e)}}function Y(e,t){try{const r=m(e),s=new Set;for(const a of r.statements)f.isImportDeclaration(a)&&s.add(a.getText(r).trim());const n=[];for(const a of t){const u=a.trim();[...s].some(g=>q(g,u))||n.push(u)}if(n.length===0)return{content:e,success:!0};const o=r.statements.filter(f.isImportDeclaration).at(-1)?.getEnd()??0,i=`
13
- `+n.join(`
14
- `);return{content:R(e,o,i),success:!0}}catch(r){return l(r,e)}}function O(e){return new Set(e.split(",").map(t=>t.trim()).filter(Boolean))}function _(e,t){const r=O(e),s=O(t);for(const n of s)if(!r.has(n))return!1;return!0}function q(e,t){const r=e.match(F),s=t.match(F);if(!r||!s||r[1]!==s[1])return!1;const n=e.match(N),o=t.match(N);return n&&o?_(n[1],o[1]):!0}const F=/from\s+["']([^"']+)["']/,N=/\{([^}]+)\}/,v={"before-imports":0,"after-imports":1,"after-app-init":2,"after-tags":3,"after-resource":4,"end-of-file":5};function U(e){return[...e].sort((t,r)=>{const s=v[r.position]-v[t.position];return s!==0?s:(r.originalLine??0)-(t.originalLine??0)})}function j(e,t,r,s){if(r!==null){const o=K(e,r,t);return R(e,r,o)}const n=t.afterManagedResource?`// [ORPHANED: was after ${p(t.afterManagedResource.type,t.afterManagedResource.name)}]
15
- `:`// [ORPHANED]
16
- `;return s.push(`Custom code from line ${t.originalLine} could not be positioned. Added at end of file.`),e+`
17
- `+n+t.sourceText}function Z(e,t,r){if(!t||t.length===0)return{content:e,success:!0};try{const s=m(e),n=y(s),o=[],i=U(t);let c=e;for(const a of i){const u=G(s,n,a,r,o);c=j(c,a,u,o)}return{content:c,success:!0,warnings:o.length>0?o:void 0}}catch(s){return l(s,e)}}function k(e,t,r,s){if(!t.afterManagedResource)return null;const n=t.afterManagedResource,o=(n.name&&r?.get(n.name))??n.name,i=e.find(a=>a.type===n.type&&a.resourceName===o);if(i)return i.endPos;const c=e.filter(a=>a.type===n.type&&a.isManaged);return c.length===1?c[0].endPos:(s&&s.push(`Resource ${p(t.afterManagedResource.type,t.afterManagedResource.name)} not found. Custom code may be orphaned.`),null)}function G(e,t,r,s,n){switch(r.position){case"before-imports":return 0;case"after-imports":return L(t,"import")?.endPos??0;case"after-app-init":return P(t,"app-init")?.endPos??null;case"after-tags":return P(t,"tags")?.endPos??null;case"after-resource":return k(t,r,s,n);case"end-of-file":return e.getEnd();default:return null}}function K(e,t,r){const s=E(e,t);let n=r.sourceText;return n=I(s,n)+n,n.endsWith(`
18
- `)||(n+=`
19
- `),n}function b(e){try{let s=function(n){n.kind===f.SyntaxKind.Unknown&&r.push("Unknown node found in AST - possible parse error"),f.forEachChild(n,s)};const t=m(e),r=[];return s(t),r.length>0?{valid:!1,errors:r}:{valid:!0}}catch(t){return{valid:!1,errors:[M(t)]}}}export{J as addResourceSurgically,Y as ensureImports,Z as injectCustomCodeBlocks,V as removeResourceSurgically,Q as updateResourceSurgically,b as validateModifiedFile};
10
+ `;return s+t+o}function H(e,r){const{resourceType:t,resourceName:i,newCode:n}=r;try{const s=w(e),o=P(s,e,t,i);if(R(o))return o;const c=o,a=c.node.getFullStart(),u=c.endPos,l=e.slice(a,c.node.getStart()),g=$(l);return{content:e.slice(0,a)+g+n+e.slice(u),success:!0}}catch(s){return f(s,e)}}function $(e){const r=e.match(/^[\s]*[\n\r]+[\s]*/);return r?r[0]:""}function N(e,r,t,i){let n=e,s=0;for(const o of r){const c=`// [ORPHANED: was after ${p(t,i)}]
11
+ `,a=o.sourceText.trim(),u=n.indexOf(a,s);u!==-1&&(n=C(n,u,c),s=u+c.length+a.length)}return n}function b(e,r){const{resourceType:t,resourceName:i,orphanHandling:n}=r,s=[];try{const o=w(e),c=P(o,e,t,i);if(R(c))return c;const a=c,l=(F(e,{extractCustomCode:!0}).customCodeBlocks??[]).filter(h=>h.position==="after-resource"&&h.afterManagedResource?.type===t&&h.afterManagedResource?.name===i);if(l.length>0)if(n==="preserve-with-warning")s.push(`Custom code after ${p(t,i)} will be orphaned. Added // [ORPHANED] marker comment.`);else return f(new Error(`Orphan handling "${n}" is not yet implemented`),e);const g=a.node.getFullStart(),d=a.endPos,S=e[d]===`
12
+ `?d+1:d;let m=e.slice(0,g)+e.slice(S);return l.length>0&&n==="preserve-with-warning"&&(m=N(m,l,t,i)),{content:m,success:!0,warnings:s.length>0?s:void 0}}catch(o){return f(o,e)}}export{B as addResourceSurgically,f as createErrorResult,L as findClassification,A as findLastClassification,T as formatLeadingNewlines,p as formatResourceId,I as getContextBeforePosition,C as insertAtPosition,w as parseSourceFile,b as removeResourceSurgically,H as updateResourceSurgically};
@@ -5,7 +5,7 @@ export declare function parseAndConvert(code: string): {
5
5
  type: "standard" | "resilient" | "enterprise" | "tinkerer" | "lightweight" | "custom";
6
6
  database: {
7
7
  name: string;
8
- type: "Aurora" | "Instance" | "GlobalAurora";
8
+ type: "Aurora" | "Instance" | "GlobalAurora" | "ClickHouse";
9
9
  databaseName: string;
10
10
  instanceType?: string | undefined;
11
11
  allocatedStorage?: number | undefined;
@@ -127,12 +127,20 @@ export declare function parseAndConvert(code: string): {
127
127
  domain?: string | undefined;
128
128
  loadBalancer?: false | "public" | "internal" | undefined;
129
129
  directAccess?: boolean | undefined;
130
+ extraProperties?: {
131
+ key: string;
132
+ sourceText: string;
133
+ }[] | undefined;
130
134
  } | undefined;
131
135
  services?: {
132
136
  name: string;
133
137
  capacityProvider: "FARGATE" | "FARGATE_SPOT" | "EC2";
134
- dockerfilePath?: string | undefined;
135
- dockerTarget?: string | undefined;
138
+ docker?: {
139
+ path: string;
140
+ context?: string | undefined;
141
+ target?: string | undefined;
142
+ buildArgs?: Record<string, string> | undefined;
143
+ } | undefined;
136
144
  needsDatabaseConnection?: boolean | undefined;
137
145
  needsStorageConnection?: boolean | undefined;
138
146
  needsMessagingConnection?: boolean | undefined;
@@ -199,6 +207,10 @@ export declare function parseAndConvert(code: string): {
199
207
  minSize?: number | undefined;
200
208
  reuseOnScaleIn?: boolean | undefined;
201
209
  } | undefined;
210
+ extraProperties?: {
211
+ key: string;
212
+ sourceText: string;
213
+ }[] | undefined;
202
214
  } | undefined;
203
215
  ssmSecretsPath?: string | undefined;
204
216
  extraProperties?: {
@@ -212,7 +224,12 @@ export declare function parseAndConvert(code: string): {
212
224
  http5xxThreshold?: number | undefined;
213
225
  } | undefined;
214
226
  }[] | undefined;
215
- dockerfilePath?: string | undefined;
227
+ docker?: {
228
+ path?: string | undefined;
229
+ context?: string | undefined;
230
+ target?: string | undefined;
231
+ buildArgs?: Record<string, string> | undefined;
232
+ } | undefined;
216
233
  deployment?: "code" | "container" | undefined;
217
234
  codePath?: string | undefined;
218
235
  timeout?: number | undefined;
@@ -501,7 +518,7 @@ export declare function parseAndConvert(code: string): {
501
518
  count?: number | undefined;
502
519
  } | undefined;
503
520
  flowLogs?: false | {
504
- destination?: "cloudwatch" | "s3" | undefined;
521
+ destination?: "s3" | "cloudwatch" | undefined;
505
522
  retentionDays?: number | undefined;
506
523
  trafficType?: "ALL" | "ACCEPT" | "REJECT" | undefined;
507
524
  } | undefined;
@@ -534,7 +551,7 @@ export declare function parseAndConvert(code: string): {
534
551
  count?: number | undefined;
535
552
  } | undefined;
536
553
  flowLogs?: false | {
537
- destination?: "cloudwatch" | "s3" | undefined;
554
+ destination?: "s3" | "cloudwatch" | undefined;
538
555
  retentionDays?: number | undefined;
539
556
  trafficType?: "ALL" | "ACCEPT" | "REJECT" | undefined;
540
557
  } | undefined;
@@ -583,6 +600,23 @@ export declare function parseAndConvert(code: string): {
583
600
  sourceText: string;
584
601
  }[] | undefined;
585
602
  }[] | undefined;
603
+ clickhouse?: {
604
+ name: string;
605
+ type: "ClickHouse";
606
+ databaseName: string;
607
+ instanceType?: string | undefined;
608
+ coldTier?: false | {
609
+ mode: "s3";
610
+ } | undefined;
611
+ optimiseSchedule?: string | false | undefined;
612
+ backupSchedule?: string | false | undefined;
613
+ backupRetentionDays?: number | undefined;
614
+ variableName?: string | undefined;
615
+ extraProperties?: {
616
+ key: string;
617
+ sourceText: string;
618
+ }[] | undefined;
619
+ }[] | undefined;
586
620
  sqs?: {
587
621
  name: string;
588
622
  queueType: "standard" | "fifo";
@@ -619,7 +653,7 @@ export declare function parseAndConvert(code: string): {
619
653
  sourceText: string;
620
654
  position: "before-imports" | "after-imports" | "after-app-init" | "after-tags" | "after-resource" | "end-of-file";
621
655
  afterManagedResource?: {
622
- type: "custom" | "storage" | "database" | "compute" | "pattern" | "import" | "app-init" | "tags" | "network" | "messaging" | "cdn";
656
+ type: "custom" | "storage" | "database" | "compute" | "pattern" | "import" | "app-init" | "tags" | "network" | "messaging" | "cdn" | "vpc-peer" | "vpc-peer-accepter" | "cross-plan-connection";
623
657
  name?: string | undefined;
624
658
  } | undefined;
625
659
  originalLine?: number | undefined;
@@ -1,4 +1,5 @@
1
1
  export { type IdentifierRef, type ExpressionRef, type CallRef, type ParsedValue, type ParsedObject, isPlainObject, isIdentifierRef, isExpressionRef, isCallRef, isParsedObject, asString, asNumber, asBoolean, asStringArray, asStringUnion, captureExtraProperties, } from "./astCommonParser.js";
2
- export { type ParsedInfrastructure, type ParsedDatabaseResource, type ParsedS3Resource, type ParsedComputeResource, type ParsedSQSResource, type ParsedCDNResource, type ParsedNetworkResource, type ParsedDynamoDBResource, type ParsedLambdaConfig, type ParsedPatternResource, type ImportInfo, type StatementType, type ClassifiedStatement, type CustomCodeBlock, parseInfrastructure, convertToResourcePlan, classifyStatements, extractCustomCodeBlocks, findManagedResourcePosition, getLastManagedStatementOfType, getManagedResourcesByType, } from "./astInfrastructureParser.js";
3
- export { type SurgicalModificationResult, type InsertionOptions, type UpdateOptions, type DeleteOptions, type FileValidationResult, addResourceSurgically, updateResourceSurgically, removeResourceSurgically, ensureImports, injectCustomCodeBlocks, validateModifiedFile, } from "./astSurgicalModification.js";
2
+ export { type ParsedInfrastructure, type ParsedDatabaseResource, type ParsedS3Resource, type ParsedComputeResource, type ParsedSQSResource, type ParsedCDNResource, type ParsedNetworkResource, type ParsedDynamoDBResource, type ParsedLambdaConfig, type ParsedPatternResource, type ImportInfo, type AstStatementType, type ClassifiedStatement, type CustomCodeBlock, parseInfrastructure, convertToResourcePlan, classifyStatements, extractCustomCodeBlocks, findManagedResourcePosition, getLastManagedStatementOfType, getManagedResourcesByType, } from "./astInfrastructureParser.js";
3
+ export { type SurgicalModificationResult, type InsertionOptions, type UpdateOptions, type DeleteOptions, addResourceSurgically, updateResourceSurgically, removeResourceSurgically, } from "./astSurgicalModification.js";
4
+ export { type FileValidationResult, ensureImports, injectCustomCodeBlocks, validateModifiedFile, } from "./astCodeInjection.js";
4
5
  export { type DomainCallMatch, type ParsedFjallTarget, type ParsedDnsRecordFromAst, type ParsedCertificateFromAst, type ParsedDelegationFromAst, type ParsedDomainProps, type ParsedRoute53ApexDomainProps, type ParsedExternalDelegatedDomainProps, type ParsedExternalRecordsDomainProps, type ParseDomainError, findDomainConstructCall, parseDomainProps, parseDomainErrorMessage, splitTopLevelArgs, } from "./astDomainParser.js";