@fjall/generator 0.96.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 (81) 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/astComputeParser.js +1 -1
  5. package/dist/src/ast/astComputeParserHelpers.js +1 -1
  6. package/dist/src/ast/astDatabaseParser.d.ts +5 -2
  7. package/dist/src/ast/astDatabaseParser.js +1 -1
  8. package/dist/src/ast/astInfrastructureParser.d.ts +6 -0
  9. package/dist/src/ast/astInfrastructureParser.js +1 -1
  10. package/dist/src/ast/astPlanConverter.js +2 -2
  11. package/dist/src/ast/astScheduleParser.d.ts +18 -0
  12. package/dist/src/ast/astScheduleParser.js +1 -0
  13. package/dist/src/ast/astTestHelpers.d.ts +40 -6
  14. package/dist/src/codemod/edits/crossPlanConnection.d.ts +2 -6
  15. package/dist/src/codemod/edits/vpcPeer.d.ts +2 -6
  16. package/dist/src/codemod/edits/vpcPeerAccepter.d.ts +2 -5
  17. package/dist/src/codemod/edits/vpcPeerAccepter.js +1 -1
  18. package/dist/src/codemod/index.d.ts +1 -1
  19. package/dist/src/codemod/llmFallback/prompt.js +13 -13
  20. package/dist/src/codemod/llmFallback/tierRunner.js +1 -1
  21. package/dist/src/codemod/types.d.ts +5 -0
  22. package/dist/src/detection/index.d.ts +148 -0
  23. package/dist/src/detection/index.js +1 -0
  24. package/dist/src/generation/common.d.ts +22 -0
  25. package/dist/src/generation/common.js +5 -4
  26. package/dist/src/generation/compute/ec2.d.ts +2 -0
  27. package/dist/src/generation/compute/ec2.js +4 -0
  28. package/dist/src/generation/compute/ecs.d.ts +2 -0
  29. package/dist/src/generation/compute/ecs.js +42 -0
  30. package/dist/src/generation/compute/lambda.d.ts +3 -0
  31. package/dist/src/generation/compute/lambda.js +26 -0
  32. package/dist/src/generation/compute/shared.d.ts +22 -0
  33. package/dist/src/generation/compute/shared.js +4 -0
  34. package/dist/src/generation/compute.d.ts +4 -5
  35. package/dist/src/generation/compute.js +6 -86
  36. package/dist/src/generation/database.d.ts +11 -0
  37. package/dist/src/generation/database.js +23 -12
  38. package/dist/src/generation/index.d.ts +1 -1
  39. package/dist/src/generation/index.js +1 -1
  40. package/dist/src/generation/infrastructure.js +5 -5
  41. package/dist/src/generation/storage.js +30 -30
  42. package/dist/src/index.d.ts +1 -1
  43. package/dist/src/index.js +1 -1
  44. package/dist/src/planning/resourceAddition.d.ts +5 -1
  45. package/dist/src/planning/resourceAddition.js +1 -1
  46. package/dist/src/planning/resourcePlanning.js +1 -1
  47. package/dist/src/presets/clickhouseTierPreset.d.ts +35 -0
  48. package/dist/src/presets/clickhouseTierPreset.js +0 -0
  49. package/dist/src/presets/tierPresets.d.ts +5 -12
  50. package/dist/src/presets/tierPresets.js +1 -1
  51. package/dist/src/presets/tierTypes.d.ts +9 -19
  52. package/dist/src/schemas/applicationSchemas.d.ts +51 -8
  53. package/dist/src/schemas/applicationSchemas.js +1 -1
  54. package/dist/src/schemas/baseSchemas.d.ts +16 -0
  55. package/dist/src/schemas/baseSchemas.js +2 -2
  56. package/dist/src/schemas/computeSchemas.d.ts +108 -14
  57. package/dist/src/schemas/computeSchemas.js +1 -1
  58. package/dist/src/schemas/constants.d.ts +14 -0
  59. package/dist/src/schemas/constants.js +1 -1
  60. package/dist/src/schemas/databaseSchemas.d.ts +80 -0
  61. package/dist/src/schemas/databaseSchemas.js +1 -1
  62. package/dist/src/schemas/networkSchemas.d.ts +7 -6
  63. package/dist/src/schemas/networkSchemas.js +1 -1
  64. package/dist/src/schemas/patternSchemas.js +1 -1
  65. package/dist/src/schemas/sharedTypes.d.ts +1 -1
  66. package/dist/src/schemas/sharedTypes.js +1 -1
  67. package/dist/src/validation/patterns.d.ts +1 -1
  68. package/dist/src/validation/patterns.js +1 -1
  69. package/dist/src/validation/validationMessages.d.ts +5 -4
  70. package/dist/src/validation/validationMessages.js +1 -1
  71. package/dist/src/validation/validationPatterns.d.ts +14 -0
  72. package/dist/src/validation/validationPatterns.js +1 -1
  73. package/dist/src/version.d.ts +1 -1
  74. package/dist/src/version.js +1 -1
  75. package/package.json +19 -13
  76. package/dist/src/codemod/drift/__tests__/fixtures.d.ts +0 -55
  77. package/dist/src/codemod/drift/__tests__/fixtures.js +0 -2
  78. package/dist/src/codemod/llmFallback/__tests__/fixtures.d.ts +0 -5
  79. package/dist/src/codemod/llmFallback/__tests__/fixtures.js +0 -7
  80. package/dist/src/codemod/telemetry/__tests__/errorKinds.fixture.d.ts +0 -1
  81. package/dist/src/codemod/telemetry/__tests__/errorKinds.fixture.js +0 -1
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 132 files minified at 2026-04-27T00:08:23.229Z
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};
@@ -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,8 +8,10 @@ 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";
@@ -19,10 +21,12 @@ 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};
@@ -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";
@@ -1,6 +1,6 @@
1
1
  import type { CrossPlanConnectionResourcePlan } from "../../schemas/applicationSchemas.js";
