@fjall/generator 9.0.0 → 10.1.2

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.
@@ -9,7 +9,7 @@
9
9
  "package.json",
10
10
  "tsconfig.json"
11
11
  ],
12
- "hash": "ad0983e8acdd6ab00f35788c1a68734a2a72ae29e370dc810e7d1c4491996315",
12
+ "hash": "5b175a710669adc822d3af8fec13e49d7605546ad52e976b4e4d7bbc5210927d",
13
13
  "files": {
14
14
  "src/ast/astTestHelpers.ts": "026cac849eb88bdb",
15
15
  "src/ast/domain/astDomainParser.ts": "940ce5742507477d",
@@ -26,7 +26,7 @@
26
26
  "src/ast/parsers/resources/astClickHouseParser.ts": "cf49943b3d2bbd48",
27
27
  "src/ast/parsers/resources/astComputeConnectionParser.ts": "e0f1533845f3ce8a",
28
28
  "src/ast/parsers/resources/astComputeParser.ts": "98e4a2e6b2d634fa",
29
- "src/ast/parsers/resources/astComputeParserHelpers.ts": "6e0349d365bcf6cf",
29
+ "src/ast/parsers/resources/astComputeParserHelpers.ts": "b824f221f8c7e3d9",
30
30
  "src/ast/parsers/resources/astDatabaseParser.ts": "e18f5483f5e23297",
31
31
  "src/ast/parsers/resources/astDynamoDBParser.ts": "809c2c633447b388",
32
32
  "src/ast/parsers/resources/astMessagingParser.ts": "b185ec22e6b96943",
@@ -41,7 +41,7 @@
41
41
  "src/codemod/drift/merge.ts": "29093929befa9abd",
42
42
  "src/codemod/drift/snapshot.ts": "d3c70df4f8537237",
43
43
  "src/codemod/drift/types.ts": "7f1d7899e420e4d7",
44
- "src/codemod/edits/addResource.ts": "c8fe476d5ef589fe",
44
+ "src/codemod/edits/addResource.ts": "dacb2e18657b74cf",
45
45
  "src/codemod/edits/addResource/appBinding.ts": "3553fdb30fe06335",
46
46
  "src/codemod/edits/addResource/bodyIndex.ts": "3e179eac10d7bcf4",
47
47
  "src/codemod/edits/addResource/propertyBuilder.ts": "9102dff7e9fab376",
@@ -54,11 +54,11 @@
54
54
  "src/codemod/edits/ensureImports.ts": "3ca0b6d446c4333c",
55
55
  "src/codemod/edits/findInsertionPosition.ts": "20cd34fdcf781017",
56
56
  "src/codemod/edits/index.ts": "bea5ed7c3983342b",
57
- "src/codemod/edits/modifyResource.ts": "c27380cf9dae5dfc",
57
+ "src/codemod/edits/modifyResource.ts": "2c47fdf60ad340e4",
58
58
  "src/codemod/edits/modifyResource/literalConversion.ts": "31295cccd59131b7",
59
59
  "src/codemod/edits/moduleConstResolver.ts": "85a8597427849a80",
60
60
  "src/codemod/edits/objectGraph.ts": "5efc4181547237f8",
61
- "src/codemod/edits/removeResource.ts": "2c7c8fe67bc3a866",
61
+ "src/codemod/edits/removeResource.ts": "6af70ee482fabc06",
62
62
  "src/codemod/edits/removeResource/commentHeuristic.ts": "90b6ce7ba5aa2a48",
63
63
  "src/codemod/edits/removeResource/importPruning.ts": "f22783108b40f6cb",
64
64
  "src/codemod/edits/secretsProvability.ts": "d723283918e31efd",
@@ -66,7 +66,7 @@
66
66
  "src/codemod/edits/unmanagedShapeErrors.ts": "47a2644913c8e619",
67
67
  "src/codemod/edits/vpcPeer.ts": "0bcf90c2e6d16ca4",
68
68
  "src/codemod/edits/vpcPeerAccepter.ts": "c9eace933e9e2345",
69
- "src/codemod/emitGuard.ts": "652d9b188276acf8",
69
+ "src/codemod/emitGuard.ts": "d11e4297781ca81c",
70
70
  "src/codemod/emitProjection.ts": "9a47ef44995be65f",
71
71
  "src/codemod/fileRewriter/builders.ts": "46a0d43240ff0818",
72
72
  "src/codemod/fileRewriter/index.ts": "fd715b41176a7999",
@@ -89,7 +89,7 @@
89
89
  "src/codemod/llmFallback/telemetryEvents.ts": "33a85939739693ab",
90
90
  "src/codemod/llmFallback/tierRunner.ts": "a26094accd78cf15",
91
91
  "src/codemod/llmFallback/types.ts": "14af8d2bd9afae12",
92
- "src/codemod/registry.ts": "e4c9ae5ccc782b7f",
92
+ "src/codemod/registry.ts": "fca9df965dd2d7ed",
93
93
  "src/codemod/semanticIndex/classifyControlFlow.ts": "ed96215d91a3cae3",
94
94
  "src/codemod/semanticIndex/findReferences.ts": "96aea37418d1e91a",
95
95
  "src/codemod/semanticIndex/index.ts": "cfcd212d34ab20fb",
@@ -99,11 +99,11 @@
99
99
  "src/codemod/semanticIndex/resolveConstructByLiteralProperty.ts": "2d013a330af15c5c",
100
100
  "src/codemod/telemetry/errorKinds.ts": "66c736abfa8b3a67",
101
101
  "src/codemod/types.ts": "0cd929df5bb46696",
102
- "src/codemod/validationGate/gates/classify.ts": "edb92a1f7a2d9aeb",
102
+ "src/codemod/validationGate/gates/classify.ts": "3cba0ee8fe6d94d9",
103
103
  "src/codemod/validationGate/gates/drift.ts": "bd603a216fbb91a9",
104
104
  "src/codemod/validationGate/gates/locate.ts": "2c186c32edbb97ce",
105
105
  "src/codemod/validationGate/gates/parse.ts": "5433c5c8ffa35324",
106
- "src/codemod/validationGate/gates/schema.ts": "aa904146e30219bd",
106
+ "src/codemod/validationGate/gates/schema.ts": "7ed5acaec0620a46",
107
107
  "src/codemod/validationGate/index.ts": "df5754bea9070410",
108
108
  "src/codemod/validationGate/types.ts": "af466ee5f3433042",
109
109
  "src/detection/index.ts": "b4ad9a935564cb3e",
@@ -116,7 +116,7 @@
116
116
  "src/generation/common.ts": "ab66eac580bc227f",
117
117
  "src/generation/compute.ts": "4029a0d8e3197686",
118
118
  "src/generation/compute/ec2.ts": "4d8187d293a57fb1",
119
- "src/generation/compute/ecs.ts": "72190132fdaa1847",
119
+ "src/generation/compute/ecs.ts": "38a345cbd45c40d4",
120
120
  "src/generation/compute/lambda.ts": "4f5e31080941b83a",
121
121
  "src/generation/compute/shared.ts": "3724d4bfe92cfcb7",
122
122
  "src/generation/database.ts": "dd4a1540986ad350",
@@ -133,7 +133,7 @@
133
133
  "src/planning/planBuilders.ts": "bea93d0c05caef21",
134
134
  "src/planning/resourceAddition.ts": "ba27203af283d840",
135
135
  "src/planning/resourceConnections.ts": "a6b7db8f733e560f",
136
- "src/planning/resourcePlanning.ts": "6c966fe586fff080",
136
+ "src/planning/resourcePlanning.ts": "1fefdbc93e12ba7f",
137
137
  "src/planning/staticSitePlanning.ts": "242af1e9618821ab",
138
138
  "src/presets/clickhouseTierPreset.ts": "72b2b8a8caf4bdb4",
139
139
  "src/presets/index.ts": "8332c0198b2a6fe9",
@@ -150,8 +150,8 @@
150
150
  "src/schemas/baseSchemas.ts": "93d9bd1c0adfcaa0",
151
151
  "src/schemas/buildkiteSchemas.ts": "a28ec3b40f7851ec",
152
152
  "src/schemas/cdnSchemas.ts": "a982034c7903a31a",
153
- "src/schemas/computeSchemas.ts": "516df862131921fe",
154
- "src/schemas/constants.ts": "1df67cde0522a514",
153
+ "src/schemas/computeSchemas.ts": "907747add0b1e1a9",
154
+ "src/schemas/constants.ts": "52cabac20382fbc9",
155
155
  "src/schemas/databaseSchemas.ts": "3c05f176e1aadb46",
156
156
  "src/schemas/devRolePolicies.ts": "6ca70fb20f5fbebc",
157
157
  "src/schemas/index.ts": "a1500a885048074b",
@@ -169,11 +169,11 @@
169
169
  "src/validation/patterns.ts": "f9629eafdad7ac3e",
170
170
  "src/validation/validationMessages.ts": "c727ade4690274f4",
171
171
  "src/validation/validationPatterns.ts": "865f3d688975b7c8",
172
- "src/version.ts": "27d242fcf04ce64a",
172
+ "src/version.ts": "f76d0e8359ab9f9a",
173
173
  "../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
174
- "package.json": "8ff7f2a2605bff3a",
174
+ "package.json": "f373e1cdb8a703b0",
175
175
  "tsconfig.json": "1929cf3f99fe9b1e"
176
176
  },
177
- "outputHash": "764ac0887b73972f66e833ef1670b1225c82080d76940e2dc6781c0a873419f0",
177
+ "outputHash": "44f500f10015045f9e609f1888a6ac31b9d9589d5739516c43a12c6b974b69fa",
178
178
  "outputFileCount": 319
179
179
  }
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 159 files minified at 2026-08-09T10:17:00.891Z
1
+ 159 files minified at 2026-08-12T11:07:56.613Z
@@ -216,6 +216,7 @@ export declare function parseAndConvert(code: string): {
216
216
  priority?: number | undefined;
217
217
  healthCheckPath?: string | undefined;
218
218
  }[] | undefined;
219
+ serviceType?: "web" | "worker" | undefined;
219
220
  cpu?: number | undefined;
220
221
  memoryLimitMiB?: number | undefined;
221
222
  desiredCount?: number | undefined;
