@fjall/generator 8.0.0 → 10.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-source-hash +32 -29
- package/dist/.minified +1 -1
- package/dist/src/ast/astTestHelpers.d.ts +1 -0
- package/dist/src/ast/parsers/resources/astComputeParserHelpers.js +1 -1
- package/dist/src/codemod/edits/addResource.js +1 -1
- package/dist/src/codemod/edits/appendAccountToStage.js +1 -1
- package/dist/src/codemod/edits/computeServiceLocator.d.ts +65 -0
- package/dist/src/codemod/edits/computeServiceLocator.js +1 -0
- package/dist/src/codemod/edits/connectResourceToCompute.d.ts +65 -0
- package/dist/src/codemod/edits/connectResourceToCompute.js +1 -0
- package/dist/src/codemod/edits/modifyResource.js +1 -1
- package/dist/src/codemod/edits/moduleConstResolver.d.ts +1 -0
- package/dist/src/codemod/edits/moduleConstResolver.js +1 -1
- package/dist/src/codemod/edits/objectGraph.d.ts +6 -0
- package/dist/src/codemod/edits/objectGraph.js +1 -1
- package/dist/src/codemod/edits/setContainerSecrets.js +1 -1
- package/dist/src/codemod/emitGuard.d.ts +5 -6
- package/dist/src/codemod/index.d.ts +1 -0
- package/dist/src/codemod/index.js +1 -1
- package/dist/src/codemod/registry.d.ts +28 -7
- package/dist/src/codemod/registry.js +1 -1
- package/dist/src/codemod/types.d.ts +9 -1
- package/dist/src/codemod/types.js +1 -1
- package/dist/src/codemod/validationGate/gates/schema.js +1 -1
- package/dist/src/generation/common.d.ts +15 -0
- package/dist/src/generation/common.js +6 -6
- package/dist/src/generation/compute/ecs.js +14 -13
- package/dist/src/generation/database.d.ts +20 -0
- package/dist/src/generation/database.js +18 -18
- package/dist/src/generation/messagingConnections.js +1 -1
- package/dist/src/generation/storageConnections.d.ts +9 -0
- package/dist/src/generation/storageConnections.js +1 -1
- package/dist/src/planning/index.d.ts +2 -1
- package/dist/src/planning/index.js +1 -1
- package/dist/src/planning/planBuilders.d.ts +48 -0
- package/dist/src/planning/planBuilders.js +1 -0
- package/dist/src/planning/resourceAddition.d.ts +3 -0
- package/dist/src/planning/resourceAddition.js +1 -1
- package/dist/src/planning/resourcePlanning.js +1 -1
- package/dist/src/schemas/applicationSchemas.d.ts +4 -0
- package/dist/src/schemas/computeSchemas.d.ts +13 -1
- package/dist/src/schemas/computeSchemas.js +1 -1
- package/dist/src/schemas/constants.d.ts +2 -0
- package/dist/src/schemas/constants.js +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
var b=Object.defineProperty;var d=(a,e)=>b(a,"name",{value:e,configurable:!0});import{success as c,failure as u}from"../types/Result.js";import{toPascalCase as l}from"../generation/common.js";import{applyComputeConnections as y,applyServiceConnections as w}from"./resourceConnections.js";function
|
|
1
|
+
var b=Object.defineProperty;var d=(a,e)=>b(a,"name",{value:e,configurable:!0});import{success as c,failure as u}from"../types/Result.js";import{toPascalCase as l}from"../generation/common.js";import{applyComputeConnections as y,applyServiceConnections as w}from"./resourceConnections.js";function z(a){const e=a.database.length>0,n=a.cdn!==void 0;return[{type:"database",label:"Database (RDS)",available:!0},{type:"database:proxy",label:"RDS Proxy",available:e,reason:e?void 0:"Requires at least one database"},{type:"storage:s3",label:"S3 Bucket",available:!0},{type:"network",label:"Network (VPC)",available:!0},{type:"compute:ecs",label:"Compute (ECS)",available:!0},{type:"compute:lambda",label:"Compute (Lambda)",available:!0},{type:"cdn",label:"CDN (CloudFront)",available:!n,reason:n?"A CDN is already configured. Remove existing CDN first.":void 0},{type:"tunnel",label:"Database Tunnel",available:e&&!a.tunnel,reason:e?a.tunnel?"Tunnel is already enabled":void 0:"Requires at least one database"}]}d(z,"listAvailableResources");function g(a,e){if(S(a,e.resourceName))return u(new Error($(e.resourceName)));switch(e.type){case"database":return v(a,e);case"database:proxy":return h(a,e);case"storage:s3":return c(void 0);case"network":return c(void 0);case"compute:ecs":return!e.services||e.services.length===0?u(new Error("ECS compute requires at least one service.")):c(void 0);case"compute:lambda":return c(void 0);case"cdn":return C(a,e);case"tunnel":return R(a);default:{const n=e;return u(new Error(`Unknown resource type: ${String(n)}`))}}}d(g,"validateResourceAddition");function v(a,e){const n=e.databaseName??e.resourceName.toLowerCase();return a.database.some(t=>t.databaseName===n)?u(new Error(`Database name '${n}' already exists. Choose a different database name.`)):e.databaseType==="GlobalAurora"&&!e.primaryRegion?u(new Error("GlobalAurora databases require a primaryRegion.")):c(void 0)}d(v,"validateDatabaseAddition");function h(a,e){const n=a.database.find(r=>r.name===e.targetDatabase||r.databaseName===e.targetDatabase);if(!n){const r=a.database.map(t=>t.name).join(", ")||"none";return u(new Error(`Database '${e.targetDatabase}' not found. Available databases: ${r}`))}return n.proxy!==void 0&&n.proxy!==!1?u(new Error(`Database '${n.name}' already has RDS Proxy enabled.`)):c(void 0)}d(h,"validateProxyAddition");function C(a,e){if(a.cdn)return u(new Error("A CDN is already configured for this application. Remove the existing CDN first."));if(!f(a,e.defaultOriginRef))return u(new Error(`Origin '${e.defaultOriginRef}' not found in plan. CDN origin must reference an existing resource.`));if(e.behaviours){for(const n of e.behaviours)if(!f(a,n.originRef))return u(new Error(`Behaviour origin '${n.originRef}' not found in plan.`))}return c(void 0)}d(C,"validateCdnAddition");function R(a){return a.tunnel&&typeof a.tunnel=="object"?u(new Error("Tunnel is already enabled for this application.")):a.database.length===0?u(new Error("No databases found \u2014 tunnel requires at least one relational database.")):c(void 0)}d(R,"validateTunnelAddition");function O(a,e){const n=g(a,e);if(!n.success)return n;switch(e.type){case"database":return k(a,e);case"database:proxy":return x(a,e);case"storage:s3":return N(a,e);case"network":return D(a,e);case"compute:ecs":return A(a,e);case"compute:lambda":return T(a,e);case"cdn":return E(a,e);case"tunnel":return P(a,e);default:{const r=e;return u(new Error(`Unknown resource type: ${String(r)}`))}}}d(O,"addResourceToPlan");function k(a,e){const n=e.databaseName??e.resourceName.toLowerCase(),r={name:e.resourceName,type:e.databaseType,databaseName:n};let t;switch(e.databaseType){case"Instance":t={...r,...e.instanceType!==void 0?{instanceType:e.instanceType}:{},...e.multiAz!==void 0?{multiAz:e.multiAz}:{},...e.readReplica!==void 0?{readReplica:e.readReplica}:{},...e.publiclyAccessible!==void 0?{publiclyAccessible:e.publiclyAccessible}:{},...e.backupRetention!==void 0?{backupRetention:e.backupRetention}:{}};break;case"Aurora":t={...r,...e.writer!==void 0?{writer:e.writer}:{},...e.readers!==void 0?{readers:e.readers}:{},...e.backupRetention!==void 0?{backupRetention:e.backupRetention}:{},...e.preferredMaintenanceWindow!==void 0?{preferredMaintenanceWindow:e.preferredMaintenanceWindow}:{}};break;case"GlobalAurora":t={...r,primaryRegion:e.primaryRegion,...e.secondaryRegions!==void 0?{secondaryRegions:e.secondaryRegions}:{}};break;default:{const s=e.databaseType;return u(new Error(`Unknown database type: ${String(s)}`))}}const i={...a,database:[...a.database,t]};return o(i,e.resourceName,"database",e),c(i)}d(k,"addDatabase");function x(a,e){const n=a.database.map(i=>({...i})),r=n.find(i=>i.name===e.targetDatabase||i.databaseName===e.targetDatabase);if(!r)return u(new Error(`Database '${e.targetDatabase}' not found.`));const t={};return e.maxConnections!==void 0&&(t.maxConnections=e.maxConnections),e.maxIdleConnections!==void 0&&(t.maxIdleConnections=e.maxIdleConnections),e.connectionBorrowTimeout!==void 0&&(t.connectionBorrowTimeout=e.connectionBorrowTimeout),e.requireTLS!==void 0&&(t.requireTLS=e.requireTLS),r.proxy=Object.keys(t).length>0?t:{},c({...a,database:n})}d(x,"addProxy");function N(a,e){const n=e.bucketName??e.resourceName.toLowerCase(),r=l(n),t=a.s3.length,i=t===0?"":`${t+1}`,s={name:r,bucketName:n,variableName:`bucket${i}`,...e.publicReadAccess!==void 0?{publicReadAccess:e.publicReadAccess}:{},...e.versioned!==void 0?{versioned:e.versioned}:{},...e.encryption!==void 0?{encryption:e.encryption}:{},...e.websiteHosting?{websiteHosting:{indexDocument:"index.html"}}:{}},m={...a,s3:[...a.s3,s]};return o(m,r,"storage",e),c(m)}d(N,"addS3");function D(a,e){const n={};if(e.maxAzs!==void 0&&(n.maxAzs=e.maxAzs),e.natGateways!==void 0&&(n.natGateways=e.natGateways),e.flowLogs!==void 0&&(n.flowLogs=e.flowLogs),e.vpcEndpoints!==void 0&&(n.vpcEndpoints=e.vpcEndpoints),e.networkName){const r={name:e.networkName,...n};return c({...a,additionalNetworks:[...a.additionalNetworks??[],r]})}return c({...a,network:{...a.network??{},...n}})}d(D,"addNetwork");function A(a,e){const n=e.connectedDatabase??[],r={name:e.resourceName,type:"ecs",needsConnection:n.length>0,connectedDatabase:n,...e.loadBalancer!==void 0?{cluster:{loadBalancer:e.loadBalancer}}:{},services:e.services.map(t=>({name:t.name,capacityProvider:t.capacityProvider??"FARGATE",...t.port!==void 0?{containers:[{port:t.port}]}:{},...t.cpu!==void 0?{cpu:t.cpu}:{},...t.memory!==void 0?{memoryLimitMiB:t.memory}:{}})),...e.docker!==void 0&&{docker:e.docker}};return c({...a,compute:[...a.compute,r]})}d(A,"addEcsCompute");function T(a,e){const n=e.connectedDatabase??[],r={name:e.resourceName,type:"lambda",needsConnection:n.length>0,connectedDatabase:n,...e.timeout!==void 0?{timeout:e.timeout}:{},...e.memory!==void 0?{memory:e.memory}:{},...e.handler!==void 0?{handler:e.handler}:{},...e.runtime!==void 0?{runtime:e.runtime}:{}};return c({...a,compute:[...a.compute,r]})}d(T,"addLambdaCompute");function E(a,e){const n={name:e.resourceName,defaultOriginRef:e.defaultOriginRef,...e.customDomain!==void 0?{customDomain:e.customDomain}:{},...e.certificateArn!==void 0?{certificateArn:e.certificateArn}:{},...e.behaviours&&e.behaviours.length>0?{behaviours:[...e.behaviours].map(r=>({pathPattern:r.pathPattern,originRef:r.originRef,...r.cachePolicy!==void 0?{cachePolicy:r.cachePolicy}:{}}))}:{}};return c({...a,cdn:n})}d(E,"addCdn");function P(a,e){const n=e.instanceType?{instanceType:e.instanceType}:{};return c({...a,tunnel:n})}d(P,"addTunnel");function S(a,e){const n=[...a.database.map(r=>r.name),...(a.clickhouse??[]).map(r=>r.name),...a.s3.map(r=>r.name),...a.compute.map(r=>r.name),...(a.dynamodb??[]).map(r=>r.name),...(a.sqs??[]).map(r=>r.name),...(a.additionalNetworks??[]).map(r=>r.name)];return a.cdn&&n.push(a.cdn.name),n.includes(e)}d(S,"isResourceNameTaken");function $(a){return`Resource name '${a}' is already used in this application.`}d($,"resourceNameTakenMessage");function f(a,e){return a.database.some(n=>n.name===e)||a.s3.some(n=>n.name===e)||a.compute.some(n=>n.name===e)||(a.dynamodb??[]).some(n=>n.name===e)||(a.sqs??[]).some(n=>n.name===e)}d(f,"resourceExistsInPlan");function o(a,e,n,r){r.connectToCompute&&r.connectToCompute.length>0&&y(a,[...r.connectToCompute],e,n),r.connectToServices&&r.connectToServices.length>0&&w(a,[...r.connectToServices],e,n)}d(o,"applyConnections");export{O as addResourceToPlan,S as isResourceNameTaken,z as listAvailableResources,$ as resourceNameTakenMessage,g as validateResourceAddition};
|
|
@@ -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
|
|
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
|
|
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};
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const GENERATOR_VERSION = "
|
|
1
|
+
export declare const GENERATOR_VERSION = "10.1.1";
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const E="
|
|
1
|
+
const E="10.1.1";export{E as GENERATOR_VERSION};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/generator",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.1.1",
|
|
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": "^
|
|
56
|
+
"@fjall/util": "^10.1.1",
|
|
57
57
|
"ast-types": "^0.16.1",
|
|
58
58
|
"recast": "^0.23.12",
|
|
59
59
|
"ts-morph": "^28.0.0",
|