2
2
  import { type Result } from "../../types/Result.js";
3
- import type { CodemodError, LinesChanged } from "../types.js";
3
+ import type { CodemodError, EditOrchestratorSuccess } from "../types.js";
4
4
  export type CrossPlanConnectionAddOptions = Omit<CrossPlanConnectionResourcePlan, "name"> & {
5
5
  name: string;
6
6
  filePath?: string;
@@ -14,11 +14,7 @@ export type CrossPlanConnectionModifyOptions = Partial<Omit<CrossPlanConnectionR
14
14
  name: string;
15
15
  filePath?: string;
16
16
  };
17
- export interface CrossPlanConnectionOrchestratorSuccess {
18
- content: string;
19
- linesChanged: LinesChanged;
20
- warnings?: string[];
21
- }
17
+ export type CrossPlanConnectionOrchestratorSuccess = EditOrchestratorSuccess;
22
18
  export declare function addCrossPlanConnection(content: string, options: CrossPlanConnectionAddOptions): Result<CrossPlanConnectionOrchestratorSuccess, CodemodError>;
23
19
  export declare function removeCrossPlanConnection(content: string, options: CrossPlanConnectionRemoveOptions): Result<CrossPlanConnectionOrchestratorSuccess, CodemodError>;
24
20
  export declare function modifyCrossPlanConnection(content: string, options: CrossPlanConnectionModifyOptions): Result<CrossPlanConnectionOrchestratorSuccess, CodemodError>;
@@ -1,6 +1,6 @@
1
1
  import type { VpcPeerResourcePlan } from "../../schemas/networkSchemas.js";
2
2
  import { type Result } from "../../types/Result.js";