@@ -1 +1 @@
1
- var S=Object.defineProperty;var a=(e,n)=>S(e,"name",{value:n,configurable:!0});import{isPlainObject as y,isParsedObject as s,isExpressionRef as C,isCallRef as h,asString as r,asNumber as i,asBoolean as f,asStringArray as m,asStringUnion as d,captureExtraProperties as p}from"../common/astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as E,LOAD_BALANCER_TYPES as P,SCALING_TYPES as _,AMI_HARDWARE_TYPES as x}from"../../../schemas/constants.js";function A(e){return e!==void 0&&y(e)}a(A,"isEnvironmentRecord");function N(e){if(!s(e))return;const n={};for(const[t,o]of Object.entries(e))if(s(o)){const c=r(o.id),u=r(o.name);c&&u&&(n[t]={id:c,name:u,field:r(o.field)})}return Object.keys(n).length>0?n:void 0}a(N,"parseContainerSecretsImport");function g(e){if(!s(e))return;const n=m(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)}}a(g,"parseContainerHealthCheck");function O(e){const t=p(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:A(e.environment)?e.environment:void 0,essential:f(e.essential),command:m(e.command),entryPoint:m(e.entryPoint),secretsImport:N(e.secretsImport),ssmSecrets:m(e.secrets),healthCheck:g(e.healthCheck),extraProperties:t.length>0?t:void 0}}a(O,"parseServiceContainer");function T(e){if(Array.isArray(e))return e.filter(s).map(n=>({path:r(n.path),host:r(n.host),priority:i(n.priority),healthCheckPath:r(n.healthCheckPath)}));if(s(e))return{path:r(e.path),host:r(e.host),priority:i(e.priority),healthCheckPath:r(e.healthCheckPath)}}a(T,"parseServiceRouting");function I(e){if(e===!1)return!1;if(s(e))return{minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),desiredCount:i(e.desiredCount),scalingType:d(e.scalingType,_)}}a(I,"parseServiceScaling");const R=new Set(["instanceType","amiHardwareType","minCapacity","maxCapacity","memoryLimitMiB","warmPool"]);function l(e){if(!s(e))return;const n=e.warmPool,t=s(n)?{minSize:i(n.minSize),reuseOnScaleIn:f(n.reuseOnScaleIn)}:void 0,o=p(e,R);return{instanceType:r(e.instanceType),amiHardwareType:d(e.amiHardwareType,x),minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),memoryLimitMiB:i(e.memoryLimitMiB),warmPool:t,extraProperties:o.length>0?o:void 0}}a(l,"parseServiceEc2Config");const B=new Set(["domain","loadBalancer","directAccess"]);function k(e){if(!s(e))return;const n=e.loadBalancer,t=p(e,B);return{domain:r(e.domain),loadBalancer:n===!1?!1:d(n,P),directAccess:f(e.directAccess),...t.length>0&&{extraProperties:t}}}a(k,"extractClusterConfig");function W(e){const n=e.containers,t=Array.isArray(n)?n.filter(s).map(O):void 0,c=p(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:K(e.docker),ssmSecretsPath:r(e.ssmSecretsPath),containers:t,routing:T(e.routing),cpu:i(e.cpu),memoryLimitMiB:i(e.memoryLimitMiB),desiredCount:i(e.desiredCount),scaling:I(e.scaling),capacityProvider:d(e.capacityProvider,E)??"FARGATE",ec2Config:l(e.ec2Config),...c.length>0&&{extraProperties:c}}}a(W,"parseEcsService");function K(e){if(!s(e))return;const n=r(e.path);if(n===void 0)return;const t=r(e.context),o=r(e.target);return{path:n,...t!==void 0&&{context:t},...o!==void 0&&{target:o}}}a(K,"parseServiceDocker");function M(e,n){const t=r(e);if(t)return t;if(C(e)&&e.__expression.startsWith(n+"."))return e.__expression.slice(n.length+1)}a(M,"extractEnumString");function b(e){return h(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}a(b,"extractCallStringArg");function D(e,n,t){t!==void 0&&(e[n]=t)}a(D,"assignIfDefined");export{D as assignIfDefined,b as extractCallStringArg,k as extractClusterConfig,M as extractEnumString,A as isEnvironmentRecord,W as parseEcsService};
1
+ var S=Object.defineProperty;var a=(e,n)=>S(e,"name",{value:n,configurable:!0});import{isPlainObject as y,isParsedObject as s,isExpressionRef as C,isCallRef as h,asString as r,asNumber as i,asBoolean as f,asStringArray as d,asStringUnion as m,captureExtraProperties as p}from"../common/astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as E,ECS_SERVICE_TYPES as P,LOAD_BALANCER_TYPES as _,SCALING_TYPES as x,AMI_HARDWARE_TYPES as A}from"../../../schemas/constants.js";function N(e){return e!==void 0&&y(e)}a(N,"isEnvironmentRecord");function T(e){if(!s(e))return;const n={};for(const[t,o]of Object.entries(e))if(s(o)){const c=r(o.id),u=r(o.name);c&&u&&(n[t]={id:c,name:u,field:r(o.field)})}return Object.keys(n).length>0?n:void 0}a(T,"parseContainerSecretsImport");function g(e){if(!s(e))return;const n=d(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)}}a(g,"parseContainerHealthCheck");function O(e){const t=p(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:N(e.environment)?e.environment:void 0,essential:f(e.essential),command:d(e.command),entryPoint:d(e.entryPoint),secretsImport:T(e.secretsImport),ssmSecrets:d(e.secrets),healthCheck:g(e.healthCheck),extraProperties:t.length>0?t:void 0}}a(O,"parseServiceContainer");function I(e){if(Array.isArray(e))return e.filter(s).map(n=>({path:r(n.path),host:r(n.host),priority:i(n.priority),healthCheckPath:r(n.healthCheckPath)}));if(s(e))return{path:r(e.path),host:r(e.host),priority:i(e.priority),healthCheckPath:r(e.healthCheckPath)}}a(I,"parseServiceRouting");function R(e){if(e===!1)return!1;if(s(e))return{minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),desiredCount:i(e.desiredCount),scalingType:m(e.scalingType,x)}}a(R,"parseServiceScaling");const l=new Set(["instanceType","amiHardwareType","minCapacity","maxCapacity","memoryLimitMiB","warmPool"]);function B(e){if(!s(e))return;const n=e.warmPool,t=s(n)?{minSize:i(n.minSize),reuseOnScaleIn:f(n.reuseOnScaleIn)}:void 0,o=p(e,l);return{instanceType:r(e.instanceType),amiHardwareType:m(e.amiHardwareType,A),minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),memoryLimitMiB:i(e.memoryLimitMiB),warmPool:t,extraProperties:o.length>0?o:void 0}}a(B,"parseServiceEc2Config");const K=new Set(["domain","loadBalancer","directAccess"]);function W(e){if(!s(e))return;const n=e.loadBalancer,t=p(e,K);return{domain:r(e.domain),loadBalancer:n===!1?!1:m(n,_),directAccess:f(e.directAccess),...t.length>0&&{extraProperties:t}}}a(W,"extractClusterConfig");function M(e){const n=e.containers,t=Array.isArray(n)?n.filter(s).map(O):void 0,c=p(e,new Set(["name","image","docker","ssmSecretsPath","containers","routing","connections","serviceType","cpu","memoryLimitMiB","desiredCount","scaling","capacityProvider","ec2Config"]));return{name:r(e.name)??"",image:r(e.image),docker:w(e.docker),ssmSecretsPath:r(e.ssmSecretsPath),containers:t,routing:I(e.routing),serviceType:m(e.serviceType,P),cpu:i(e.cpu),memoryLimitMiB:i(e.memoryLimitMiB),desiredCount:i(e.desiredCount),scaling:R(e.scaling),capacityProvider:m(e.capacityProvider,E)??"FARGATE",ec2Config:B(e.ec2Config),...c.length>0&&{extraProperties:c}}}a(M,"parseEcsService");function w(e){if(!s(e))return;const n=r(e.path);if(n===void 0)return;const t=r(e.context),o=r(e.target);return{path:n,...t!==void 0&&{context:t},...o!==void 0&&{target:o}}}a(w,"parseServiceDocker");function b(e,n){const t=r(e);if(t)return t;if(C(e)&&e.__expression.startsWith(n+"."))return e.__expression.slice(n.length+1)}a(b,"extractEnumString");function D(e){return h(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}a(D,"extractCallStringArg");function H(e,n,t){t!==void 0&&(e[n]=t)}a(H,"assignIfDefined");export{H as assignIfDefined,D as extractCallStringArg,W as extractClusterConfig,b as extractEnumString,N as isEnvironmentRecord,M as parseEcsService};
@@ -1 +1 @@
1
- var D=Object.defineProperty;var u=(r,e)=>D(r,"name",{value:e,configurable:!0});import{failure as t,success as P}from"../../types/Result.js";import{DEFAULT_FILE_PATH as F,computeLinesDelta as M,extractProgramBody as C,isRecord as v}from"../_internal.js";import{evaluateEmitGuard as x}from"../emitGuard.js";import{projectEmittedProperties as w}from"../emitProjection.js";import{appendSpecifier as G,buildAppMethodWrappedStatement as N,buildFactoryStatement as Q,buildImportDeclaration as B,detectQuoteStyle as U,parse as _,printFile as O}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as W}from"../registry.js";import{locateAllShapes as j,locateByShape as Y}from"../semanticIndex/index.js";import{checkControlFlowPolicy as q}from"./controlFlowPolicy.js";import{driftGate as H,runPipeline as $,schemaGate as z}from"../validationGate/index.js";import{resolveAppBindingName as J}from"./addResource/appBinding.js";import{buildUnmanagedDuplicateError as K}from"./unmanagedShapeErrors.js";import{buildResourceLocations as V,indexBody as X,orderByEndPos as Z,resolveInsertIndex as ee}from"./addResource/bodyIndex.js";import{buildPropertyInputs as re}from"./addResource/propertyBuilder.js";import{findInsertionPosition as te}from"./findInsertionPosition.js";const k="@fjall/components-infrastructure";function ge(r,e,m={}){const s=e.filePath??F,o=_(r,s);if(!o.success)return t(o.error);const a=Y(r,{type:e.type,name:e.name},s);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?t(a.error):t({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data!==void 0){if(a.data.managed===!1)return t(K(e.type,a.data.symbolName));const d=q({ast:o.data,target:a.data,resource:{type:e.type,name:e.name},op:"add"});if(d.refusal!==void 0)return t(d.refusal);const h=$([z,H],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"},baseline:m.baseline,policy:e.driftPolicy});return h.success?h.data.action==="skip"?P({content:r,linesChanged:{added:0,removed:0},skipped:!0}):t({kind:"DuplicateResourceError",type:e.type,name:e.name}):t(ae(h.error))}const f=U(o.data),l=w(e.type,e.properties);if("refusal"in l)return t(l.refusal);const y=re(l.props,f);if(!y.success)return t(y.error);const c=C(o.data);if(c===void 0)return t({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const i=W[e.type],I=x(i.emitGuard,e.properties);if(I!==void 0)return t(I);const S={factory:i.factoryIdentifier,name:e.name,properties:y.data,quoteStyle:f};let E;if(i.emitWrapper!==void 0){const d=J(c);if(d===void 0)return t({kind:"MissingAppInitError",type:e.type,appMethod:i.emitWrapper.appMethod});E=N({...S,appIdentifier:d,appMethod:i.emitWrapper.appMethod})}else E=Q(S);const p=X(c,r),n=j(r,s);if(!n.success)return n.error.kind==="TemplateLiteralNameError"?t(n.error):t({kind:"SemanticQueryError",reason:n.error.reason,cause:n.error.cause});const L=V(p.anchors,n.data),R=Z([...p.appInitLocations,...L]),b=te(p.importInfos,R,e.type,p.programEnd),T=ee(p.anchors,b);c.splice(T,0,E),oe(c,i.factoryIdentifier,f);const g=O(o.data,r),A=M(r,g);return P({content:g,linesChanged:A})}u(ge,"addResource");function ae(r){switch(r.kind){case"ParseError":case"TemplateLiteralNameError":case"DuplicateResourceError":case"InvalidPropertyError":case"SemanticQueryError":case"MissingAppInitError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}u(ae,"narrowGateError");function oe(r,e,m){for(const o of r){if(o.type!=="ImportDeclaration")continue;const a=o.source;if(!(!v(a)||a.type!=="StringLiteral")&&a.value===k){G(o,e);return}}const s=B([e],k,m);r.unshift(s)}u(oe,"ensureFactoryImport");export{ge as addResource};
1
+ var M=Object.defineProperty;var u=(r,e)=>M(r,"name",{value:e,configurable:!0});import{failure as t,success as k}from"../../types/Result.js";import{DEFAULT_FILE_PATH as C,computeLinesDelta as v,extractProgramBody as x,isRecord as w}from"../_internal.js";import{evaluateEmitGuard as G}from"../emitGuard.js";import{projectEmittedProperties as N}from"../emitProjection.js";import{appendSpecifier as Q,buildAppMethodWrappedStatement as B,buildFactoryStatement as O,buildImportDeclaration as U,detectQuoteStyle as _,parse as W,printFile as j}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as Y}from"../registry.js";import{locateAllShapes as q,locateByShape as H}from"../semanticIndex/index.js";import{checkControlFlowPolicy as $}from"./controlFlowPolicy.js";import{driftGate as z,runPipeline as J,schemaGate as K}from"../validationGate/index.js";import{resolveAppBindingName as V}from"./addResource/appBinding.js";import{buildUnmanagedDuplicateError as X}from"./unmanagedShapeErrors.js";import{buildResourceLocations as Z,indexBody as ee,orderByEndPos as re,resolveInsertIndex as te}from"./addResource/bodyIndex.js";import{buildPropertyInputs as ae}from"./addResource/propertyBuilder.js";import{findInsertionPosition as ne}from"./findInsertionPosition.js";const L="@fjall/components-infrastructure";function Pe(r,e,m={}){const s=e.filePath??C,n=W(r,s);if(!n.success)return t(n.error);const a=H(r,{type:e.type,name:e.name},s);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?t(a.error):t({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data!==void 0){if(a.data.managed===!1)return t(X(e.type,a.data.symbolName));const d=$({ast:n.data,target:a.data,resource:{type:e.type,name:e.name},op:"add"});if(d.refusal!==void 0)return t(d.refusal);const h=J([z],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"},baseline:m.baseline,policy:e.driftPolicy});return h.success?h.data.action==="skip"?k({content:r,linesChanged:{added:0,removed:0},skipped:!0}):t({kind:"DuplicateResourceError",type:e.type,name:e.name}):t(R(h.error))}const f=_(n.data),l=N(e.type,e.properties);if("refusal"in l)return t(l.refusal);const y=ae(l.props,f);if(!y.success)return t(y.error);const c=x(n.data);if(c===void 0)return t({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const o=Y[e.type],I=G(o.emitGuard,e.properties);if(I!==void 0)return t(I);const S=K.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"}});if(!S.success)return t(R(S.error));const g={factory:o.factoryIdentifier,name:e.name,properties:y.data,quoteStyle:f};let E;if(o.emitWrapper!==void 0){const d=V(c);if(d===void 0)return t({kind:"MissingAppInitError",type:e.type,appMethod:o.emitWrapper.appMethod});E=B({...g,appIdentifier:d,appMethod:o.emitWrapper.appMethod})}else E=O(g);const p=ee(c,r),i=q(r,s);if(!i.success)return i.error.kind==="TemplateLiteralNameError"?t(i.error):t({kind:"SemanticQueryError",reason:i.error.reason,cause:i.error.cause});const b=Z(p.anchors,i.data),T=re([...p.appInitLocations,...b]),A=ne(p.importInfos,T,e.type,p.programEnd),D=te(p.anchors,A);c.splice(D,0,E),oe(c,o.factoryIdentifier,f);const P=j(n.data,r),F=v(r,P);return k({content:P,linesChanged:F})}u(Pe,"addResource");function R(r){switch(r.kind){case"ParseError":case"TemplateLiteralNameError":case"DuplicateResourceError":case"InvalidPropertyError":case"SemanticQueryError":case"MissingAppInitError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}u(R,"narrowGateError");function oe(r,e,m){for(const n of r){if(n.type!=="ImportDeclaration")continue;const a=n.source;if(!(!w(a)||a.type!=="StringLiteral")&&a.value===L){Q(n,e);return}}const s=U([e],L,m);r.unshift(s)}u(oe,"ensureFactoryImport");export{Pe as addResource};
@@ -1 +1 @@
1
- var T=Object.defineProperty;var d=(r,e)=>T(r,"name",{value:e,configurable:!0});import{failure as i,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as F,computeLinesDelta as L,extractProgramBody as j}from"../_internal.js";import{buildObjectProperty as A,detectQuoteStyle as G,parse as Q,printFile as U}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as P}from"../registry.js";import{locateAllShapes as I,locateByShape as D}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as O}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as V}from"./controlFlowPolicy.js";import{driftGate as B,runPipeline as K,schemaGate as _}from"../validationGate/index.js";import{toAstValue as M}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as b,collectPropertyKeys as $,isNodeShape as S}from"./modifyResource/literalConversion.js";import{findPropertyByKey as H,visit as Y}from"./objectGraph.js";import{evaluateEmitGuard as q,UNRESOLVED as z}from"../emitGuard.js";import{projectEmittedProperties as J,projectionRefusal as W}from"../emitProjection.js";function Ee(r,e,s={}){const n=e.filePath??F,t=Q(r,n);if(!t.success)return i(t.error);const a=D(r,{type:e.type,name:e.name},n);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?i(a.error):i({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data===void 0)return i({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:te(r,e.type,n)});if(a.data.managed===!1)return i(O(e.type,"modify"));const o=V({ast:t.data,target:a.data,resource:{type:e.type,name:e.name},op:"modify"});if(o.refusal!==void 0)return i(o.refusal);const u=K([_,B],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:s.baseline,policy:e.driftPolicy});if(!u.success)return i(X(u.error));if(u.data.action==="skip")return y({content:r,linesChanged:{added:0,removed:0},skipped:!0});const c=j(t.data);if(c===void 0)return i({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=Z(c,a.data);if(f===void 0)return i({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const w=G(t.data),x=b(f,e.properties),C=P[e.type].emitGuard,g=d(l=>q(C,l)??W(e.type,l),"judge"),R=g(v(f,b(f,{}))),p=g(v(f,x));if(p!==void 0&&p.property!==R?.property)return i(p);const E=P[e.type].schemaFragment.safeParse(e.properties);if(!E.success){const l=E.error.issues[0];return i({kind:"InvalidPropertyError",property:l!==void 0&&l.path.length>0?String(l.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:l?.message??"Schema validation failed"})}const m=J(e.type,e.properties,{editingExisting:!0});if("refusal"in m)return i(m.refusal);const h=ee(f,m.props,w);if(!h.success)return i(h.error);const k=U(t.data,r),N=o.warning!==void 0?[o.warning.message]:void 0;return y({content:k,linesChanged:L(r,k),warnings:N})}d(Ee,"modifyResource");function v(r,e){const s={...e};for(const n of $(r))n in s||(s[n]=z);return s}d(v,"buildGuardView");function X(r){switch(r.kind){case"ParseError":case"ResourceNotFoundError":case"InvalidPropertyError":case"TemplateLiteralNameError":case"SemanticQueryError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}d(X,"narrowGateError");function Z(r,e){const s=e.start+e.length;let n;const t=d(a=>{if(n!==void 0||a.type!=="CallExpression")return;const o=a.arguments;if(!Array.isArray(o)||o.length<2)return;const u=o[0];if(!S(u)||u.type!=="StringLiteral"||u.start!==e.start||u.end!==s)return;const c=o[1];S(c)&&c.type==="ObjectExpression"&&(n=c)},"visitor");for(const a of r)if(Y(a,t),n!==void 0)break;return n}d(Z,"findConfigObject");function ee(r,e,s){const n=re(r);for(const{key:t,value:a}of e){const o=M(a,s);if(o===void 0)return i({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (accepts string/number/boolean/null/array/object of the same).`});const u=H(r,t);if(u!==void 0){u.value=o;continue}const c=A(t,o,s);n&&(c.extra={...c.extra??{},trailingComma:!0}),r.properties.push(c)}return y(void 0)}d(ee,"applyPropertyEdits");function re(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}d(re,"detectTrailingCommaStyle");function te(r,e,s){const n=I(r,s);return n.success?n.data.filter(t=>t.type===e).map(t=>t.symbolName):[]}d(te,"collectKnownNames");export{Ee as modifyResource};
1
+ var T=Object.defineProperty;var d=(r,e)=>T(r,"name",{value:e,configurable:!0});import{failure as i,success as m}from"../../types/Result.js";import{DEFAULT_FILE_PATH as L,computeLinesDelta as F,extractProgramBody as j}from"../_internal.js";import{buildObjectProperty as A,detectQuoteStyle as G,parse as Q,printFile as U}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as D}from"../registry.js";import{locateAllShapes as I,locateByShape as O}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as V}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as B}from"./controlFlowPolicy.js";import{driftGate as K,runPipeline as _,schemaGate as M}from"../validationGate/index.js";import{toAstValue as $}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as k,collectPropertyKeys as H,isNodeShape as P}from"./modifyResource/literalConversion.js";import{findPropertyByKey as Y,visit as q}from"./objectGraph.js";import{evaluateEmitGuard as z,UNRESOLVED as J}from"../emitGuard.js";import{projectEmittedProperties as W,projectionRefusal as X}from"../emitProjection.js";function Ee(r,e,s={}){const n=e.filePath??L,t=Q(r,n);if(!t.success)return i(t.error);const a=O(r,{type:e.type,name:e.name},n);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?i(a.error):i({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data===void 0)return i({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:te(r,e.type,n)});if(a.data.managed===!1)return i(V(e.type,"modify"));const o=B({ast:t.data,target:a.data,resource:{type:e.type,name:e.name},op:"modify"});if(o.refusal!==void 0)return i(o.refusal);const u=_([K],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:s.baseline,policy:e.driftPolicy});if(!u.success)return i(v(u.error));if(u.data.action==="skip")return m({content:r,linesChanged:{added:0,removed:0},skipped:!0});const c=j(t.data);if(c===void 0)return i({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=Z(c,a.data);if(f===void 0)return i({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const w=G(t.data),x=k(f,e.properties),C=D[e.type].emitGuard,y=d(b=>z(C,b)??X(e.type,b),"judge"),R=y(S(f,k(f,{}))),l=y(S(f,x));if(l!==void 0&&l.property!==R?.property)return i(l);const g=M.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"}});if(!g.success)return i(v(g.error));const p=W(e.type,e.properties,{editingExisting:!0});if("refusal"in p)return i(p.refusal);const E=ee(f,p.props,w);if(!E.success)return i(E.error);const h=U(t.data,r),N=o.warning!==void 0?[o.warning.message]:void 0;return m({content:h,linesChanged:F(r,h),warnings:N})}d(Ee,"modifyResource");function S(r,e){const s={...e};for(const n of H(r))n in s||(s[n]=J);return s}d(S,"buildGuardView");function v(r){switch(r.kind){case"ParseError":case"ResourceNotFoundError":case"InvalidPropertyError":case"TemplateLiteralNameError":case"SemanticQueryError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}d(v,"narrowGateError");function Z(r,e){const s=e.start+e.length;let n;const t=d(a=>{if(n!==void 0||a.type!=="CallExpression")return;const o=a.arguments;if(!Array.isArray(o)||o.length<2)return;const u=o[0];if(!P(u)||u.type!=="StringLiteral"||u.start!==e.start||u.end!==s)return;const c=o[1];P(c)&&c.type==="ObjectExpression"&&(n=c)},"visitor");for(const a of r)if(q(a,t),n!==void 0)break;return n}d(Z,"findConfigObject");function ee(r,e,s){const n=re(r);for(const{key:t,value:a}of e){const o=$(a,s);if(o===void 0)return i({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (accepts string/number/boolean/null/array/object of the same).`});const u=Y(r,t);if(u!==void 0){u.value=o;continue}const c=A(t,o,s);n&&(c.extra={...c.extra??{},trailingComma:!0}),r.properties.push(c)}return m(void 0)}d(ee,"applyPropertyEdits");function re(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}d(re,"detectTrailingCommaStyle");function te(r,e,s){const n=I(r,s);return n.success?n.data.filter(t=>t.type===e).map(t=>t.symbolName):[]}d(te,"collectKnownNames");export{Ee as modifyResource};
@@ -36,12 +36,11 @@ export interface EmitGuardRule {
36
36
  /**
37
37
  * Standard tail for a refusal with no in-vocabulary alternative.
38
38
  *
39
- * It deliberately does NOT name a construct-prop spelling that would work
40
- * as an unvalidated passthrough (`fjall add` performs no property-key
41
- * validation today, so `--memorySize` or `--originType` reach the emitted
42
- * object untouched). Advertising those would document a surface no schema
43
- * checks and no test pins, and it would go stale the moment the schema gate
44
- * stops being a no-op. Hand-authoring is always correct.
39
+ * It deliberately does NOT name a construct-prop spelling: the schema gate
40
+ * validates property keys against the PLAN schemas, so `--memorySize` or
41
+ * `--originType` are refused as unrecognised keys a construct-vocabulary
42
+ * spelling is not an alternative the operator can reach. Hand-authoring is
43
+ * always correct.
45
44
  */
46
45
  export declare const AUTHOR_BY_HAND: string;
47
46
  /** True when the key holds a value the codemod itself could have written. */
@@ -27,6 +27,27 @@ export interface StatementTypeEntry {
27
27
  locator: StatementLocator;
28
28
  generator: StatementGenerator;
29
29
  schemaFragment: z.ZodObject<z.ZodRawShape>;
30
+ /**
31
+ * The ADD path's required-aware input contract: the plan schema minus
32
+ * `name`, WITHOUT `.partial()`, so a first-time add must carry every
33
+ * required plan key (`database` demands `type` + `databaseName`) as well
34
+ * as satisfying the per-key shapes. `schemaFragment` stays the partial
35
+ * delta contract for MODIFY.
36
+ *
37
+ * Declared ONLY for guard-free types, and that is a rule, not a
38
+ * convenience: a guarded type's required plan keys are exactly the
39
+ * scaffold-consumed keys its own guard REFUSES to write
40
+ * (`compute.needsConnection` is required by the plan schema and
41
+ * `silentlyDropped` by the guard; `cdn.defaultOriginRef` likewise), so
42
+ * demanding them at the gate would be a catch-22 no invocation could
43
+ * satisfy. When an increment lands a type's projection and deletes its
44
+ * guard table, declare `addContract` in the same edit — the schema-gate
45
+ * XOR test pins the pairing.
46
+ *
47
+ * Absent = the schema gate applies `schemaFragment` to adds too
48
+ * (unknown-key and per-key-shape checks only, no required demand).
49
+ */
50
+ addContract?: z.ZodObject<z.ZodRawShape>;
30
51
  /**
31
52
  * When present, the ADD path emits `app.<appMethod>(XFactory.build(...))`
32
53
  * instead of the bare factory call. MANDATORY for any type whose factory
@@ -84,11 +105,12 @@ export interface StatementTypeEntry {
84
105
  * @fjall/components-infrastructure.
85
106
  *
86
107
  * Deliberately NOT covered: INCOMPLETE input, where the vocabulary can
87
- * express a working call and the operator has not yet. That fails loudly
88
- * at synth naming the missing prop and is accepted behaviour — `fjall add
89
- * buildkite` with no flags has always thrown `Buildkite: invalid props`.
90
- * Nor is this general schema validation: unknown keys still pass straight
91
- * through (a separate, recorded gap).
108
+ * express a working call and the operator has not yet that is
109
+ * `addContract`'s territory, refused at write time by the schema gate for
110
+ * guard-free types (`fjall add buildkite` with no flags is now refused
111
+ * naming `buildkiteQueue` + `buildkiteOrgSlug` instead of throwing
112
+ * `Buildkite: invalid props` at synth). Nor is this general schema
113
+ * validation: unknown keys and mistyped values are the schema gate's job.
92
114
  *
93
115
  * Absent = every expressible property shape for this type reaches a
94
116
  * synthesising statement. That is a claim, not an oversight, and it is now
@@ -1 +1 @@
1
- var C=Object.defineProperty;var n=(e,t)=>C(e,"name",{value:t,configurable:!0});import{z as d}from"zod";import{BuildkitePropsObjectSchema as v,CDNResourcePlanSchema as R,ComputeResourcePlanSchema as k,CrossPlanConnectionResourcePlanSchema as T,DatabaseResourcePlanSchema as A,NetworkResourcePlanSchema as E,NextJSPatternConfigSchema as w,OrganisationResourcePlanSchema as F,PayloadPatternConfigSchema as N,S3ResourcePlanSchema as M,SQSResourcePlanSchema as D,StaticSitePatternConfigSchema as _,VpcPeerAccepterResourcePlanSchema as x,VpcPeerResourcePlanSchema as O}from"../schemas/index.js";import{failure as W}from"../types/Result.js";import{isRecord as G}from"./_internal.js";import{AUTHOR_BY_HAND as c,requiresLiveValue as g,silentlyDropped as a,UNRESOLVED as m,whenAbsent as p}from"./emitGuard.js";const r={database:"DatabaseFactory",storage:"StorageFactory",compute:"ComputeFactory",messaging:"MessagingFactory",cdn:"CdnFactory",network:"NetworkFactory",pattern:"PatternFactory","vpc-peer":"VpcPeerFactory","vpc-peer-accepter":"VpcPeerAccepterFactory","cross-plan-connection":"CrossPlanConnectionFactory",organisation:"OrganisationFactory",buildkite:"BuildkiteFactory"};function s(e){const{name:t,...i}=e.shape;return d.object(i).partial().strict()}n(s,"fragmentOf");const I=s(A),B=s(M),j=(()=>{const{name:e,...t}=k.shape;return d.object(t).partial().strict()})(),L=s(D),V=s(R),Y=s(E),q=(()=>{const{name:e,type:t,cdn:i,...f}=N.shape,{name:ae,type:re,cdn:oe,...b}=w.shape,{name:se,type:ie,domain:ce,cdn:S,...P}=_.shape;return d.object({...f,...b,...P,cdn:d.union([i,S])}).partial().strict()})(),K=s(O),U=s(x),z=s(T),H=s(F),Q=s(v);function l(e,t){return W({kind:"SemanticQueryError",reason:`StatementTypeEntry.${e} for ${t} is not wired; existing types dispatch through the shared locator/generator.`})}n(l,"notWiredError");function $(e){return{factoryIdentifier:e,findByShape:n(()=>l("locator.findByShape",e),"findByShape"),validateContext:n(()=>l("locator.validateContext",e),"validateContext")}}n($,"createLocator");function J(e){return{build:n(()=>{const t=l("generator.build",e);throw new Error(t.success?"unreachable":t.error.reason)},"build")}}n(J,"createGenerator");const X=a("variableName","`variableName` is a plan-only round-trip key naming the `const <var> =` binding the scaffold emits; no construct reads it."),y=a("extraProperties","`extraProperties` is a plan-only round-trip key: the scaffold flattens each `{ key, sourceText }` entry into a sibling property, and no construct reads the array."),u="the connection keys are scaffold inputs, not construct props: the scaffold expands them into environment variables and a `connections: [...]` array, and the compute constructs read none of them.",Z=[{property:"deployment",refuseWhen:n(e=>(e.type==="lambda"||e.deployment!==void 0)&&e.deployment!=="container"&&e.code!==m,"refuseWhen"),reason:"a code-deployed Lambda requires `code: Code`, a CDK object built by `Code.fromAsset(...)` that no flag value can carry, so the statement takes the whole app's synth down with `Cannot read properties of undefined (reading 'bind')` \u2014 naming no resource. Use `--deployment container`, which is fully expressible, or write this compute in infrastructure.ts by hand."},a("codePath","`codePath` is the scaffold's input to `Code.fromAsset(...)`; no compute construct reads it, and a container Lambda takes its code from the image."),g("runtime","the construct expects a CDK `Runtime`, not a version string, and a container Lambda takes its runtime from the image (`Runtime.FROM_IMAGE`) regardless."),g("architecture","the construct expects a CDK `Architecture`, not a string: `--architecture ARM_64` emits an EMPTY `Architectures` list, whereas omitting the flag emits the correct default."),a("memory","the Lambda construct reads `memorySize`, so `--memory 1024` deploys a function at the 128 MB default."),a("ssmSecrets","the Lambda construct reads `secrets`, so `--ssmSecrets` deploys a function with no SSM wiring and no secrets environment at all."),a("scheduleExpression","`scheduleExpression` is not a compute prop: the scaffold turns it into a SEPARATE `app.addSchedule(...)` statement, which this command cannot emit."),a("needsConnection",u),a("connectedDatabase",u),a("connectedStorage",u),a("connectedMessaging",u),X,y],ee=[{property:"originType",refuseWhen:p("originType"),reason:"`Cdn` selects its origin implementation from an `originType` discriminator that the CDN vocabulary does not carry, so a distribution built from CDN properties throws `Unsupported CDN origin type: undefined` the moment `app.addCdn` materialises it. "+c},{property:"originType",refuseWhen:n(e=>e.originType==="s3"&&e.bucket!==m,"refuseWhen"),reason:"an s3 origin needs `bucket` to be an `IBucket` or a Fjall `Storage` \u2014 a live construct, not a name, and not a string; omitting it throws `Cannot read properties of undefined (reading 'bucketRegionalDomainName')` at synth. "+c},{property:"originType",refuseWhen:n(e=>e.originType==="alb"&&e.loadBalancer!==m,"refuseWhen"),reason:'an alb origin needs `loadBalancer` to be an `IApplicationLoadBalancer` or an ECS compute \u2014 a live construct, not a name, and not a string; a string reaches CloudFormation as `Supplied properties not correct for "OriginProperty"`. '+c},{property:"behaviours",refuseWhen:n(e=>Array.isArray(e.behaviours)&&e.behaviours.some(t=>G(t)&&t.originRef!==void 0),"refuseWhen"),reason:"the plan's `behaviours[].originRef` names another planned resource, while the construct's behaviour takes a live origin object; the plan shape throws `Cannot read properties of undefined (reading 'computeType')` at synth. "+c},a("customDomain","the distribution reads `domainNames`, so `--customDomain` deploys a distribution with no alias."),a("defaultOriginRef","`defaultOriginRef` names another planned resource for the scaffold to resolve into a live origin; no CDN construct reads it."),y],te=[{property:"name",refuseWhen:p("name"),reason:"every pattern construct requires a `name` PROPERTY in addition to its construct id, and `fjall add --name` binds the construct id, so no invocation can deliver it \u2014 `toPascalCase(props.name)` throws at synth and takes the whole app down. "+c},{property:"type",refuseWhen:p("type"),reason:"`PatternFactory.build` reads `PATTERN_REGISTRY[props.type]` before it even returns the thunk, and the pattern vocabulary carries no `type` discriminator. "+c}],ne=[{property:"peerAppName",refuseWhen:p("peerAppName"),reason:"`peerAppName` is required: it is the SSM prefix every remote lookup is built from, and omitting it does NOT fail \u2014 synth succeeds and the app deploys a peering connection pointed at `/fjall/default/undefined/vpc-id`. Pass `--peerAppName <remote app>`."},{property:"peerAccountId",refuseWhen:p("peerAccountId"),reason:"`peerAccountId` is required: omitting it does NOT fail, it deploys a VPC peering connection with no `PeerOwnerId`. Pass `--peerAccountId <12-digit account>`."}];function o(e,t,i={}){return{factoryIdentifier:e,locator:$(e),generator:J(e),schemaFragment:t,...i}}n(o,"createEntry");const h={database:o(r.database,I,{emitWrapper:{appMethod:"addDatabase"}}),storage:o(r.storage,B,{emitWrapper:{appMethod:"addStorage"}}),compute:o(r.compute,j,{emitWrapper:{appMethod:"addCompute"},emitGuard:Z}),messaging:o(r.messaging,L,{emitWrapper:{appMethod:"addMessaging"}}),cdn:o(r.cdn,V,{emitWrapper:{appMethod:"addCdn"},emitGuard:ee}),network:o(r.network,Y,{emitWrapper:{appMethod:"addNetwork"}}),pattern:o(r.pattern,q,{emitWrapper:{appMethod:"addPattern"},emitGuard:te}),"vpc-peer":o(r["vpc-peer"],K,{emitWrapper:{appMethod:"addVpcPeer"},emitGuard:ne}),"vpc-peer-accepter":o(r["vpc-peer-accepter"],U,{emitWrapper:{appMethod:"addVpcPeerAccepter"}}),"cross-plan-connection":o(r["cross-plan-connection"],z),organisation:o(r.organisation,H),buildkite:o(r.buildkite,Q,{emitWrapper:{appMethod:"addBuildkite",propsOverloadConstructId:"Buildkite"}})},ge=Object.keys(h);function ye(e){const t=Object.keys(h);for(const i of t)if(h[i].factoryIdentifier===e)return i}n(ye,"findTypeByIdentifier");export{r as FACTORY_IDENTIFIERS,ge as REGISTERED_STATEMENT_TYPES,h as STATEMENT_REGISTRY,ye as findTypeByIdentifier};
1
+ var N=Object.defineProperty;var a=(e,t)=>N(e,"name",{value:t,configurable:!0});import{z as p}from"zod";import{BuildkitePropsObjectSchema as y,CDNResourcePlanSchema as M,ComputeResourcePlanSchema as _,CrossPlanConnectionResourcePlanSchema as f,DatabaseResourcePlanSchema as b,NetworkResourcePlanSchema as C,NextJSPatternConfigSchema as D,OrganisationResourcePlanSchema as S,PayloadPatternConfigSchema as O,S3ResourcePlanSchema as P,SQSResourcePlanSchema as v,StaticSitePatternConfigSchema as x,VpcPeerAccepterResourcePlanSchema as R,VpcPeerResourcePlanSchema as W}from"../schemas/index.js";import{failure as G}from"../types/Result.js";import{isRecord as I}from"./_internal.js";import{AUTHOR_BY_HAND as d,requiresLiveValue as k,silentlyDropped as n,UNRESOLVED as l,whenAbsent as u}from"./emitGuard.js";const r={database:"DatabaseFactory",storage:"StorageFactory",compute:"ComputeFactory",messaging:"MessagingFactory",cdn:"CdnFactory",network:"NetworkFactory",pattern:"PatternFactory","vpc-peer":"VpcPeerFactory","vpc-peer-accepter":"VpcPeerAccepterFactory","cross-plan-connection":"CrossPlanConnectionFactory",organisation:"OrganisationFactory",buildkite:"BuildkiteFactory"};function i(e){const{name:t,...s}=e.shape;return p.object(s).partial().strict()}a(i,"fragmentOf");function c(e){const{name:t,...s}=e.shape;return p.object(s).strict()}a(c,"completeFragmentOf");const j=i(b),B=i(P),L=(()=>{const{name:e,...t}=_.shape;return p.object(t).partial().strict()})(),V=i(v),Y=i(M),q=i(C),K=(()=>{const{name:e,type:t,cdn:s,...A}=O.shape,{name:re,type:oe,cdn:se,...E}=D.shape,{name:ie,type:ce,domain:de,cdn:F,...w}=x.shape;return p.object({...A,...E,...w,cdn:p.union([s,F])}).partial().strict()})(),U=i(W),z=i(R),H=i(f),Q=i(S),$=i(y);function h(e,t){return G({kind:"SemanticQueryError",reason:`StatementTypeEntry.${e} for ${t} is not wired; existing types dispatch through the shared locator/generator.`})}a(h,"notWiredError");function J(e){return{factoryIdentifier:e,findByShape:a(()=>h("locator.findByShape",e),"findByShape"),validateContext:a(()=>h("locator.validateContext",e),"validateContext")}}a(J,"createLocator");function X(e){return{build:a(()=>{const t=h("generator.build",e);throw new Error(t.success?"unreachable":t.error.reason)},"build")}}a(X,"createGenerator");const Z=n("variableName","`variableName` is a plan-only round-trip key naming the `const <var> =` binding the scaffold emits; no construct reads it."),T=n("extraProperties","`extraProperties` is a plan-only round-trip key: the scaffold flattens each `{ key, sourceText }` entry into a sibling property, and no construct reads the array."),m="the connection keys are scaffold inputs, not construct props: the scaffold expands them into environment variables and a `connections: [...]` array, and the compute constructs read none of them.",ee=[{property:"deployment",refuseWhen:a(e=>(e.type==="lambda"||e.deployment!==void 0)&&e.deployment!=="container"&&e.code!==l,"refuseWhen"),reason:"a code-deployed Lambda requires `code: Code`, a CDK object built by `Code.fromAsset(...)` that no flag value can carry, so the statement takes the whole app's synth down with `Cannot read properties of undefined (reading 'bind')` \u2014 naming no resource. Use `--deployment container`, which is fully expressible, or write this compute in infrastructure.ts by hand."},n("codePath","`codePath` is the scaffold's input to `Code.fromAsset(...)`; no compute construct reads it, and a container Lambda takes its code from the image."),k("runtime","the construct expects a CDK `Runtime`, not a version string, and a container Lambda takes its runtime from the image (`Runtime.FROM_IMAGE`) regardless."),k("architecture","the construct expects a CDK `Architecture`, not a string: `--architecture ARM_64` emits an EMPTY `Architectures` list, whereas omitting the flag emits the correct default."),n("memory","the Lambda construct reads `memorySize`, so `--memory 1024` deploys a function at the 128 MB default."),n("ssmSecrets","the Lambda construct reads `secrets`, so `--ssmSecrets` deploys a function with no SSM wiring and no secrets environment at all."),n("scheduleExpression","`scheduleExpression` is not a compute prop: the scaffold turns it into a SEPARATE `app.addSchedule(...)` statement, which this command cannot emit."),n("needsConnection",m),n("connectedDatabase",m),n("connectedStorage",m),n("connectedMessaging",m),Z,T],te=[{property:"originType",refuseWhen:u("originType"),reason:"`Cdn` selects its origin implementation from an `originType` discriminator that the CDN vocabulary does not carry, so a distribution built from CDN properties throws `Unsupported CDN origin type: undefined` the moment `app.addCdn` materialises it. "+d},{property:"originType",refuseWhen:a(e=>e.originType==="s3"&&e.bucket!==l,"refuseWhen"),reason:"an s3 origin needs `bucket` to be an `IBucket` or a Fjall `Storage` \u2014 a live construct, not a name, and not a string; omitting it throws `Cannot read properties of undefined (reading 'bucketRegionalDomainName')` at synth. "+d},{property:"originType",refuseWhen:a(e=>e.originType==="alb"&&e.loadBalancer!==l,"refuseWhen"),reason:'an alb origin needs `loadBalancer` to be an `IApplicationLoadBalancer` or an ECS compute \u2014 a live construct, not a name, and not a string; a string reaches CloudFormation as `Supplied properties not correct for "OriginProperty"`. '+d},{property:"behaviours",refuseWhen:a(e=>Array.isArray(e.behaviours)&&e.behaviours.some(t=>I(t)&&t.originRef!==void 0),"refuseWhen"),reason:"the plan's `behaviours[].originRef` names another planned resource, while the construct's behaviour takes a live origin object; the plan shape throws `Cannot read properties of undefined (reading 'computeType')` at synth. "+d},n("customDomain","the distribution reads `domainNames`, so `--customDomain` deploys a distribution with no alias."),n("defaultOriginRef","`defaultOriginRef` names another planned resource for the scaffold to resolve into a live origin; no CDN construct reads it."),T],ae=[{property:"name",refuseWhen:u("name"),reason:"every pattern construct requires a `name` PROPERTY in addition to its construct id, and `fjall add --name` binds the construct id, so no invocation can deliver it \u2014 `toPascalCase(props.name)` throws at synth and takes the whole app down. "+d},{property:"type",refuseWhen:u("type"),reason:"`PatternFactory.build` reads `PATTERN_REGISTRY[props.type]` before it even returns the thunk, and the pattern vocabulary carries no `type` discriminator. "+d}],ne=[{property:"peerAppName",refuseWhen:u("peerAppName"),reason:"`peerAppName` is required: it is the SSM prefix every remote lookup is built from, and omitting it does NOT fail \u2014 synth succeeds and the app deploys a peering connection pointed at `/fjall/default/undefined/vpc-id`. Pass `--peerAppName <remote app>`."},{property:"peerAccountId",refuseWhen:u("peerAccountId"),reason:"`peerAccountId` is required: omitting it does NOT fail, it deploys a VPC peering connection with no `PeerOwnerId`. Pass `--peerAccountId <12-digit account>`."}];function o(e,t,s={}){return{factoryIdentifier:e,locator:J(e),generator:X(e),schemaFragment:t,...s}}a(o,"createEntry");const g={database:o(r.database,j,{emitWrapper:{appMethod:"addDatabase"},addContract:c(b)}),storage:o(r.storage,B,{emitWrapper:{appMethod:"addStorage"},addContract:c(P)}),compute:o(r.compute,L,{emitWrapper:{appMethod:"addCompute"},emitGuard:ee}),messaging:o(r.messaging,V,{emitWrapper:{appMethod:"addMessaging"},addContract:c(v)}),cdn:o(r.cdn,Y,{emitWrapper:{appMethod:"addCdn"},emitGuard:te}),network:o(r.network,q,{emitWrapper:{appMethod:"addNetwork"},addContract:c(C)}),pattern:o(r.pattern,K,{emitWrapper:{appMethod:"addPattern"},emitGuard:ae}),"vpc-peer":o(r["vpc-peer"],U,{emitWrapper:{appMethod:"addVpcPeer"},emitGuard:ne}),"vpc-peer-accepter":o(r["vpc-peer-accepter"],z,{emitWrapper:{appMethod:"addVpcPeerAccepter"},addContract:c(R)}),"cross-plan-connection":o(r["cross-plan-connection"],H,{addContract:c(f)}),organisation:o(r.organisation,Q,{addContract:c(S)}),buildkite:o(r.buildkite,$,{emitWrapper:{appMethod:"addBuildkite",propsOverloadConstructId:"Buildkite"},addContract:c(y)})},ye=Object.keys(g);function fe(e){const t=Object.keys(g);for(const s of t)if(g[s].factoryIdentifier===e)return s}a(fe,"findTypeByIdentifier");export{r as FACTORY_IDENTIFIERS,ye as REGISTERED_STATEMENT_TYPES,g as STATEMENT_REGISTRY,fe as findTypeByIdentifier};
@@ -1 +1 @@
1
- import{success as c}from"../../../types/Result.js";const t={id:"schema",run(e){return c({action:"proceed"})}};export{t as schemaGate};
1
+ var a=Object.defineProperty;var s=(e,r)=>a(e,"name",{value:r,configurable:!0});import{failure as p,success as c}from"../../../types/Result.js";import{STATEMENT_REGISTRY as d}from"../../registry.js";const h={id:"schema",run(e){const r=d[e.plan.type],n=(e.plan.op==="add"?r.addContract??r.schemaFragment:r.schemaFragment).safeParse(e.plan.properties);return n.success?c({action:"proceed"}):p(u(e,n.error))}};function u(e,r){const t=f(e,r);if(t.length>0){const o=t.map(i=>`\`${i}\``).join(", ");return{kind:"InvalidPropertyError",property:t[0]??"<unknown>",reason:`required for a new ${e.plan.type} and not provided (missing: ${o}). Nothing has been written.`}}const n=r.issues[0];if(n!==void 0&&n.code==="unrecognized_keys"){const o=n.keys.map(i=>`\`${i}\``).join(", ");return{kind:"InvalidPropertyError",property:n.keys[0]??"<unknown>",reason:`not a ${e.plan.type} property (unrecognised: ${o}). Nothing has been written.`}}return{kind:"InvalidPropertyError",property:n!==void 0&&n.path.length>0?String(n.path[0]):Object.keys(e.plan.properties)[0]??"<unknown>",reason:n?.message??"Schema validation failed"}}s(u,"toInvalidPropertyError");function f(e,r){const t=[];for(const n of r.issues){if(n.path.length!==1)continue;const o=n.path[0];typeof o=="string"&&(o in e.plan.properties||t.includes(o)||t.push(o))}return t}s(f,"missingRequiredKeys");export{h as schemaGate};
@@ -1,12 +1,12 @@
1
- var O=Object.defineProperty;var u=(e,n)=>O(e,"name",{value:n,configurable:!0});import{formatValue as $,emitExtraProperties as E,escapeStringLiteral as o,formatStringArray as k,emitProductionAlertsTopicSpread as R}from"../common.js";import{DATABASE_ENV_VARS as y,getConnectedDatabases as D,buildDatabaseEnvVars as N}from"../database.js";import{STORAGE_ENV_VARS as B,getConnectedStorage as j,buildStorageEnvVars as L,formatAllConnectionsCode as _}from"../storageConnections.js";import{MESSAGING_ENV_VARS as C,getConnectedMessaging as H,buildMessagingEnvVars as w}from"../messagingConnections.js";import{BASE_ENVIRONMENT_VARS as I,computeHasConnections as G,computeHasDatabaseConnections as P,computeHasMessagingConnections as M,computeHasStorageConnections as V,formatCompactOrExpandedObject as v,formatEnvBlock as x}from"./shared.js";function J(e){const n=[];if(e.instanceType!==void 0&&n.push(`instanceType: ${o(e.instanceType)}`),e.amiHardwareType!==void 0&&n.push(`amiHardwareType: ${o(e.amiHardwareType)}`),e.minCapacity!==void 0&&n.push(`minCapacity: ${e.minCapacity}`),e.maxCapacity!==void 0&&n.push(`maxCapacity: ${e.maxCapacity}`),e.memoryLimitMiB!==void 0&&n.push(`memoryLimitMiB: ${e.memoryLimitMiB}`),e.warmPool!==void 0&&n.push(`warmPool: ${$(e.warmPool," ")}`),e.extraProperties?.length)for(const t of e.extraProperties)n.push(`${t.key}: ${t.sourceText}`);return`
2
- ec2Config: ${v(n," "," ")},`}u(J,"generateEcsServiceEc2ConfigCode");function K(e){if(!e.cluster)return"";const n=[];if(e.cluster.directAccess&&n.push("directAccess: true"),e.cluster.domain&&n.push(`domain: ${o(e.cluster.domain)}`),e.cluster.loadBalancer!==void 0&&n.push(e.cluster.loadBalancer===!1?"loadBalancer: false":`loadBalancer: ${o(e.cluster.loadBalancer)}`),e.cluster.extraProperties?.length)for(const t of e.cluster.extraProperties)n.push(`${t.key}: ${t.sourceText}`);return`
3
- cluster: ${v(n," "," ")},`}u(K,"generateEcsClusterCode");function U(e,n,t,l,h,p){let i="";e.name&&(i+=`
1
+ var O=Object.defineProperty;var u=(e,n)=>O(e,"name",{value:n,configurable:!0});import{formatValue as S,emitExtraProperties as E,escapeStringLiteral as o,formatStringArray as k,emitProductionAlertsTopicSpread as R}from"../common.js";import{DATABASE_ENV_VARS as y,getConnectedDatabases as D,buildDatabaseEnvVars as N}from"../database.js";import{STORAGE_ENV_VARS as B,getConnectedStorage as j,buildStorageEnvVars as L,formatAllConnectionsCode as _}from"../storageConnections.js";import{MESSAGING_ENV_VARS as C,getConnectedMessaging as H,buildMessagingEnvVars as w}from"../messagingConnections.js";import{BASE_ENVIRONMENT_VARS as I,computeHasConnections as G,computeHasDatabaseConnections as P,computeHasMessagingConnections as M,computeHasStorageConnections as V,formatCompactOrExpandedObject as $,formatEnvBlock as x}from"./shared.js";function J(e){const n=[];if(e.instanceType!==void 0&&n.push(`instanceType: ${o(e.instanceType)}`),e.amiHardwareType!==void 0&&n.push(`amiHardwareType: ${o(e.amiHardwareType)}`),e.minCapacity!==void 0&&n.push(`minCapacity: ${e.minCapacity}`),e.maxCapacity!==void 0&&n.push(`maxCapacity: ${e.maxCapacity}`),e.memoryLimitMiB!==void 0&&n.push(`memoryLimitMiB: ${e.memoryLimitMiB}`),e.warmPool!==void 0&&n.push(`warmPool: ${S(e.warmPool," ")}`),e.extraProperties?.length)for(const t of e.extraProperties)n.push(`${t.key}: ${t.sourceText}`);return`
2
+ ec2Config: ${$(n," "," ")},`}u(J,"generateEcsServiceEc2ConfigCode");function K(e){if(!e.cluster)return"";const n=[];if(e.cluster.directAccess&&n.push("directAccess: true"),e.cluster.domain&&n.push(`domain: ${o(e.cluster.domain)}`),e.cluster.loadBalancer!==void 0&&n.push(e.cluster.loadBalancer===!1?"loadBalancer: false":`loadBalancer: ${o(e.cluster.loadBalancer)}`),e.cluster.extraProperties?.length)for(const t of e.cluster.extraProperties)n.push(`${t.key}: ${t.sourceText}`);return`
3
+ cluster: ${$(n," "," ")},`}u(K,"generateEcsClusterCode");function U(e,n,t,l,p,h){let i="";e.name&&(i+=`
4
4
  name: ${o(e.name)},`),e.image&&(i+=`
5
5
  image: ${o(e.image)},`),e.port!==void 0&&(i+=`
6
6
  port: ${e.port},`),e.essential!==void 0&&(i+=`
7
7
  essential: ${e.essential},`),e.command?.length&&(i+=`
8
8
  command: ${JSON.stringify(e.command)},`),e.entryPoint?.length&&(i+=`
9
- entryPoint: ${JSON.stringify(e.entryPoint)},`);const c=[y.HOST,y.PORT,y.NAME,y.SSL,y.USERNAME,y.PASSWORD,B.NAME,C.URL,C.ARN],r=u(a=>{if(!a)return a;const d={};for(const[m,g]of Object.entries(a))c.some(S=>m===S||m.startsWith(`${S}_`))||(d[m]=g);return Object.keys(d).length>0?d:void 0},"stripConnectionEnv"),f=n?{...p,...t.env,...l.env,...h.env,...e.environment}:{...p,...r(e.environment)},s=n?{...t.secrets,...e.secretsImport}:r(e.secretsImport);return f&&Object.keys(f).length>0&&(i+=`
9
+ entryPoint: ${JSON.stringify(e.entryPoint)},`);const c=[y.HOST,y.PORT,y.NAME,y.SSL,y.USERNAME,y.PASSWORD,B.NAME,C.URL,C.ARN],r=u(a=>{if(!a)return a;const d={};for(const[m,g]of Object.entries(a))c.some(v=>m===v||m.startsWith(`${v}_`))||(d[m]=g);return Object.keys(d).length>0?d:void 0},"stripConnectionEnv"),f=n?{...h,...t.env,...l.env,...p.env,...e.environment}:{...h,...r(e.environment)},s=n?{...t.secrets,...e.secretsImport}:r(e.secretsImport);return f&&Object.keys(f).length>0&&(i+=`
10
10
  environment: {
11
11
  ${x(f," ")}
12
12
  },`),s&&Object.keys(s).length>0&&(i+=`
@@ -14,29 +14,30 @@ ${x(f," ")}
14
14
  ${x(s," ")}
15
15
  },`),e.ssmSecrets&&e.ssmSecrets.length>0&&(i+=`
16
16
  secrets: [${k(e.ssmSecrets)}],`),e.healthCheck&&(i+=`
17
- healthCheck: ${$(e.healthCheck," ")},`),i+=E(e.extraProperties," "),i}u(U,"generateEcsContainerCode");function A(e,n){const t=[];return e.path&&t.push(`path: ${o(e.path)}`),e.host&&t.push(`host: ${o(e.host)}`),e.priority!==void 0&&t.push(`priority: ${e.priority}`),e.healthCheckPath&&t.push(`healthCheckPath: ${o(e.healthCheckPath)}`),v(t,n,`${n} `)}u(A,"formatRoutingRule");function W(e){const n=Array.isArray(e)?e:[e];return n.length===1?`
17
+ healthCheck: ${S(e.healthCheck," ")},`),i+=E(e.extraProperties," "),i}u(U,"generateEcsContainerCode");function A(e,n){const t=[];return e.path&&t.push(`path: ${o(e.path)}`),e.host&&t.push(`host: ${o(e.host)}`),e.priority!==void 0&&t.push(`priority: ${e.priority}`),e.healthCheckPath&&t.push(`healthCheckPath: ${o(e.healthCheckPath)}`),$(t,n,`${n} `)}u(A,"formatRoutingRule");function W(e){const n=Array.isArray(e)?e:[e];return n.length===1?`
18
18
  routing: ${A(n[0]," ")},`:`
19
19
  routing: [
20
20
  ${n.map(l=>A(l," ")).join(`,
21
21
  `)},
22
22
  ],`}u(W,"generateEcsServiceRoutingCode");function q(e){if(e===!1)return`
23
23
  scaling: false,`;if(typeof e!="object"||!(e.minCapacity!==void 0||e.maxCapacity!==void 0||e.desiredCount!==void 0||e.scalingType!==void 0))return"";const t=[];return e.minCapacity!==void 0&&t.push(`minCapacity: ${e.minCapacity}`),e.maxCapacity!==void 0&&t.push(`maxCapacity: ${e.maxCapacity}`),e.desiredCount!==void 0&&t.push(`desiredCount: ${e.desiredCount}`),e.scalingType&&t.push(`scalingType: ${o(e.scalingType)}`),`
24
- scaling: ${v(t," "," ")},`}u(q,"generateEcsServiceScalingCode");function z(e,n,t){return{needsDb:e.needsDatabaseConnection!==void 0?e.needsDatabaseConnection:n&&P(t),needsStorage:e.needsStorageConnection!==void 0?e.needsStorageConnection:n&&V(t),needsMessaging:e.needsMessagingConnection!==void 0?e.needsMessagingConnection:n&&M(t)}}u(z,"deriveServiceConnectionNeeds");function F(e){const{service:n,isFirstService:t,hasConnections:l,dbEnvVars:h,storageEnvVars:p,messagingEnvVars:i,baseEnvVars:c,plan:r,compute:f}=e;let s=`
24
+ scaling: ${$(t," "," ")},`}u(q,"generateEcsServiceScalingCode");function z(e,n,t){return{needsDb:e.needsDatabaseConnection!==void 0?e.needsDatabaseConnection:n&&P(t),needsStorage:e.needsStorageConnection!==void 0?e.needsStorageConnection:n&&V(t),needsMessaging:e.needsMessagingConnection!==void 0?e.needsMessagingConnection:n&&M(t)}}u(z,"deriveServiceConnectionNeeds");function F(e){const{service:n,isFirstService:t,hasConnections:l,dbEnvVars:p,storageEnvVars:h,messagingEnvVars:i,baseEnvVars:c,plan:r,compute:f}=e;let s=`
25
25
  name: ${o(n.name)},`;s+=`
26
- capacityProvider: ${o(n.capacityProvider)},`,n.ec2Config&&(s+=J(n.ec2Config)),n.docker&&(s+=`
27
- docker: ${$(n.docker," ")},`),n.image&&(s+=`
26
+ capacityProvider: ${o(n.capacityProvider)},`,n.serviceType!==void 0&&(s+=`
27
+ serviceType: ${o(n.serviceType)},`),n.ec2Config&&(s+=J(n.ec2Config)),n.docker&&(s+=`
28
+ docker: ${S(n.docker," ")},`),n.image&&(s+=`
28
29
  image: ${o(n.image)},`),n.ssmSecretsPath&&(s+=`
29
30
  ssmSecretsPath: ${o(n.ssmSecretsPath)},`);const a=z(n,t,f);if(n.containers?.length){s+=`
30
- containers: [{`;for(let d=0;d<n.containers.length;d++){const m=n.containers[d];if(!m)continue;const g=d===0&&(a.needsDb||a.needsStorage||a.needsMessaging)&&l,b=a.needsDb?h:{env:{},secrets:{}},S=a.needsStorage?p:{env:{},secrets:{}},T=a.needsMessaging?i:{env:{},secrets:{}};d>0&&(s+=`
31
- }, {`),s+=U(m,g,b,S,T,c)}s+=`
31
+ containers: [{`;for(let d=0;d<n.containers.length;d++){const m=n.containers[d];if(!m)continue;const g=d===0&&(a.needsDb||a.needsStorage||a.needsMessaging)&&l,b=a.needsDb?p:{env:{},secrets:{}},v=a.needsStorage?h:{env:{},secrets:{}},T=a.needsMessaging?i:{env:{},secrets:{}};d>0&&(s+=`
32
+ }, {`),s+=U(m,g,b,v,T,c)}s+=`
32
33
  }],`}if(n.routing&&(s+=W(n.routing)),n.cpu!==void 0&&(s+=`
33
34
  cpu: ${n.cpu},`),n.memoryLimitMiB!==void 0&&(s+=`
34
35
  memoryLimitMiB: ${n.memoryLimitMiB},`),n.desiredCount!==void 0&&(s+=`
35
36
  desiredCount: ${n.desiredCount},`),n.scaling!==void 0&&(s+=q(n.scaling)),n.alarms===!1?s+=`
36
37
  alarms: false,`:typeof n.alarms=="object"&&(s+=`
37
- alarms: ${$(n.alarms," ")},`),s+=E(n.extraProperties," "),a.needsDb||a.needsStorage||a.needsMessaging){const d=a.needsDb?D(r,f):[],m=a.needsStorage?j(r,f):[],g=a.needsMessaging?H(r,f):[];(d.length>0||m.length>0||g.length>0)&&(s+=`
38
- ${_(d,m,g)}`)}return s}u(F,"generateEcsServiceCode");function te(e,n){const t=G(e),l={...I},h={env:{},secrets:{}};if(P(e)){const r=N(n,e);Object.assign(h.env,r.env),Object.assign(h.secrets,r.secrets)}const p={env:{},secrets:{}};if(V(e)){const r=L(n,e);Object.assign(p.env,r.env)}const i={env:{},secrets:{}};if(M(e)){const r=w(n,e);Object.assign(i.env,r.env)}let c=`
38
+ alarms: ${S(n.alarms," ")},`),s+=E(n.extraProperties," "),a.needsDb||a.needsStorage||a.needsMessaging){const d=a.needsDb?D(r,f):[],m=a.needsStorage?j(r,f):[],g=a.needsMessaging?H(r,f):[];(d.length>0||m.length>0||g.length>0)&&(s+=`
39
+ ${_(d,m,g)}`)}return s}u(F,"generateEcsServiceCode");function te(e,n){const t=G(e),l={...I},p={env:{},secrets:{}};if(P(e)){const r=N(n,e);Object.assign(p.env,r.env),Object.assign(p.secrets,r.secrets)}const h={env:{},secrets:{}};if(V(e)){const r=L(n,e);Object.assign(h.env,r.env)}const i={env:{},secrets:{}};if(M(e)){const r=w(n,e);Object.assign(i.env,r.env)}let c=`
39
40
  ecrRepository: app.getDefaultContainerRegistry(),`;if(c+=K(e),e.services?.length){c+=`
40
41
  services: [{`;for(let r=0;r<e.services.length;r++){const f=e.services[r];f&&(r>0&&(c+=`
41
- }, {`),c+=F({service:f,isFirstService:r===0,hasConnections:t,dbEnvVars:h,storageEnvVars:p,messagingEnvVars:i,baseEnvVars:l,plan:n,compute:e}))}c+=`
42
+ }, {`),c+=F({service:f,isFirstService:r===0,hasConnections:t,dbEnvVars:p,storageEnvVars:h,messagingEnvVars:i,baseEnvVars:l,plan:n,compute:e}))}c+=`
42
43
  }],`}return c+=E(e.extraProperties),c+=R(),c}u(te,"generateEcsCode");export{te as generateEcsCode};
@@ -1 +1 @@
1
- var b=Object.defineProperty;var i=(e,n)=>b(e,"name",{value:n,configurable:!0});import{TIER_PRESETS as l,getDefaultDatabaseTypeForTier as P,applyTierDefaultsToServices as k}from"../presets/tierPresets.js";import{COMPUTE_TYPE as D,DEFAULT_CONTAINER_PORT as T}from"../schemas/constants.js";import{success as f,failure as h}from"../types/Result.js";import{injectCustomCodeBlocks as p}from"../ast/mutation/astCodeInjection.js";import{toVariableName as m,toValidDatabaseName as v,generateImports as S,generateAppInit as E,generateTags as R,generateNetworkCode as C,generateDatabaseCode as y,generateClickHouseCode as I,generateS3Code as w,generateDynamoDBCode as x,generateSQSCode as A,generateComputeCode as B,generateCDNCode as U,collectCdnReferencedResources as j,usesPatternApproach as F,generatePatternCodeWithComments as _}from"../generation/index.js";function J(e){return e?.map(n=>({name:n.name,...n.serviceType!==void 0&&{serviceType:n.serviceType},...n.docker!==void 0&&{docker:n.docker},...n.containerPort!==void 0&&{containerPort:n.containerPort},...n.needsDatabaseConnection!==void 0&&{needsDatabaseConnection:n.needsDatabaseConnection},...n.routing!==void 0&&{routing:n.routing}}))}i(J,"toUserServiceConfigs");function K(e,n,r=!0,c,t){const o={appName:e,type:n,database:[],s3:[],compute:[]};if(n==="custom")return o;const s=n,a=l[s];return{...o,database:$(e,a,s,r,t),compute:W(e,a,s,r,c),network:a.network,backup:a.backup}}i(K,"planApplicationResources");function $(e,n,r,c,t){const o=P(r),s=n.database[o];return!c||s===null?[]:[{name:e,type:o,databaseName:v(e),variableName:`${m(e)}Database`,...s,...t?.snapshotIdentifier!==void 0&&{snapshotIdentifier:t.snapshotIdentifier},...t?.snapshotUsername!==void 0&&{snapshotUsername:t.snapshotUsername}}]}i($,"buildDatabasePlan");function N(e,n){if(!(e===void 0&&n===void 0))return{scaling:{...e!==void 0&&{minCapacity:e},...n!==void 0&&{maxCapacity:n}}}}i(N,"buildScalingConfig");function H(e){const{minCapacity:n,maxCapacity:r,...c}=e;return{...c,...N(n,r)}}i(H,"planServiceFromTierPreset");function M(e,n){const r=H(e),c=n?.serviceType==="worker",t=n?.containerPort??T,o=n?.docker;return{...r,...o?.path!==void 0&&{docker:{path:o.path,...o.context!==void 0&&{context:o.context},...o.target!==void 0&&{target:o.target}}},...n?.needsDatabaseConnection!==void 0&&{needsDatabaseConnection:n.needsDatabaseConnection},containers:c?[{}]:[{port:t}]}}i(M,"buildServiceEntry");function V(e,n){return n||e?.directAccess===!0?e:{...e,loadBalancer:!1}}i(V,"resolveClusterConfig");function W(e,n,r,c,t){const o=n.compute.ecs,a=(t&&t.length>0?k(r,t):o.services.map((u,d)=>({...u,name:d===0?"api":`service-${d+1}`}))).map((u,d)=>M(u,t?.[d])),g=a.some(u=>u.containers?.some(d=>d.port!==void 0));return[{name:e,type:D.ECS,needsConnection:c,connectedDatabase:c?[e]:void 0,variableName:`${m(e)}Compute`,cluster:V(o.cluster,g),services:a}]}i(W,"buildComputePlan");function O(e,n){const r=[S(e),E(e),R(e)];if(F(e))r.push(_(e),C(e));else{const t=j(e);r.push(C(e),y(e),I(e),w(e),x(e),A(e),B(e,t),U(e))}const c=r.join("");if(e.customCodeBlocks&&e.customCodeBlocks.length>0){const t=p(c,e.customCodeBlocks,n?.resourceMapping);return t.success?f(t.content):h(new Error(`Custom code injection failed: ${t.error??"unknown error"}`))}return f(c)}i(O,"generateInfrastructureFromPlan");export{O as generateInfrastructureFromPlan,K as planApplicationResources,H as planServiceFromTierPreset,J as toUserServiceConfigs};
1
+ var b=Object.defineProperty;var i=(e,n)=>b(e,"name",{value:n,configurable:!0});import{TIER_PRESETS as l,getDefaultDatabaseTypeForTier as k,applyTierDefaultsToServices as P}from"../presets/tierPresets.js";import{COMPUTE_TYPE as D,DEFAULT_CONTAINER_PORT as T}from"../schemas/constants.js";import{success as f,failure as p}from"../types/Result.js";import{injectCustomCodeBlocks as h}from"../ast/mutation/astCodeInjection.js";import{toVariableName as m,toValidDatabaseName as v,generateImports as S,generateAppInit as y,generateTags as E,generateNetworkCode as C,generateDatabaseCode as R,generateClickHouseCode as I,generateS3Code as w,generateDynamoDBCode as x,generateSQSCode as A,generateComputeCode as B,generateCDNCode as U,collectCdnReferencedResources as j,usesPatternApproach as F,generatePatternCodeWithComments as _}from"../generation/index.js";function J(e){return e?.map(n=>({name:n.name,...n.serviceType!==void 0&&{serviceType:n.serviceType},...n.docker!==void 0&&{docker:n.docker},...n.containerPort!==void 0&&{containerPort:n.containerPort},...n.needsDatabaseConnection!==void 0&&{needsDatabaseConnection:n.needsDatabaseConnection},...n.routing!==void 0&&{routing:n.routing}}))}i(J,"toUserServiceConfigs");function K(e,n,o=!0,c,t){const r={appName:e,type:n,database:[],s3:[],compute:[]};if(n==="custom")return r;const s=n,a=l[s];return{...r,database:$(e,a,s,o,t),compute:W(e,a,s,o,c),network:a.network,backup:a.backup}}i(K,"planApplicationResources");function $(e,n,o,c,t){const r=k(o),s=n.database[r];return!c||s===null?[]:[{name:e,type:r,databaseName:v(e),variableName:`${m(e)}Database`,...s,...t?.snapshotIdentifier!==void 0&&{snapshotIdentifier:t.snapshotIdentifier},...t?.snapshotUsername!==void 0&&{snapshotUsername:t.snapshotUsername}}]}i($,"buildDatabasePlan");function N(e,n){if(!(e===void 0&&n===void 0))return{scaling:{...e!==void 0&&{minCapacity:e},...n!==void 0&&{maxCapacity:n}}}}i(N,"buildScalingConfig");function H(e){const{minCapacity:n,maxCapacity:o,...c}=e;return{...c,...N(n,o)}}i(H,"planServiceFromTierPreset");function M(e,n){const o=H(e),c=n?.serviceType==="worker",t=n?.containerPort??T,r=n?.docker;return{...o,...r?.path!==void 0&&{docker:{path:r.path,...r.context!==void 0&&{context:r.context},...r.target!==void 0&&{target:r.target}}},...n?.needsDatabaseConnection!==void 0&&{needsDatabaseConnection:n.needsDatabaseConnection},...c&&{serviceType:"worker"},containers:c?[{}]:[{port:t}]}}i(M,"buildServiceEntry");function V(e,n){return n||e?.directAccess===!0?e:{...e,loadBalancer:!1}}i(V,"resolveClusterConfig");function W(e,n,o,c,t){const r=n.compute.ecs,a=(t&&t.length>0?P(o,t):r.services.map((u,d)=>({...u,name:d===0?"api":`service-${d+1}`}))).map((u,d)=>M(u,t?.[d])),g=a.some(u=>u.containers?.some(d=>d.port!==void 0));return[{name:e,type:D.ECS,needsConnection:c,connectedDatabase:c?[e]:void 0,variableName:`${m(e)}Compute`,cluster:V(r.cluster,g),services:a}]}i(W,"buildComputePlan");function O(e,n){const o=[S(e),y(e),E(e)];if(F(e))o.push(_(e),C(e));else{const t=j(e);o.push(C(e),R(e),I(e),w(e),x(e),A(e),B(e,t),U(e))}const c=o.join("");if(e.customCodeBlocks&&e.customCodeBlocks.length>0){const t=h(c,e.customCodeBlocks,n?.resourceMapping);return t.success?f(t.content):p(new Error(`Custom code injection failed: ${t.error??"unknown error"}`))}return f(c)}i(O,"generateInfrastructureFromPlan");export{O as generateInfrastructureFromPlan,K as planApplicationResources,H as planServiceFromTierPreset,J as toUserServiceConfigs};
@@ -612,6 +612,10 @@ export declare const ApplicationResourcePlanSchema: z.ZodObject<{
612
612
  priority: z.ZodOptional<z.ZodNumber>;
613
613
  healthCheckPath: z.ZodOptional<z.ZodString>;
614
614
  }, z.core.$strict>>]>>;
615
+ serviceType: z.ZodOptional<z.ZodEnum<{
616
+ web: "web";
617
+ worker: "worker";
618
+ }>>;
615
619
  cpu: z.ZodOptional<z.ZodNumber>;
616
620
  memoryLimitMiB: z.ZodOptional<z.ZodNumber>;
617
621
  desiredCount: z.ZodOptional<z.ZodNumber>;
@@ -221,6 +221,10 @@ export declare const EcsServiceConfigSchema: z.ZodObject<{
221
221
  priority: z.ZodOptional<z.ZodNumber>;
222
222
  healthCheckPath: z.ZodOptional<z.ZodString>;
223
223
  }, z.core.$strict>>]>>;
224
+ serviceType: z.ZodOptional<z.ZodEnum<{
225
+ web: "web";
226
+ worker: "worker";
227
+ }>>;
224
228
  cpu: z.ZodOptional<z.ZodNumber>;
225
229
  memoryLimitMiB: z.ZodOptional<z.ZodNumber>;
226
230
  desiredCount: z.ZodOptional<z.ZodNumber>;
@@ -370,6 +374,10 @@ export declare const ComputeResourcePlanSchema: z.ZodObject<{
370
374
  priority: z.ZodOptional<z.ZodNumber>;
371
375
  healthCheckPath: z.ZodOptional<z.ZodString>;
372
376
  }, z.core.$strict>>]>>;
377
+ serviceType: z.ZodOptional<z.ZodEnum<{
378
+ web: "web";
379
+ worker: "worker";
380
+ }>>;
373
381
  cpu: z.ZodOptional<z.ZodNumber>;
374
382
  memoryLimitMiB: z.ZodOptional<z.ZodNumber>;
375
383
  desiredCount: z.ZodOptional<z.ZodNumber>;
@@ -556,8 +564,8 @@ export declare const LambdaGeneratorSchema: z.ZodObject<{
556
564
  nameProvidedByFlag: z.ZodOptional<z.ZodBoolean>;
557
565
  lambdaType: z.ZodOptional<z.ZodEnum<{
558
566
  custom: "custom";
559
- basic: "basic";
560
567
  web: "web";
568
+ basic: "basic";
561
569
  }>>;
562
570
  ecrRepository: z.ZodOptional<z.ZodString>;
563
571
  timeout: z.ZodOptional<z.ZodNumber>;
@@ -769,6 +777,10 @@ export declare const ComputeGeneratorSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
769
777
  priority: z.ZodOptional<z.ZodNumber>;
770
778
  healthCheckPath: z.ZodOptional<z.ZodString>;
771
779
  }, z.core.$strict>>]>>;
780
+ serviceType: z.ZodOptional<z.ZodEnum<{
781
+ web: "web";
782
+ worker: "worker";
783
+ }>>;
772
784
  cpu: z.ZodOptional<z.ZodNumber>;
773
785
  memoryLimitMiB: z.ZodOptional<z.ZodNumber>;
774
786
  desiredCount: z.ZodOptional<z.ZodNumber>;
@@ -1 +1 @@
1
- var j=Object.defineProperty;var h=(n,t)=>j(n,"name",{value:t,configurable:!0});import{z as e}from"zod";import{VALIDATION_PATTERNS as m,VALIDATION_MESSAGES as o}from"../validation/patterns.js";import{COMPUTE_TYPES as f,ECS_CAPACITY_PROVIDERS as x,EC2_INSTANCE_TYPES as W,HTTP_METHODS as w,MIN_LAMBDA_MEMORY as V,MAX_LAMBDA_MEMORY as K,MIN_LAMBDA_TIMEOUT as S,MAX_LAMBDA_TIMEOUT as g,MIN_ECS_CAPACITY as O,MAX_ECS_CAPACITY as L,MAX_SCALING_CAPACITY as p,MAX_WARM_POOL_SIZE as F,constIncludes as Z,COMPUTE_ARCHITECTURES as z,FUNCTION_URL_AUTH_TYPES as H,DEPLOYMENT_TYPES as Q,AMI_HARDWARE_TYPES as $,LOAD_BALANCER_TYPES as q,SCALING_TYPES as J}from"./constants.js";import{validateArchitectureMatch as ee,getArchitectureForInstanceType as oe}from"./instanceTypeArchitecture.js";import{optionalOrDisabled as ne,CAPACITY_REFINEMENT as r,memoryLimitMiBSchema as I,ResourceNameSchema as c,AppNameSchema as s,PortSchema as T,ExtraPropertySchema as l,EnvironmentRecordSchema as E,SecretsImportRecordSchema as te}from"./baseSchemas.js";import{DockerBuildSchema as A}from"@fjall/util/manifest/schemas";import{EcsServiceAlarmConfigSchema as ie,LambdaAlarmConfigSchema as ae}from"./alarmSchemas.js";function re(n){return!(n.image!==void 0&&n.docker!==void 0)}h(re,"imageDockerMutexCheck");const D=e.number().int(o.CAPACITY.MIN.INTEGER).min(O,o.GENERATOR_CAPACITY.MIN.MIN).max(L,o.GENERATOR_CAPACITY.MIN.MAX),G=e.number().int(o.CAPACITY.MAX.INTEGER).min(O,o.GENERATOR_CAPACITY.MAX.MIN).max(L,o.GENERATOR_CAPACITY.MAX.MAX),N=e.number().int(o.LAMBDA.MEMORY.INTEGER).min(V,o.LAMBDA.MEMORY.MIN).max(K,o.LAMBDA.MEMORY.MAX).refine(n=>n===128||n%64===0,o.LAMBDA.MEMORY.MULTIPLE),Y=e.string().regex(m.LAMBDA_RUNTIME_IDENTIFIER,o.LAMBDA.RUNTIME),d=e.number().int(o.CPU.INTEGER).min(256,o.CPU.MIN).max(4096,o.CPU.MAX),u=e.number().int(o.CAPACITY.DESIRED.INTEGER).min(0,o.CAPACITY.DESIRED.MIN).max(p,o.CAPACITY.DESIRED.MAX),C=e.object({connectToDatabase:e.array(e.string()).optional()}).strict(),ce=e.object({minSize:e.number().int(o.CAPACITY.WARM_POOL.MIN_SIZE.INTEGER).min(0,o.CAPACITY.WARM_POOL.MIN_SIZE.MIN).max(F,o.CAPACITY.WARM_POOL.MIN_SIZE.MAX).optional(),reuseOnScaleIn:e.boolean().optional()}).strict(),_=e.object({instanceType:e.string().optional(),amiHardwareType:e.enum($).optional(),minCapacity:e.number().int(o.CAPACITY.MIN.INTEGER).min(0,o.CAPACITY.MIN.MIN_0).max(p,o.CAPACITY.MIN.MAX).optional(),maxCapacity:e.number().int(o.CAPACITY.MAX.INTEGER).min(1,o.CAPACITY.MAX.MIN_1).max(p,o.CAPACITY.MAX.MAX).optional(),memoryLimitMiB:I(128).optional(),warmPool:ce.optional(),extraProperties:e.array(l).optional()}).strict().superRefine((n,t)=>{if(!n.instanceType||!n.amiHardwareType)return;const i=ee(n.instanceType,n.amiHardwareType);i.valid||t.addIssue({code:"custom",message:i.message??o.ARCHITECTURE_MISMATCH,path:["instanceType"]})}).superRefine((n,t)=>{n.minCapacity===0&&!n.warmPool&&t.addIssue({code:"custom",message:o.CAPACITY.WARM_POOL_REQUIRED,path:["minCapacity"]}),n.warmPool?.minSize!==void 0&&n.maxCapacity!==void 0&&n.warmPool.minSize>n.maxCapacity&&t.addIssue({code:"custom",message:o.CAPACITY.WARM_POOL.MIN_SIZE_EXCEEDS_MAX_CAPACITY,path:["warmPool","minSize"]})}),se=e.enum(f).describe(`Compute type must be one of: ${f.join(", ")}`),y=e.enum(x).describe(`ECS capacity provider must be one of: ${x.join(", ")}`),b=e.string().refine(n=>Z(W,n),{message:o.INSTANCE_TYPE}),v=e.object({sourceType:e.enum(["sqs","dynamodb","eventbridge"]),sourceRef:e.string().describe("Name of the source resource"),batchSize:e.number().int(o.BATCH_SIZE.INTEGER).min(1,o.BATCH_SIZE.MIN).max(1e4,o.BATCH_SIZE.MAX).optional(),startingPosition:e.enum(["TRIM_HORIZON","LATEST"]).optional(),maxBatchingWindow:e.number().int(o.BATCHING_WINDOW.INTEGER).min(0,o.BATCHING_WINDOW.MIN).max(300,o.BATCHING_WINDOW.MAX).optional(),reportBatchItemFailures:e.boolean().optional()}).strict(),me=e.object({name:e.string().min(1,o.REQUIRED.CONTAINER_NAME).optional(),image:e.string().optional(),port:T.optional(),environment:E.optional(),secretsImport:te.optional(),command:e.array(e.string()).optional(),entryPoint:e.array(e.string()).optional(),essential:e.boolean().optional(),healthCheck:e.object({command:e.array(e.string()),interval:e.number().int(o.HEALTH_CHECK.INTERVAL.INTEGER).min(5,o.HEALTH_CHECK.INTERVAL.MIN).max(300,o.HEALTH_CHECK.INTERVAL.MAX).optional(),timeout:e.number().int(o.HEALTH_CHECK.TIMEOUT.INTEGER).min(2,o.HEALTH_CHECK.TIMEOUT.MIN).max(60,o.HEALTH_CHECK.TIMEOUT.MAX).optional(),retries:e.number().int(o.HEALTH_CHECK.RETRIES.INTEGER).min(1,o.HEALTH_CHECK.RETRIES.MIN).max(10,o.HEALTH_CHECK.RETRIES.MAX).optional(),startPeriod:e.number().int(o.HEALTH_CHECK.START_PERIOD.INTEGER).min(0,o.HEALTH_CHECK.START_PERIOD.MIN).max(300,o.HEALTH_CHECK.START_PERIOD.MAX).optional()}).strict().optional(),ssmSecrets:e.array(e.string().regex(m.SECRET_NAME,o.SECRET_NAME)).optional(),extraProperties:e.array(l).optional()}).strict(),U=e.string().min(1,o.REQUIRED.SERVICE_NAME).max(255,o.MAX_LENGTH.SERVICE_NAME).regex(m.ECS_SERVICE_NAME,o.ECS_SERVICE_NAME),B=e.object({domain:e.string().optional(),loadBalancer:e.union([e.literal(!1),e.enum(q)]).optional(),directAccess:e.boolean().optional(),extraProperties:e.array(l).optional()}).strict().refine(n=>!(n.directAccess&&n.domain),{message:o.DIRECT_ACCESS.NO_DOMAIN,path:["directAccess"]}).refine(n=>!(n.directAccess&&typeof n.loadBalancer=="string"),{message:o.DIRECT_ACCESS.NO_LOAD_BALANCER}).describe("Cluster-level configuration"),M=e.object({path:e.string().optional(),host:e.string().optional(),priority:e.number().int(o.PRIORITY.INTEGER).min(1,o.PRIORITY.MIN).max(5e4,o.PRIORITY.MAX).optional(),healthCheckPath:e.string().optional()}).strict().describe("Path/host-based routing configuration"),pe=e.object({desiredCount:u.optional(),minCapacity:e.number().int(o.CAPACITY.MIN.INTEGER).min(0,o.CAPACITY.MIN.MIN_0).max(p,o.CAPACITY.MIN.MAX).optional(),maxCapacity:e.number().int(o.CAPACITY.MAX.INTEGER).min(1,o.CAPACITY.MAX.MIN_1).max(p,o.CAPACITY.MAX.MAX).optional(),scalingType:e.enum(J).optional()}).strict().refine(r.check,r.params).describe("ECS service scaling configuration"),X=e.object({name:U,docker:A.optional(),needsDatabaseConnection:e.boolean().optional(),needsStorageConnection:e.boolean().optional(),needsMessagingConnection:e.boolean().optional(),image:e.string().optional(),containers:e.array(me).optional(),routing:e.union([M,e.array(M).min(1)]).optional(),cpu:d.optional(),memoryLimitMiB:I(512).optional(),desiredCount:u.optional(),scaling:ne(pe).optional(),capacityProvider:y,ec2Config:_.optional(),ssmSecretsPath:e.string().regex(m.SSM_PATH,o.SSM_PATH).optional(),extraProperties:e.array(l).optional(),alarms:ie.optional()}).strict().superRefine((n,t)=>{re(n)||t.addIssue({code:"custom",path:["docker"],message:o.IMAGE_DOCKER_MUTEX})}).describe("Configuration for a service in an ECS cluster"),Ne=e.object({name:c,type:se,needsConnection:e.boolean(),connectedDatabase:e.array(e.string()).optional(),connectedStorage:e.array(e.string()).optional(),connectedMessaging:e.array(e.string()).optional(),cluster:B.optional(),services:e.array(X).optional(),docker:A.partial().optional(),deployment:e.enum(Q).optional(),codePath:e.string().optional(),timeout:e.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(S,o.LAMBDA.TIMEOUT.MIN).max(g,o.LAMBDA.TIMEOUT.MAX).optional(),memory:N.optional(),handler:e.string().optional(),runtime:Y.optional(),environment:E.optional(),secrets:E.optional(),eventSources:e.array(v).optional(),functionUrl:e.object({authType:e.enum(H)}).strict().optional(),description:e.string().optional(),scheduleExpression:e.string().optional(),architecture:e.enum(z).optional(),ephemeralStorageSize:e.number().int(o.EPHEMERAL_STORAGE.INTEGER).min(512,o.EPHEMERAL_STORAGE.MIN).max(10240,o.EPHEMERAL_STORAGE.MAX).optional(),functionName:e.string().optional(),ssmSecrets:e.array(e.string()).optional(),ssmSecretsPath:e.string().optional(),alarms:ae.optional(),instanceType:b.optional(),enableSSH:e.boolean().optional(),keyName:e.string().optional(),userData:e.string().optional(),securityGroups:e.array(e.string()).optional(),variableName:e.string().optional(),extraProperties:e.array(l).optional()}).strict().superRefine((n,t)=>{if(n.type==="ecs"&&n.services)for(let i=0;i<n.services.length;i++){const a=n.services[i];a?.ec2Config?.instanceType&&!a.ec2Config.amiHardwareType&&oe(a.ec2Config.instanceType)!=="ARM"&&t.addIssue({code:"custom",message:`Service '${a.name??i}' uses instance type '${a.ec2Config.instanceType}' (x86), which requires Docker images built for linux/amd64. The default build targets linux/arm64 (Graviton). Use a Graviton instance type (t4g, c6g, r6g, m6g, etc.) or set amiHardwareType: "STANDARD" to acknowledge x86.`,path:["services",i,"ec2Config","instanceType"]})}n.type==="lambda"&&n.deployment==="container"&&n.architecture==="X86_64"&&t.addIssue({code:"custom",message:"Lambda architecture 'X86_64' requires Docker images built for linux/amd64, but the default build targets linux/arm64. Use 'ARM_64' for Graviton Lambdas (recommended) or ensure your build pipeline targets linux/amd64.",path:["architecture"]})}),de=e.object({appName:s,clusterName:c,containerPort:T,nameProvidedByFlag:e.boolean().optional(),ecrRepository:e.string().optional(),capacityProvider:y.optional(),useAppEcr:e.boolean().optional(),desiredCount:u.optional(),cpu:d.optional(),memoryLimitMiB:I(512).optional(),minCapacity:D.optional(),maxCapacity:G.optional(),ec2Config:_.optional(),connectionConfig:C.optional()}).strict().refine(r.check,r.params),_e=e.object({appName:s,functionName:c,nameProvidedByFlag:e.boolean().optional(),lambdaType:e.enum(["basic","web","custom"]).optional(),ecrRepository:e.string().optional(),timeout:e.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(S,o.LAMBDA.TIMEOUT.MIN).max(g,o.LAMBDA.TIMEOUT.MAX).optional(),memory:N.optional(),enableFunctionUrl:e.boolean().optional(),description:e.string().optional(),enableCors:e.boolean().optional(),corsOrigins:e.string().optional(),corsHeaders:e.string().optional(),corsMethods:e.array(e.enum(w)).optional(),corsCredentials:e.boolean().optional(),connectionConfig:C.optional()}).strict(),ye=e.object({appName:s,instanceName:c,nameProvidedByFlag:e.boolean().optional(),instanceType:b.optional(),enableSSH:e.boolean().optional(),minCapacity:D.optional(),maxCapacity:G.optional(),connectionConfig:C.optional()}).strict().refine(r.check,r.params),be=e.object({appName:s,clusterName:c,serviceName:U,capacityProvider:y,containerPort:T.optional(),cpu:d.optional(),memoryLimitMiB:I(512).optional(),desiredCount:u.optional(),ec2Config:_.optional(),routing:e.union([M,e.array(M).min(1)]).optional(),docker:A.partial().optional(),nameProvidedByFlag:e.boolean().optional(),connectionConfig:C.optional()}).strict(),P=e.object({appName:s,computeName:c,nameProvidedByFlag:e.boolean().optional(),connectionConfig:C.optional()}).strict(),le=P.extend({type:e.literal("ecs"),cluster:B.optional(),services:e.array(X).min(1,o.SERVICE.MIN_REQUIRED),docker:A.partial().optional()}).strict().refine(n=>{const t=n.services.filter(i=>i.containers?.some(a=>a.port));return t.length>1?t.every(i=>(Array.isArray(i.routing)?i.routing:i.routing?[i.routing]:[]).some(R=>R.path||R.host)):!0},{message:o.SERVICE.ROUTING_REQUIRED}).refine(n=>{const t=n.services.map(i=>i.name);return new Set(t).size===t.length},{message:o.SERVICE.UNIQUE_WITHIN_CLUSTER}),Ee=P.extend({type:e.literal("lambda"),timeout:e.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(S,o.LAMBDA.TIMEOUT.MIN).max(g,o.LAMBDA.TIMEOUT.MAX).optional(),memory:N.optional(),handler:e.string().optional(),runtime:Y.optional(),environment:E.optional(),secrets:E.optional(),description:e.string().optional(),functionUrl:e.union([e.object({authType:e.enum(H).optional()}).strict(),e.literal(!1)]).optional(),eventSources:e.array(v).optional()}).strict(),Ae=P.extend({type:e.literal("ec2"),instanceType:b.optional(),enableSSH:e.boolean().optional(),keyName:e.string().optional(),userData:e.string().optional(),securityGroups:e.array(e.string()).optional()}).strict(),Pe=e.discriminatedUnion("type",[le,Ee,Ae]),k=e.object({path:e.string().min(1,o.REQUIRED.ROUTING_PATH),priority:e.number().int(o.PRIORITY.INTEGER).min(1,o.PRIORITY.MIN).max(5e4,o.PRIORITY.MAX).optional()}).strict(),he=e.object({name:e.string().min(1,o.REQUIRED.SERVICE_NAME).max(255,o.MAX_LENGTH.SERVICE_NAME).regex(m.RESOURCE_NAME,o.RESOURCE_NAME),serviceType:e.enum(["web","worker"]).optional(),docker:A.partial().optional(),containerPort:T.optional(),needsDatabaseConnection:e.boolean().optional(),routing:e.union([k,e.array(k).min(1)]).optional()}).strict().superRefine((n,t)=>{n.serviceType==="worker"&&(n.containerPort!==void 0&&t.addIssue({code:"custom",path:["containerPort"],message:"Worker services are not reachable inbound; remove containerPort."}),n.routing!==void 0&&t.addIssue({code:"custom",path:["routing"],message:"Worker services have no ALB route; remove routing."}))}),fe=e.object({appName:s,instanceType:e.string().optional()}).strict();export{be as AddServiceGeneratorSchema,he as ApplicationServiceConfigSchema,k as ApplicationServiceRoutingSchema,Pe as ComputeGeneratorSchema,Ne as ComputeResourcePlanSchema,se as ComputeTypeSchema,me as ContainerConfigSchema,ye as EC2GeneratorSchema,de as ECSGeneratorSchema,_ as Ec2ConfigSchema,y as EcsCapacityProviderSchema,B as EcsClusterConfigSchema,M as EcsRoutingConfigSchema,pe as EcsScalingConfigSchema,X as EcsServiceConfigSchema,U as EcsServiceNameSchema,b as InstanceTypeSchema,v as LambdaEventSourceSchema,_e as LambdaGeneratorSchema,N as LambdaMemorySchema,Y as LambdaRuntimeSchema,fe as TunnelGeneratorSchema,ce as WarmPoolSchema};
1
+ var W=Object.defineProperty;var h=(n,t)=>W(n,"name",{value:t,configurable:!0});import{z as e}from"zod";import{VALIDATION_PATTERNS as m,VALIDATION_MESSAGES as o}from"../validation/patterns.js";import{COMPUTE_TYPES as f,ECS_CAPACITY_PROVIDERS as x,EC2_INSTANCE_TYPES as w,HTTP_METHODS as V,MIN_LAMBDA_MEMORY as K,MAX_LAMBDA_MEMORY as F,MIN_LAMBDA_TIMEOUT as S,MAX_LAMBDA_TIMEOUT as g,MIN_ECS_CAPACITY as O,MAX_ECS_CAPACITY as L,MAX_SCALING_CAPACITY as p,MAX_WARM_POOL_SIZE as Z,constIncludes as z,COMPUTE_ARCHITECTURES as Q,FUNCTION_URL_AUTH_TYPES as H,DEPLOYMENT_TYPES as $,AMI_HARDWARE_TYPES as q,LOAD_BALANCER_TYPES as J,SCALING_TYPES as ee,ECS_SERVICE_TYPES as D}from"./constants.js";import{validateArchitectureMatch as oe,getArchitectureForInstanceType as ne}from"./instanceTypeArchitecture.js";import{optionalOrDisabled as te,CAPACITY_REFINEMENT as r,memoryLimitMiBSchema as I,ResourceNameSchema as c,AppNameSchema as s,PortSchema as T,ExtraPropertySchema as l,EnvironmentRecordSchema as E,SecretsImportRecordSchema as ie}from"./baseSchemas.js";import{DockerBuildSchema as A}from"@fjall/util/manifest/schemas";import{EcsServiceAlarmConfigSchema as ae,LambdaAlarmConfigSchema as re}from"./alarmSchemas.js";function ce(n){return!(n.image!==void 0&&n.docker!==void 0)}h(ce,"imageDockerMutexCheck");const G=e.number().int(o.CAPACITY.MIN.INTEGER).min(O,o.GENERATOR_CAPACITY.MIN.MIN).max(L,o.GENERATOR_CAPACITY.MIN.MAX),Y=e.number().int(o.CAPACITY.MAX.INTEGER).min(O,o.GENERATOR_CAPACITY.MAX.MIN).max(L,o.GENERATOR_CAPACITY.MAX.MAX),N=e.number().int(o.LAMBDA.MEMORY.INTEGER).min(K,o.LAMBDA.MEMORY.MIN).max(F,o.LAMBDA.MEMORY.MAX).refine(n=>n===128||n%64===0,o.LAMBDA.MEMORY.MULTIPLE),v=e.string().regex(m.LAMBDA_RUNTIME_IDENTIFIER,o.LAMBDA.RUNTIME),d=e.number().int(o.CPU.INTEGER).min(256,o.CPU.MIN).max(4096,o.CPU.MAX),u=e.number().int(o.CAPACITY.DESIRED.INTEGER).min(0,o.CAPACITY.DESIRED.MIN).max(p,o.CAPACITY.DESIRED.MAX),C=e.object({connectToDatabase:e.array(e.string()).optional()}).strict(),se=e.object({minSize:e.number().int(o.CAPACITY.WARM_POOL.MIN_SIZE.INTEGER).min(0,o.CAPACITY.WARM_POOL.MIN_SIZE.MIN).max(Z,o.CAPACITY.WARM_POOL.MIN_SIZE.MAX).optional(),reuseOnScaleIn:e.boolean().optional()}).strict(),_=e.object({instanceType:e.string().optional(),amiHardwareType:e.enum(q).optional(),minCapacity:e.number().int(o.CAPACITY.MIN.INTEGER).min(0,o.CAPACITY.MIN.MIN_0).max(p,o.CAPACITY.MIN.MAX).optional(),maxCapacity:e.number().int(o.CAPACITY.MAX.INTEGER).min(1,o.CAPACITY.MAX.MIN_1).max(p,o.CAPACITY.MAX.MAX).optional(),memoryLimitMiB:I(128).optional(),warmPool:se.optional(),extraProperties:e.array(l).optional()}).strict().superRefine((n,t)=>{if(!n.instanceType||!n.amiHardwareType)return;const i=oe(n.instanceType,n.amiHardwareType);i.valid||t.addIssue({code:"custom",message:i.message??o.ARCHITECTURE_MISMATCH,path:["instanceType"]})}).superRefine((n,t)=>{n.minCapacity===0&&!n.warmPool&&t.addIssue({code:"custom",message:o.CAPACITY.WARM_POOL_REQUIRED,path:["minCapacity"]}),n.warmPool?.minSize!==void 0&&n.maxCapacity!==void 0&&n.warmPool.minSize>n.maxCapacity&&t.addIssue({code:"custom",message:o.CAPACITY.WARM_POOL.MIN_SIZE_EXCEEDS_MAX_CAPACITY,path:["warmPool","minSize"]})}),me=e.enum(f).describe(`Compute type must be one of: ${f.join(", ")}`),y=e.enum(x).describe(`ECS capacity provider must be one of: ${x.join(", ")}`),P=e.string().refine(n=>z(w,n),{message:o.INSTANCE_TYPE}),U=e.object({sourceType:e.enum(["sqs","dynamodb","eventbridge"]),sourceRef:e.string().describe("Name of the source resource"),batchSize:e.number().int(o.BATCH_SIZE.INTEGER).min(1,o.BATCH_SIZE.MIN).max(1e4,o.BATCH_SIZE.MAX).optional(),startingPosition:e.enum(["TRIM_HORIZON","LATEST"]).optional(),maxBatchingWindow:e.number().int(o.BATCHING_WINDOW.INTEGER).min(0,o.BATCHING_WINDOW.MIN).max(300,o.BATCHING_WINDOW.MAX).optional(),reportBatchItemFailures:e.boolean().optional()}).strict(),pe=e.object({name:e.string().min(1,o.REQUIRED.CONTAINER_NAME).optional(),image:e.string().optional(),port:T.optional(),environment:E.optional(),secretsImport:ie.optional(),command:e.array(e.string()).optional(),entryPoint:e.array(e.string()).optional(),essential:e.boolean().optional(),healthCheck:e.object({command:e.array(e.string()),interval:e.number().int(o.HEALTH_CHECK.INTERVAL.INTEGER).min(5,o.HEALTH_CHECK.INTERVAL.MIN).max(300,o.HEALTH_CHECK.INTERVAL.MAX).optional(),timeout:e.number().int(o.HEALTH_CHECK.TIMEOUT.INTEGER).min(2,o.HEALTH_CHECK.TIMEOUT.MIN).max(60,o.HEALTH_CHECK.TIMEOUT.MAX).optional(),retries:e.number().int(o.HEALTH_CHECK.RETRIES.INTEGER).min(1,o.HEALTH_CHECK.RETRIES.MIN).max(10,o.HEALTH_CHECK.RETRIES.MAX).optional(),startPeriod:e.number().int(o.HEALTH_CHECK.START_PERIOD.INTEGER).min(0,o.HEALTH_CHECK.START_PERIOD.MIN).max(300,o.HEALTH_CHECK.START_PERIOD.MAX).optional()}).strict().optional(),ssmSecrets:e.array(e.string().regex(m.SECRET_NAME,o.SECRET_NAME)).optional(),extraProperties:e.array(l).optional()}).strict(),B=e.string().min(1,o.REQUIRED.SERVICE_NAME).max(255,o.MAX_LENGTH.SERVICE_NAME).regex(m.ECS_SERVICE_NAME,o.ECS_SERVICE_NAME),X=e.object({domain:e.string().optional(),loadBalancer:e.union([e.literal(!1),e.enum(J)]).optional(),directAccess:e.boolean().optional(),extraProperties:e.array(l).optional()}).strict().refine(n=>!(n.directAccess&&n.domain),{message:o.DIRECT_ACCESS.NO_DOMAIN,path:["directAccess"]}).refine(n=>!(n.directAccess&&typeof n.loadBalancer=="string"),{message:o.DIRECT_ACCESS.NO_LOAD_BALANCER}).describe("Cluster-level configuration"),M=e.object({path:e.string().optional(),host:e.string().optional(),priority:e.number().int(o.PRIORITY.INTEGER).min(1,o.PRIORITY.MIN).max(5e4,o.PRIORITY.MAX).optional(),healthCheckPath:e.string().optional()}).strict().describe("Path/host-based routing configuration"),le=e.object({desiredCount:u.optional(),minCapacity:e.number().int(o.CAPACITY.MIN.INTEGER).min(0,o.CAPACITY.MIN.MIN_0).max(p,o.CAPACITY.MIN.MAX).optional(),maxCapacity:e.number().int(o.CAPACITY.MAX.INTEGER).min(1,o.CAPACITY.MAX.MIN_1).max(p,o.CAPACITY.MAX.MAX).optional(),scalingType:e.enum(ee).optional()}).strict().refine(r.check,r.params).describe("ECS service scaling configuration"),j=e.object({name:B,docker:A.optional(),needsDatabaseConnection:e.boolean().optional(),needsStorageConnection:e.boolean().optional(),needsMessagingConnection:e.boolean().optional(),image:e.string().optional(),containers:e.array(pe).optional(),routing:e.union([M,e.array(M).min(1)]).optional(),serviceType:e.enum(D).optional(),cpu:d.optional(),memoryLimitMiB:I(512).optional(),desiredCount:u.optional(),scaling:te(le).optional(),capacityProvider:y,ec2Config:_.optional(),ssmSecretsPath:e.string().regex(m.SSM_PATH,o.SSM_PATH).optional(),extraProperties:e.array(l).optional(),alarms:ae.optional()}).strict().superRefine((n,t)=>{ce(n)||t.addIssue({code:"custom",path:["docker"],message:o.IMAGE_DOCKER_MUTEX})}).describe("Configuration for a service in an ECS cluster"),de=e.object({name:c,type:me,needsConnection:e.boolean(),connectedDatabase:e.array(e.string()).optional(),connectedStorage:e.array(e.string()).optional(),connectedMessaging:e.array(e.string()).optional(),cluster:X.optional(),services:e.array(j).optional(),docker:A.partial().optional(),deployment:e.enum($).optional(),codePath:e.string().optional(),timeout:e.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(S,o.LAMBDA.TIMEOUT.MIN).max(g,o.LAMBDA.TIMEOUT.MAX).optional(),memory:N.optional(),handler:e.string().optional(),runtime:v.optional(),environment:E.optional(),secrets:E.optional(),eventSources:e.array(U).optional(),functionUrl:e.object({authType:e.enum(H)}).strict().optional(),description:e.string().optional(),scheduleExpression:e.string().optional(),architecture:e.enum(Q).optional(),ephemeralStorageSize:e.number().int(o.EPHEMERAL_STORAGE.INTEGER).min(512,o.EPHEMERAL_STORAGE.MIN).max(10240,o.EPHEMERAL_STORAGE.MAX).optional(),functionName:e.string().optional(),ssmSecrets:e.array(e.string()).optional(),ssmSecretsPath:e.string().optional(),alarms:re.optional(),instanceType:P.optional(),enableSSH:e.boolean().optional(),keyName:e.string().optional(),userData:e.string().optional(),securityGroups:e.array(e.string()).optional(),variableName:e.string().optional(),extraProperties:e.array(l).optional()}).strict().superRefine((n,t)=>{if(n.type==="ecs"&&n.services)for(let i=0;i<n.services.length;i++){const a=n.services[i];a?.ec2Config?.instanceType&&!a.ec2Config.amiHardwareType&&ne(a.ec2Config.instanceType)!=="ARM"&&t.addIssue({code:"custom",message:`Service '${a.name??i}' uses instance type '${a.ec2Config.instanceType}' (x86), which requires Docker images built for linux/amd64. The default build targets linux/arm64 (Graviton). Use a Graviton instance type (t4g, c6g, r6g, m6g, etc.) or set amiHardwareType: "STANDARD" to acknowledge x86.`,path:["services",i,"ec2Config","instanceType"]})}n.type==="lambda"&&n.deployment==="container"&&n.architecture==="X86_64"&&t.addIssue({code:"custom",message:"Lambda architecture 'X86_64' requires Docker images built for linux/amd64, but the default build targets linux/arm64. Use 'ARM_64' for Graviton Lambdas (recommended) or ensure your build pipeline targets linux/amd64.",path:["architecture"]})}),_e=e.object({appName:s,clusterName:c,containerPort:T,nameProvidedByFlag:e.boolean().optional(),ecrRepository:e.string().optional(),capacityProvider:y.optional(),useAppEcr:e.boolean().optional(),desiredCount:u.optional(),cpu:d.optional(),memoryLimitMiB:I(512).optional(),minCapacity:G.optional(),maxCapacity:Y.optional(),ec2Config:_.optional(),connectionConfig:C.optional()}).strict().refine(r.check,r.params),ye=e.object({appName:s,functionName:c,nameProvidedByFlag:e.boolean().optional(),lambdaType:e.enum(["basic","web","custom"]).optional(),ecrRepository:e.string().optional(),timeout:e.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(S,o.LAMBDA.TIMEOUT.MIN).max(g,o.LAMBDA.TIMEOUT.MAX).optional(),memory:N.optional(),enableFunctionUrl:e.boolean().optional(),description:e.string().optional(),enableCors:e.boolean().optional(),corsOrigins:e.string().optional(),corsHeaders:e.string().optional(),corsMethods:e.array(e.enum(V)).optional(),corsCredentials:e.boolean().optional(),connectionConfig:C.optional()}).strict(),Pe=e.object({appName:s,instanceName:c,nameProvidedByFlag:e.boolean().optional(),instanceType:P.optional(),enableSSH:e.boolean().optional(),minCapacity:G.optional(),maxCapacity:Y.optional(),connectionConfig:C.optional()}).strict().refine(r.check,r.params),be=e.object({appName:s,clusterName:c,serviceName:B,capacityProvider:y,containerPort:T.optional(),cpu:d.optional(),memoryLimitMiB:I(512).optional(),desiredCount:u.optional(),ec2Config:_.optional(),routing:e.union([M,e.array(M).min(1)]).optional(),docker:A.partial().optional(),nameProvidedByFlag:e.boolean().optional(),connectionConfig:C.optional()}).strict(),b=e.object({appName:s,computeName:c,nameProvidedByFlag:e.boolean().optional(),connectionConfig:C.optional()}).strict(),Ee=b.extend({type:e.literal("ecs"),cluster:X.optional(),services:e.array(j).min(1,o.SERVICE.MIN_REQUIRED),docker:A.partial().optional()}).strict().refine(n=>{const t=n.services.filter(i=>i.containers?.some(a=>a.port));return t.length>1?t.every(i=>(Array.isArray(i.routing)?i.routing:i.routing?[i.routing]:[]).some(R=>R.path||R.host)):!0},{message:o.SERVICE.ROUTING_REQUIRED}).refine(n=>{const t=n.services.map(i=>i.name);return new Set(t).size===t.length},{message:o.SERVICE.UNIQUE_WITHIN_CLUSTER}),Ae=b.extend({type:e.literal("lambda"),timeout:e.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(S,o.LAMBDA.TIMEOUT.MIN).max(g,o.LAMBDA.TIMEOUT.MAX).optional(),memory:N.optional(),handler:e.string().optional(),runtime:v.optional(),environment:E.optional(),secrets:E.optional(),description:e.string().optional(),functionUrl:e.union([e.object({authType:e.enum(H).optional()}).strict(),e.literal(!1)]).optional(),eventSources:e.array(U).optional()}).strict(),Ce=b.extend({type:e.literal("ec2"),instanceType:P.optional(),enableSSH:e.boolean().optional(),keyName:e.string().optional(),userData:e.string().optional(),securityGroups:e.array(e.string()).optional()}).strict(),he=e.discriminatedUnion("type",[Ee,Ae,Ce]),k=e.object({path:e.string().min(1,o.REQUIRED.ROUTING_PATH),priority:e.number().int(o.PRIORITY.INTEGER).min(1,o.PRIORITY.MIN).max(5e4,o.PRIORITY.MAX).optional()}).strict(),fe=e.object({name:e.string().min(1,o.REQUIRED.SERVICE_NAME).max(255,o.MAX_LENGTH.SERVICE_NAME).regex(m.RESOURCE_NAME,o.RESOURCE_NAME),serviceType:e.enum(D).optional(),docker:A.partial().optional(),containerPort:T.optional(),needsDatabaseConnection:e.boolean().optional(),routing:e.union([k,e.array(k).min(1)]).optional()}).strict().superRefine((n,t)=>{n.serviceType==="worker"&&(n.containerPort!==void 0&&t.addIssue({code:"custom",path:["containerPort"],message:"Worker services are not reachable inbound; remove containerPort."}),n.routing!==void 0&&t.addIssue({code:"custom",path:["routing"],message:"Worker services have no ALB route; remove routing."}))}),xe=e.object({appName:s,instanceType:e.string().optional()}).strict();export{be as AddServiceGeneratorSchema,fe as ApplicationServiceConfigSchema,k as ApplicationServiceRoutingSchema,he as ComputeGeneratorSchema,de as ComputeResourcePlanSchema,me as ComputeTypeSchema,pe as ContainerConfigSchema,Pe as EC2GeneratorSchema,_e as ECSGeneratorSchema,_ as Ec2ConfigSchema,y as EcsCapacityProviderSchema,X as EcsClusterConfigSchema,M as EcsRoutingConfigSchema,le as EcsScalingConfigSchema,j as EcsServiceConfigSchema,B as EcsServiceNameSchema,P as InstanceTypeSchema,U as LambdaEventSourceSchema,ye as LambdaGeneratorSchema,N as LambdaMemorySchema,v as LambdaRuntimeSchema,xe as TunnelGeneratorSchema,se as WarmPoolSchema};
@@ -41,6 +41,8 @@ export declare const PATTERN_DATABASE_TYPES: readonly ["Instance", "Aurora"];
41
41
  export type PatternDatabaseType = (typeof PATTERN_DATABASE_TYPES)[number];
42
42
  export declare const DATABASE_ENGINES: readonly ["postgresql", "mysql"];
43
43
  export type DatabaseEngine = (typeof DATABASE_ENGINES)[number];
44
+ export declare const ECS_SERVICE_TYPES: readonly ["web", "worker"];
45
+ export type EcsServiceType = (typeof ECS_SERVICE_TYPES)[number];
44
46
  export declare const GOVERNANCE_PRESETS: readonly ["foundation", "compliance", "hardened"];
45
47
  export type GovernancePreset = (typeof GOVERNANCE_PRESETS)[number];
46
48
  export { ECS_CAPACITY_PROVIDERS, type EcsCapacityProvider, } from "./sharedTypes.js";
@@ -1 +1 @@
1
- var t=Object.defineProperty;var a=(e,r)=>t(e,"name",{value:r,configurable:!0});const x=Object.freeze({RESOURCE_SUFFIXES:Object.freeze({storage:"Storage",database:"Database",cluster:"Cluster",function:"Function",instance:"Instance",compute:"Compute"})});import{DATABASE_TYPES as y}from"./sharedTypes.js";const E=["ecs","lambda","ec2"],o=Object.freeze({ECS:"ecs",LAMBDA:"lambda",EC2:"ec2"}),l=["code","container"],T=Object.freeze({CODE:"code",CONTAINER:"container"}),A=["ARM_64","X86_64"],c="ARM_64",_=["NONE","AWS_IAM"],n=["public","internal"],s=["CPU","MEMORY"],P=["ARM","STANDARD"],S=["Instance","Aurora"],p=["postgresql","mysql"],O=["foundation","compliance","hardened"];import{ECS_CAPACITY_PROVIDERS as Z}from"./sharedTypes.js";const R="FARGATE";import{PATTERN_TYPE_VALUES as w,PATTERN_TYPES as k,isPatternType as v,PATTERN_REGISTRY as J,DEPLOYABLE_PATTERN_TYPES as Q,OPENNEXT_PATTERN_TYPES as $,isOpenNextPatternType as ee}from"@fjall/util";import{APP_TYPES as ae,CUSTOM_TIER as te}from"./sharedTypes.js";const N=["t3.nano","t3.micro","t3.small","t3.medium","t3.large","t3.xlarge","t3.2xlarge","t3a.nano","t3a.micro","t3a.small","t3a.medium","t3a.large","t3a.xlarge","t3a.2xlarge","t4g.nano","t4g.micro","t4g.small","t4g.medium","t4g.large","t4g.xlarge","t4g.2xlarge","c5.large","c5.xlarge","c5.2xlarge","c5.4xlarge","c5.9xlarge","c5.12xlarge","c5.18xlarge","c5.24xlarge","c5a.large","c5a.xlarge","c5a.2xlarge","c5a.4xlarge","c5a.8xlarge","c5a.12xlarge","c5a.16xlarge","c5a.24xlarge","c6g.medium","c6g.large","c6g.xlarge","c6g.2xlarge","c6g.4xlarge","c6g.8xlarge","c6g.12xlarge","c6g.16xlarge","r5.large","r5.xlarge","r5.2xlarge","r5.4xlarge","r5.8xlarge","r5.12xlarge","r5.16xlarge","r5.24xlarge","r5a.large","r5a.xlarge","r5a.2xlarge","r5a.4xlarge","r5a.8xlarge","r5a.12xlarge","r5a.16xlarge","r5a.24xlarge","r6g.medium","r6g.large","r6g.xlarge","r6g.2xlarge","r6g.4xlarge","r6g.8xlarge","r6g.12xlarge","r6g.16xlarge","i3.large","i3.xlarge","i3.2xlarge","i3.4xlarge","i3.8xlarge","i3.16xlarge","p3.2xlarge","p3.8xlarge","p3.16xlarge","g4dn.xlarge","g4dn.2xlarge","g4dn.4xlarge","g4dn.8xlarge","g4dn.12xlarge","g4dn.16xlarge","m5.large","m5.xlarge","m5.2xlarge","m5.4xlarge","m5.8xlarge","m5.12xlarge","m5.16xlarge","m5.24xlarge","m5a.large","m5a.xlarge","m5a.2xlarge","m5a.4xlarge","m5a.8xlarge","m5a.12xlarge","m5a.16xlarge","m5a.24xlarge"],m=[0,1,5,10,15,30,60];function C(e,r){return e.includes(r)}a(C,"constIncludes");const I=1,M=65535,D=Object.freeze({postgresql:5432,mysql:3306}),Y=128,L=10240,i=1,U=900,d=1,u=1e3,f=100,F=100,B=1,b=!1,G=3e3,X="t4g.micro",H=30,V=["GET","POST","PUT","DELETE","HEAD","OPTIONS","PATCH"],j=["standard","assets","upload","website"],z=["AES256","KMS"];import{BACKUP_VAULT_TIERS as xe}from"./sharedTypes.js";export{P as AMI_HARDWARE_TYPES,ae as APP_TYPES,xe as BACKUP_VAULT_TIERS,A as COMPUTE_ARCHITECTURES,o as COMPUTE_TYPE,E as COMPUTE_TYPES,te as CUSTOM_TIER,p as DATABASE_ENGINES,y as DATABASE_TYPES,x as DEFAULTS,R as DEFAULT_CAPACITY_PROVIDER,c as DEFAULT_COMPUTE_ARCHITECTURE,G as DEFAULT_CONTAINER_PORT,X as DEFAULT_EC2_INSTANCE_TYPE,H as DEFAULT_SECRET_ROTATION_DAYS,B as DEFAULT_WARM_POOL_MIN_SIZE,b as DEFAULT_WARM_POOL_REUSE_ON_SCALE_IN,Q as DEPLOYABLE_PATTERN_TYPES,T as DEPLOYMENT_TYPE,l as DEPLOYMENT_TYPES,N as EC2_INSTANCE_TYPES,Z as ECS_CAPACITY_PROVIDERS,D as ENGINE_DEFAULT_DATABASE_PORTS,_ as FUNCTION_URL_AUTH_TYPES,O as GOVERNANCE_PRESETS,V as HTTP_METHODS,n as LOAD_BALANCER_TYPES,u as MAX_ECS_CAPACITY,L as MAX_LAMBDA_MEMORY,U as MAX_LAMBDA_TIMEOUT,M as MAX_PORT,f as MAX_SCALING_CAPACITY,F as MAX_WARM_POOL_SIZE,d as MIN_ECS_CAPACITY,Y as MIN_LAMBDA_MEMORY,i as MIN_LAMBDA_TIMEOUT,I as MIN_PORT,$ as OPENNEXT_PATTERN_TYPES,S as PATTERN_DATABASE_TYPES,J as PATTERN_REGISTRY,k as PATTERN_TYPES,w as PATTERN_TYPE_VALUES,z as S3_ENCRYPTION_TYPES,s as SCALING_TYPES,j as STORAGE_PRESET_TYPES,m as VALID_MONITORING_INTERVALS,C as constIncludes,ee as isOpenNextPatternType,v as isPatternType};
1
+ var t=Object.defineProperty;var a=(e,r)=>t(e,"name",{value:r,configurable:!0});const x=Object.freeze({RESOURCE_SUFFIXES:Object.freeze({storage:"Storage",database:"Database",cluster:"Cluster",function:"Function",instance:"Instance",compute:"Compute"})});import{DATABASE_TYPES as w}from"./sharedTypes.js";const E=["ecs","lambda","ec2"],o=Object.freeze({ECS:"ecs",LAMBDA:"lambda",EC2:"ec2"}),l=["code","container"],T=Object.freeze({CODE:"code",CONTAINER:"container"}),A=["ARM_64","X86_64"],c="ARM_64",_=["NONE","AWS_IAM"],n=["public","internal"],s=["CPU","MEMORY"],P=["ARM","STANDARD"],S=["Instance","Aurora"],p=["postgresql","mysql"],R=["web","worker"],O=["foundation","compliance","hardened"];import{ECS_CAPACITY_PROVIDERS as Z}from"./sharedTypes.js";const C="FARGATE";import{PATTERN_TYPE_VALUES as k,PATTERN_TYPES as v,isPatternType as J,PATTERN_REGISTRY as Q,DEPLOYABLE_PATTERN_TYPES as $,OPENNEXT_PATTERN_TYPES as ee,isOpenNextPatternType as re}from"@fjall/util";import{APP_TYPES as te,CUSTOM_TIER as ge}from"./sharedTypes.js";const N=["t3.nano","t3.micro","t3.small","t3.medium","t3.large","t3.xlarge","t3.2xlarge","t3a.nano","t3a.micro","t3a.small","t3a.medium","t3a.large","t3a.xlarge","t3a.2xlarge","t4g.nano","t4g.micro","t4g.small","t4g.medium","t4g.large","t4g.xlarge","t4g.2xlarge","c5.large","c5.xlarge","c5.2xlarge","c5.4xlarge","c5.9xlarge","c5.12xlarge","c5.18xlarge","c5.24xlarge","c5a.large","c5a.xlarge","c5a.2xlarge","c5a.4xlarge","c5a.8xlarge","c5a.12xlarge","c5a.16xlarge","c5a.24xlarge","c6g.medium","c6g.large","c6g.xlarge","c6g.2xlarge","c6g.4xlarge","c6g.8xlarge","c6g.12xlarge","c6g.16xlarge","r5.large","r5.xlarge","r5.2xlarge","r5.4xlarge","r5.8xlarge","r5.12xlarge","r5.16xlarge","r5.24xlarge","r5a.large","r5a.xlarge","r5a.2xlarge","r5a.4xlarge","r5a.8xlarge","r5a.12xlarge","r5a.16xlarge","r5a.24xlarge","r6g.medium","r6g.large","r6g.xlarge","r6g.2xlarge","r6g.4xlarge","r6g.8xlarge","r6g.12xlarge","r6g.16xlarge","i3.large","i3.xlarge","i3.2xlarge","i3.4xlarge","i3.8xlarge","i3.16xlarge","p3.2xlarge","p3.8xlarge","p3.16xlarge","g4dn.xlarge","g4dn.2xlarge","g4dn.4xlarge","g4dn.8xlarge","g4dn.12xlarge","g4dn.16xlarge","m5.large","m5.xlarge","m5.2xlarge","m5.4xlarge","m5.8xlarge","m5.12xlarge","m5.16xlarge","m5.24xlarge","m5a.large","m5a.xlarge","m5a.2xlarge","m5a.4xlarge","m5a.8xlarge","m5a.12xlarge","m5a.16xlarge","m5a.24xlarge"],m=[0,1,5,10,15,30,60];function I(e,r){return e.includes(r)}a(I,"constIncludes");const M=1,D=65535,Y=Object.freeze({postgresql:5432,mysql:3306}),L=128,i=10240,U=1,d=900,u=1,f=1e3,F=100,b=100,B=1,G=!1,X=3e3,H="t4g.micro",V=30,j=["GET","POST","PUT","DELETE","HEAD","OPTIONS","PATCH"],z=["standard","assets","upload","website"],W=["AES256","KMS"];import{BACKUP_VAULT_TIERS as Ee}from"./sharedTypes.js";export{P as AMI_HARDWARE_TYPES,te as APP_TYPES,Ee as BACKUP_VAULT_TIERS,A as COMPUTE_ARCHITECTURES,o as COMPUTE_TYPE,E as COMPUTE_TYPES,ge as CUSTOM_TIER,p as DATABASE_ENGINES,w as DATABASE_TYPES,x as DEFAULTS,C as DEFAULT_CAPACITY_PROVIDER,c as DEFAULT_COMPUTE_ARCHITECTURE,X as DEFAULT_CONTAINER_PORT,H as DEFAULT_EC2_INSTANCE_TYPE,V as DEFAULT_SECRET_ROTATION_DAYS,B as DEFAULT_WARM_POOL_MIN_SIZE,G as DEFAULT_WARM_POOL_REUSE_ON_SCALE_IN,$ as DEPLOYABLE_PATTERN_TYPES,T as DEPLOYMENT_TYPE,l as DEPLOYMENT_TYPES,N as EC2_INSTANCE_TYPES,Z as ECS_CAPACITY_PROVIDERS,R as ECS_SERVICE_TYPES,Y as ENGINE_DEFAULT_DATABASE_PORTS,_ as FUNCTION_URL_AUTH_TYPES,O as GOVERNANCE_PRESETS,j as HTTP_METHODS,n as LOAD_BALANCER_TYPES,f as MAX_ECS_CAPACITY,i as MAX_LAMBDA_MEMORY,d as MAX_LAMBDA_TIMEOUT,D as MAX_PORT,F as MAX_SCALING_CAPACITY,b as MAX_WARM_POOL_SIZE,u as MIN_ECS_CAPACITY,L as MIN_LAMBDA_MEMORY,U as MIN_LAMBDA_TIMEOUT,M as MIN_PORT,ee as OPENNEXT_PATTERN_TYPES,S as PATTERN_DATABASE_TYPES,Q as PATTERN_REGISTRY,v as PATTERN_TYPES,k as PATTERN_TYPE_VALUES,W as S3_ENCRYPTION_TYPES,s as SCALING_TYPES,z as STORAGE_PRESET_TYPES,m as VALID_MONITORING_INTERVALS,I as constIncludes,re as isOpenNextPatternType,J as isPatternType};
@@ -1 +1 @@
1
- export declare const GENERATOR_VERSION = "9.0.0";
1
+ export declare const GENERATOR_VERSION = "10.1.2";
@@ -1 +1 @@
1
- const E="9.0.0";export{E as GENERATOR_VERSION};
1
+ const E="10.1.2";export{E as GENERATOR_VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/generator",
3
- "version": "9.0.0",
3
+ "version": "10.1.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fjall-tech/fjall.git",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "license": "SEE LICENSE IN LICENSE",
55
55
  "dependencies": {
56
- "@fjall/util": "^9.0.0",
56
+ "@fjall/util": "^10.1.2",
57
57
  "ast-types": "^0.16.1",
58
58
  "recast": "^0.23.12",
59
59
  "ts-morph": "^28.0.0",