3
- import type { CodemodError, LinesChanged, PermissionError } from "../types.js";
3
+ import type { CodemodError, EditOrchestratorSuccess, PermissionError } from "../types.js";
4
4
  export type VpcPeerAddOptions = Omit<VpcPeerResourcePlan, "name"> & {
5
5
  name: string;
6
6
  filePath?: string;
@@ -16,11 +16,7 @@ export type VpcPeerModifyOptions = Partial<Omit<VpcPeerResourcePlan, "name">> &
16
16
  filePath?: string;
17
17
  currentAccount?: string;
18
18
  };
19
- export interface VpcPeerOrchestratorSuccess {
20
- content: string;
21
- linesChanged: LinesChanged;
22
- warnings?: string[];
23
- }
19
+ export type VpcPeerOrchestratorSuccess = EditOrchestratorSuccess;
24
20
  export declare function addVpcPeer(content: string, options: VpcPeerAddOptions): Result<VpcPeerOrchestratorSuccess, CodemodError>;
25
21
  export declare function removeVpcPeer(content: string, options: VpcPeerRemoveOptions): Result<VpcPeerOrchestratorSuccess, CodemodError>;
26
22
  export declare function modifyVpcPeer(content: string, options: VpcPeerModifyOptions): Result<VpcPeerOrchestratorSuccess, CodemodError>;
@@ -1,6 +1,6 @@
1
1
  import type { VpcPeerAccepterResourcePlan } from "../../schemas/networkSchemas.js";
2
2
  import { type Result } from "../../types/Result.js";
3
- import type { CodemodError, LinesChanged } from "../types.js";
3
+ import type { CodemodError, EditOrchestratorSuccess } from "../types.js";
4
4
  export type VpcPeerAccepterAddOptions = Omit<VpcPeerAccepterResourcePlan, "name"> & {
5
5
  name: string;
6
6
  filePath?: string;
@@ -14,10 +14,7 @@ export type VpcPeerAccepterModifyOptions = Partial<Omit<VpcPeerAccepterResourceP
14
14
  name: string;
15
15
  filePath?: string;
16
16
  };
17
- export interface VpcPeerAccepterOrchestratorSuccess {
18
- content: string;
19
- linesChanged: LinesChanged;
20
- }
17
+ export type VpcPeerAccepterOrchestratorSuccess = EditOrchestratorSuccess;
21
18
  export declare function addVpcPeerAccepter(content: string, options: VpcPeerAccepterAddOptions): Result<VpcPeerAccepterOrchestratorSuccess, CodemodError>;
22
19
  export declare function removeVpcPeerAccepter(content: string, options: VpcPeerAccepterRemoveOptions): Result<VpcPeerAccepterOrchestratorSuccess, CodemodError>;
23
20
  export declare function modifyVpcPeerAccepter(content: string, options: VpcPeerAccepterModifyOptions): Result<VpcPeerAccepterOrchestratorSuccess, CodemodError>;
@@ -1 +1 @@
1
- import{failure as i,success as u}from"../../types/Result.js";import{addResource as l}from"./addResource.js";import{modifyResource as p}from"./modifyResource.js";import{removeResource as m}from"./removeResource.js";import{buildWildcardRejection as h}from"./vpcPeer.js";const d="vpc-peer-accepter";function A(n,e){const r=f(e);if(r!==void 0)return i(r);const{name:c,filePath:a,...o}=e,s={...o},t=l(n,{type:d,name:c,properties:s,...a!==void 0?{filePath:a}:{}});return t.success?u({content:t.data.content,linesChanged:t.data.linesChanged}):i(t.error)}function v(n,e){const r=m(n,{type:d,name:e.name,...e.filePath!==void 0?{filePath:e.filePath}:{},...e.force!==void 0?{force:e.force}:{}});return r.success?u({content:r.data.content,linesChanged:r.data.linesChanged}):i(r.error)}function x(n,e){const r=f(e);if(r!==void 0)return i(r);const{name:c,filePath:a,...o}=e,s={...o},t=p(n,{type:d,name:c,properties:s,...a!==void 0?{filePath:a}:{}});return t.success?u({content:t.data.content,linesChanged:t.data.linesChanged}):i(t.error)}function f(n){const{name:e,filePath:r,...c}=n;return h(d,c,"Replace the wildcard with a concrete 12-digit AWS account id.")}export{A as addVpcPeerAccepter,x as modifyVpcPeerAccepter,v as removeVpcPeerAccepter};
1
+ import{failure as a,success as p}from"../../types/Result.js";import{addResource as m}from"./addResource.js";import{modifyResource as s}from"./modifyResource.js";import{removeResource as l}from"./removeResource.js";import{buildWildcardRejection as P}from"./vpcPeer.js";const i="vpc-peer-accepter";function f(e){return e.success?p({content:e.data.content,linesChanged:e.data.linesChanged}):a(e.error)}function E(e,r){const t=u(r);if(t!==void 0)return a(t);const{name:n,filePath:c,...d}=r,o={...d};return f(m(e,{type:i,name:n,properties:o,...c!==void 0?{filePath:c}:{}}))}function v(e,r){return f(l(e,{type:i,name:r.name,...r.filePath!==void 0?{filePath:r.filePath}:{},...r.force!==void 0?{force:r.force}:{}}))}function w(e,r){const t=u(r);if(t!==void 0)return a(t);const{name:n,filePath:c,...d}=r,o={...d};return f(s(e,{type:i,name:n,properties:o,...c!==void 0?{filePath:c}:{}}))}function u(e){const{name:r,filePath:t,...n}=e;return P(i,n,"Replace the wildcard with a concrete 12-digit AWS account id.")}export{E as addVpcPeerAccepter,w as modifyVpcPeerAccepter,v as removeVpcPeerAccepter};
@@ -16,4 +16,4 @@ export { CODEMOD_ERROR_KINDS } from "./telemetry/errorKinds.js";
16
16
  export type { CodemodErrorKind } from "./telemetry/errorKinds.js";
17
17
  export type { GateId } from "./validationGate/index.js";
18
18
  export { buildEgressBlockedEvent, buildFiredEvent, buildGateFailedEvent, buildGatePassedEvent, buildRejectedEvent, buildSucceededEvent, buildTimeoutEvent, estimateCostUsd, FALLBACK_EVENTS, GATE_EVENTS, PARSE_GATE, RUNTIME_GATE, runFallback, shouldTryFallback, type AnthropicClientProvider, type FallbackClients, type FallbackDecision, type FallbackEgressBlockedEvent, type FallbackGuardConfig, type FallbackInput, type FallbackIntent, type FallbackOp, type FallbackOutput, type FallbackTelemetry, type FallbackTelemetryEvent, type MorphClientProvider, type RunFallbackInput, type TelemetrySource, type TriggerReason, } from "./llmFallback/index.js";
19
- export type { AddOptions, CodemodError, CodemodSuccess, ControlFlowClassifierError, DriftConflictError, DriftUnmergeableError, DuplicateResourceError, InvalidPropertyError, LinesChanged, LlmFallbackRejectedError, LlmFallbackTimeoutError, LlmFallbackTier, LlmFallbackUnsafeInputError, ModifyOptions, NodeLocation, ParseError, PermissionError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceListing, ResourceListingEntry, ResourceName, ResourceNotFoundError, SemanticQueryError, StatementType, TemplateLiteralNameError, } from "./types.js";
19
+ export type { AddOptions, CodemodError, CodemodSuccess, ControlFlowClassifierError, DriftConflictError, DriftUnmergeableError, DuplicateResourceError, EditOrchestratorSuccess, InvalidPropertyError, LinesChanged, LlmFallbackRejectedError, LlmFallbackTimeoutError, LlmFallbackTier, LlmFallbackUnsafeInputError, ModifyOptions, NodeLocation, ParseError, PermissionError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceListing, ResourceListingEntry, ResourceName, ResourceNotFoundError, SemanticQueryError, StatementType, TemplateLiteralNameError, } from "./types.js";
@@ -1,9 +1,9 @@
1
- import{z as c}from"zod";import{STATEMENT_REGISTRY as o}from"../registry.js";const l=[...new Set(Object.values(o).map(e=>e.factoryIdentifier))].join(", "),s=`You are a Fjall infrastructure code editor. You modify TypeScript infrastructure files that use the Fjall CDK factory pattern.
1
+ import{z as u}from"zod";import{STATEMENT_REGISTRY as s}from"../registry.js";const p=[...new Set(Object.values(s).map(e=>e.factoryIdentifier))].join(", "),a=`You are a Fjall infrastructure code editor. You modify TypeScript infrastructure files that use the Fjall CDK factory pattern.
2
2
 
3
3
  Each resource is declared as a factory call:
4
4
  \`XFactory.build("ResourceName", { ...properties })\`
5
5
 
6
- where X is one of: ${l}.
6
+ where X is one of: ${p}.
7
7
 
8
8
  ## Rules
9
9
 
@@ -13,24 +13,24 @@ where X is one of: ${l}.
13
13
  4. Preserve the quote style used in the file (single or double quotes).
14
14
  5. Do not move resource declarations into conditional blocks, loops, or function bodies. All factory calls must remain at module top level.
15
15
  6. If you cannot produce a valid edit, respond with an empty tool_use \u2014 do not guess.
16
- 7. Properties must conform to the schema provided below. Do not invent property names.`;function u(e){return e==="morph"?`${s}
16
+ 7. Properties must conform to the schema provided below. Do not invent property names.`;function d(e){return e==="morph"?`${a}
17
17
 
18
- You are operating as a fast-apply tier. Produce minimal, precise edits only.`:s}function p(e){const t=o[e.type].factoryIdentifier;switch(e.op){case"add":return`Add a new ${e.type} resource named "${e.name}" using ${t}.build("${e.name}", { ... }) with the properties specified below.`;case"remove":return`Remove the ${e.type} resource named "${e.name}" (the ${t}.build("${e.name}", ...) call and any directly related code). Preserve all other resources.`;case"modify":return`Modify the ${e.type} resource named "${e.name}" by updating its properties to match the values specified below. Keep properties not mentioned in the update unchanged.`;case"resolve-drift-merge":return`Resolve a drift conflict on the ${e.type} resource named "${e.name}". The resource has been edited manually since Fjall last wrote it, and the requested properties conflict with the manual edits. Merge the two sets of changes: apply the requested properties below while preserving any manual edits to OTHER properties not listed in the update. Use ${t}.build("${e.name}", { ... }) with the merged property set.`}}function d(e){const r=o[e.type],t=c.toJSONSchema(r.schemaFragment,{io:"input"});return`## Property Schema for ${e.type}
18
+ You are operating as a fast-apply tier. Produce minimal, precise edits only.`:a}function m(e){const t=s[e.type].factoryIdentifier;switch(e.op){case"add":return`Add a new ${e.type} resource named "${e.name}" using ${t}.build("${e.name}", { ... }) with the properties specified below.`;case"remove":return`Remove the ${e.type} resource named "${e.name}" (the ${t}.build("${e.name}", ...) call and any directly related code). Preserve all other resources.`;case"modify":return`Modify the ${e.type} resource named "${e.name}" by updating its properties to match the values specified below. Keep properties not mentioned in the update unchanged.`;case"resolve-drift-merge":return`Resolve a drift conflict on the ${e.type} resource named "${e.name}". The resource has been edited manually since Fjall last wrote it, and the requested properties conflict with the manual edits. Merge the two sets of changes: apply the requested properties below while preserving any manual edits to OTHER properties not listed in the update. Use ${t}.build("${e.name}", { ... }) with the merged property set.`}}function h(e){const o=s[e.type],t=u.toJSONSchema(o.schemaFragment,{io:"input"}),r=JSON.stringify(t,null,2),n=i(r);return`## Property Schema for ${e.type}
19
19
 
20
- \`\`\`json
21
- ${JSON.stringify(t,null,2)}
22
- \`\`\``}function m(e){if(e.op==="remove")return"";const r=Object.fromEntries(Object.entries(e.properties).filter(([,t])=>t!==void 0));return Object.keys(r).length===0?"":`## Target Properties
20
+ ${n}json
21
+ ${r}
22
+ ${n}`}function f(e){if(e.op==="remove")return"";const o=Object.fromEntries(Object.entries(e.properties).filter(([,n])=>n!==void 0));if(Object.keys(o).length===0)return"";const t=JSON.stringify(o,null,2),r=i(t);return`## Target Properties
23
23
 
24
- \`\`\`json
25
- ${JSON.stringify(r,null,2)}
26
- \`\`\``}function y(e){const r=u(e.tier),t=p(e.intent),n=d(e.intent),i=m(e.intent),a=`## Task
24
+ ${r}json
25
+ ${t}
26
+ ${r}`}function i(e){const o=e.match(/`+/g)??[];let t=0;for(const r of o)r.length>t&&(t=r.length);return"`".repeat(Math.max(3,t+1))}function b(e){const o=d(e.tier),t=m(e.intent),r=h(e.intent),n=f(e.intent),c=i(e.content),l=`## Task
27
27
 
28
28
  ${t}
29
29
 
30
+ ${r}
30
31
  ${n}
31
- ${i}
32
32
  ## Current File
33
33
 
34
- \`\`\`typescript
34
+ ${c}typescript
35
35
  ${e.content}
36
- \`\`\``.trim();return{systemPrompt:r,userPrompt:a}}export{y as buildPrompt};
36
+ ${c}`.trim();return{systemPrompt:o,userPrompt:l}}export{b as buildPrompt};
@@ -1 +1 @@
1
- import{linkAbortSignals as d}from"./signals.js";import{RUNTIME_GATE as f}from"./types.js";async function p(n,r,l,s){const a=new AbortController,{signal:c,cleanup:u}=d(n,a);let t,i=!1;const o=Date.now();try{return t=setTimeout(()=>{i=!0,a.abort()},l),await s({signal:c,started:o})}catch(e){return n?.aborted?{state:"cancelled"}:i?{state:"timeout",tier:r,elapsedMs:Date.now()-o}:{state:"rejected",tier:r,failedGate:f,diagnostics:e instanceof Error?e.message:String(e)}}finally{t!==void 0&&clearTimeout(t),u()}}export{p as withTierTimeout};
1
+ import{maskSensitiveOutput as m}from"@fjall/util";import{linkAbortSignals as d}from"./signals.js";import{RUNTIME_GATE as f}from"./types.js";async function w(r,n,l,s){const i=new AbortController,{signal:u,cleanup:c}=d(r,i);let t,a=!1;const o=Date.now();try{return t=setTimeout(()=>{a=!0,i.abort()},l),await s({signal:u,started:o})}catch(e){return r?.aborted?{state:"cancelled"}:a?{state:"timeout",tier:n,elapsedMs:Date.now()-o}:{state:"rejected",tier:n,failedGate:f,diagnostics:m(e instanceof Error?e.message:String(e))}}finally{t!==void 0&&clearTimeout(t),c()}}export{w as withTierTimeout};
@@ -157,6 +157,11 @@ export declare const CodemodSuccessSchema: z.ZodObject<{
157
157
  warnings: z.ZodOptional<z.ZodArray<z.ZodString>>;
158
158
  }, z.core.$strict>;
159
159
  export type CodemodSuccess = z.infer<typeof CodemodSuccessSchema>;
160
+ export interface EditOrchestratorSuccess {
161
+ content: string;
162
+ linesChanged: LinesChanged;
163
+ warnings?: string[];
164
+ }
160
165
  /** @internal Bridging tuple across the ts-morph / recast boundary (ADR §1). */
161
166
  export interface NodeLocation {
162
167
  filePath: string;