@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.
Files changed (47) hide show
  1. package/dist/.build-source-hash +32 -29
  2. package/dist/.minified +1 -1
  3. package/dist/src/ast/astTestHelpers.d.ts +1 -0
  4. package/dist/src/ast/parsers/resources/astComputeParserHelpers.js +1 -1
  5. package/dist/src/codemod/edits/addResource.js +1 -1
  6. package/dist/src/codemod/edits/appendAccountToStage.js +1 -1
  7. package/dist/src/codemod/edits/computeServiceLocator.d.ts +65 -0
  8. package/dist/src/codemod/edits/computeServiceLocator.js +1 -0
  9. package/dist/src/codemod/edits/connectResourceToCompute.d.ts +65 -0
  10. package/dist/src/codemod/edits/connectResourceToCompute.js +1 -0
  11. package/dist/src/codemod/edits/modifyResource.js +1 -1
  12. package/dist/src/codemod/edits/moduleConstResolver.d.ts +1 -0
  13. package/dist/src/codemod/edits/moduleConstResolver.js +1 -1
  14. package/dist/src/codemod/edits/objectGraph.d.ts +6 -0
  15. package/dist/src/codemod/edits/objectGraph.js +1 -1
  16. package/dist/src/codemod/edits/setContainerSecrets.js +1 -1
  17. package/dist/src/codemod/emitGuard.d.ts +5 -6
  18. package/dist/src/codemod/index.d.ts +1 -0
  19. package/dist/src/codemod/index.js +1 -1
  20. package/dist/src/codemod/registry.d.ts +28 -7
  21. package/dist/src/codemod/registry.js +1 -1
  22. package/dist/src/codemod/types.d.ts +9 -1
  23. package/dist/src/codemod/types.js +1 -1
  24. package/dist/src/codemod/validationGate/gates/schema.js +1 -1
  25. package/dist/src/generation/common.d.ts +15 -0
  26. package/dist/src/generation/common.js +6 -6
  27. package/dist/src/generation/compute/ecs.js +14 -13
  28. package/dist/src/generation/database.d.ts +20 -0
  29. package/dist/src/generation/database.js +18 -18
  30. package/dist/src/generation/messagingConnections.js +1 -1
  31. package/dist/src/generation/storageConnections.d.ts +9 -0
  32. package/dist/src/generation/storageConnections.js +1 -1
  33. package/dist/src/planning/index.d.ts +2 -1
  34. package/dist/src/planning/index.js +1 -1
  35. package/dist/src/planning/planBuilders.d.ts +48 -0
  36. package/dist/src/planning/planBuilders.js +1 -0
  37. package/dist/src/planning/resourceAddition.d.ts +3 -0
  38. package/dist/src/planning/resourceAddition.js +1 -1
  39. package/dist/src/planning/resourcePlanning.js +1 -1
  40. package/dist/src/schemas/applicationSchemas.d.ts +4 -0
  41. package/dist/src/schemas/computeSchemas.d.ts +13 -1
  42. package/dist/src/schemas/computeSchemas.js +1 -1
  43. package/dist/src/schemas/constants.d.ts +2 -0
  44. package/dist/src/schemas/constants.js +1 -1
  45. package/dist/src/version.d.ts +1 -1
  46. package/dist/src/version.js +1 -1
  47. package/package.json +2 -2
@@ -1 +1 @@
1
- import{addResource as o}from"./edits/addResource.js";import{removeResource as c}from"./edits/removeResource.js";import{modifyResource as m}from"./edits/modifyResource.js";import{appendAccountToStage as s}from"./edits/appendAccountToStage.js";import{setContainerSecrets as d}from"./edits/setContainerSecrets.js";import{addVpcPeer as i,modifyVpcPeer as l,removeVpcPeer as f}from"./edits/vpcPeer.js";import{addVpcPeerAccepter as P,modifyVpcPeerAccepter as x,removeVpcPeerAccepter as R}from"./edits/vpcPeerAccepter.js";import{addCrossPlanConnection as T,modifyCrossPlanConnection as v,removeCrossPlanConnection as A}from"./edits/crossPlanConnection.js";import{resolveDriftPolicy as V}from"./edits/driftPolicy.js";import{listResources as y}from"./listResources.js";import{resolveConstructByLiteralProperty as D}from"./semanticIndex/index.js";import{parse as N}from"./fileRewriter/parse.js";import{CrossPlanConnectionResourcePlanSchema as F,VpcPeerAccepterResourcePlanSchema as L,VpcPeerResourcePlanSchema as I}from"../schemas/index.js";import{detectDrift as O,mergeProperties as g,snapshotProperties as k}from"./drift/index.js";import{computeLinesDelta as U}from"./_internal.js";import{ResourceNameSchema as Y,StatementTypeSchema as j}from"./types.js";import{REGISTERED_STATEMENT_TYPES as w,STATEMENT_REGISTRY as z}from"./registry.js";import{evaluateEmitGuard as J,UNRESOLVED as Q}from"./emitGuard.js";import{CODEMOD_ERROR_KINDS as X}from"./telemetry/errorKinds.js";import{buildEgressBlockedEvent as $,buildFiredEvent as ee,buildGateFailedEvent as re,buildGatePassedEvent as oe,buildRejectedEvent as te,buildSucceededEvent as ce,buildTimeoutEvent as pe,estimateCostUsd as me,FALLBACK_EVENTS as ae,GATE_EVENTS as se,PARSE_GATE as ne,RUNTIME_GATE as de,runFallback as Ee,shouldTryFallback as ie}from"./llmFallback/index.js";export{X as CODEMOD_ERROR_KINDS,F as CrossPlanConnectionResourcePlanSchema,ae as FALLBACK_EVENTS,se as GATE_EVENTS,ne as PARSE_GATE,w as REGISTERED_STATEMENT_TYPES,de as RUNTIME_GATE,Y as ResourceNameSchema,z as STATEMENT_REGISTRY,j as StatementTypeSchema,Q as UNRESOLVED,L as VpcPeerAccepterResourcePlanSchema,I as VpcPeerResourcePlanSchema,T as addCrossPlanConnection,o as addResource,i as addVpcPeer,P as addVpcPeerAccepter,s as appendAccountToStage,$ as buildEgressBlockedEvent,ee as buildFiredEvent,re as buildGateFailedEvent,oe as buildGatePassedEvent,te as buildRejectedEvent,ce as buildSucceededEvent,pe as buildTimeoutEvent,U as computeLinesDelta,O as detectDrift,me as estimateCostUsd,J as evaluateEmitGuard,y as listResources,g as mergeProperties,v as modifyCrossPlanConnection,m as modifyResource,l as modifyVpcPeer,x as modifyVpcPeerAccepter,N as parse,A as removeCrossPlanConnection,c as removeResource,f as removeVpcPeer,R as removeVpcPeerAccepter,D as resolveConstructByLiteralProperty,V as resolveDriftPolicy,Ee as runFallback,d as setContainerSecrets,ie as shouldTryFallback,k as snapshotProperties};
1
+ import{addResource as o}from"./edits/addResource.js";import{removeResource as c}from"./edits/removeResource.js";import{modifyResource as m}from"./edits/modifyResource.js";import{appendAccountToStage as a}from"./edits/appendAccountToStage.js";import{setContainerSecrets as d}from"./edits/setContainerSecrets.js";import{connectResourceToCompute as i}from"./edits/connectResourceToCompute.js";import{addVpcPeer as f,modifyVpcPeer as u,removeVpcPeer as P}from"./edits/vpcPeer.js";import{addVpcPeerAccepter as R,modifyVpcPeerAccepter as T,removeVpcPeerAccepter as S}from"./edits/vpcPeerAccepter.js";import{addCrossPlanConnection as C,modifyCrossPlanConnection as A,removeCrossPlanConnection as V}from"./edits/crossPlanConnection.js";import{resolveDriftPolicy as y}from"./edits/driftPolicy.js";import{listResources as D}from"./listResources.js";import{resolveConstructByLiteralProperty as N}from"./semanticIndex/index.js";import{parse as F}from"./fileRewriter/parse.js";import{CrossPlanConnectionResourcePlanSchema as I,VpcPeerAccepterResourcePlanSchema as M,VpcPeerResourcePlanSchema as O}from"../schemas/index.js";import{detectDrift as k,mergeProperties as B,snapshotProperties as U}from"./drift/index.js";import{computeLinesDelta as Y}from"./_internal.js";import{ResourceNameSchema as q,StatementTypeSchema as w}from"./types.js";import{REGISTERED_STATEMENT_TYPES as H,STATEMENT_REGISTRY as J}from"./registry.js";import{evaluateEmitGuard as W,UNRESOLVED as X}from"./emitGuard.js";import{CODEMOD_ERROR_KINDS as $}from"./telemetry/errorKinds.js";import{buildEgressBlockedEvent as re,buildFiredEvent as oe,buildGateFailedEvent as te,buildGatePassedEvent as ce,buildRejectedEvent as pe,buildSucceededEvent as me,buildTimeoutEvent as se,estimateCostUsd as ae,FALLBACK_EVENTS as ne,GATE_EVENTS as de,PARSE_GATE as Ee,RUNTIME_GATE as ie,runFallback as le,shouldTryFallback as fe}from"./llmFallback/index.js";export{$ as CODEMOD_ERROR_KINDS,I as CrossPlanConnectionResourcePlanSchema,ne as FALLBACK_EVENTS,de as GATE_EVENTS,Ee as PARSE_GATE,H as REGISTERED_STATEMENT_TYPES,ie as RUNTIME_GATE,q as ResourceNameSchema,J as STATEMENT_REGISTRY,w as StatementTypeSchema,X as UNRESOLVED,M as VpcPeerAccepterResourcePlanSchema,O as VpcPeerResourcePlanSchema,C as addCrossPlanConnection,o as addResource,f as addVpcPeer,R as addVpcPeerAccepter,a as appendAccountToStage,re as buildEgressBlockedEvent,oe as buildFiredEvent,te as buildGateFailedEvent,ce as buildGatePassedEvent,pe as buildRejectedEvent,me as buildSucceededEvent,se as buildTimeoutEvent,Y as computeLinesDelta,i as connectResourceToCompute,k as detectDrift,ae as estimateCostUsd,W as evaluateEmitGuard,D as listResources,B as mergeProperties,A as modifyCrossPlanConnection,m as modifyResource,u as modifyVpcPeer,T as modifyVpcPeerAccepter,F as parse,V as removeCrossPlanConnection,c as removeResource,P as removeVpcPeer,S as removeVpcPeerAccepter,N as resolveConstructByLiteralProperty,y as resolveDriftPolicy,le as runFallback,d as setContainerSecrets,fe as shouldTryFallback,U as snapshotProperties};
@@ -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
@@ -99,7 +121,7 @@ export interface StatementTypeEntry {
99
121
  */
100
122
  emitGuard?: ReadonlyArray<EmitGuardRule>;
101
123
  }
102
- declare const FACTORY_IDENTIFIERS: {
124
+ export declare const FACTORY_IDENTIFIERS: {
103
125
  readonly database: "DatabaseFactory";
104
126
  readonly storage: "StorageFactory";
105
127
  readonly compute: "ComputeFactory";
@@ -125,4 +147,3 @@ export declare const STATEMENT_REGISTRY: Record<StatementType, StatementTypeEntr
125
147
  */
126
148
  export declare const REGISTERED_STATEMENT_TYPES: ReadonlyArray<StatementType>;
127
149
  export declare function findTypeByIdentifier(identifier: string): StatementType | undefined;
128
- export {};
@@ -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 O,VpcPeerResourcePlanSchema as W}from"../schemas/index.js";import{failure as x}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(W),U=s(O),z=s(T),H=s(F),Q=s(v);function l(e,t){return x({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{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,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { ResourceNameSchema } from "../schemas/baseSchemas.js";
2
3
  import type { GateId } from "./validationGate/types.js";
3
4
  import type { EgressRiskReason } from "./llmFallback/egressGate.types.js";
4
5
  export declare const DriftPolicySchema: z.ZodObject<{
@@ -26,7 +27,14 @@ export declare const StatementTypeSchema: z.ZodEnum<{
26
27
  buildkite: "buildkite";
27
28
  }>;
28
29
  export type StatementType = z.infer<typeof StatementTypeSchema>;
29
- export declare const ResourceNameSchema: z.ZodString;
30
+ /**
31
+ * The scaffold's shared resource-name vocabulary (lowercase-leading factory
32
+ * names included: interactive adds use `resourceName = databaseName`, the
33
+ * default is `${appName}Database`). Re-exported from the canonical schema so
34
+ * the codemod's add/modify/remove gates cannot drift from the generator's
35
+ * validation.
36
+ */
37
+ export { ResourceNameSchema };
30
38
  export type ResourceName = z.infer<typeof ResourceNameSchema>;
31
39
  export declare const AddOptionsSchema: z.ZodObject<{
32
40
  type: z.ZodEnum<{
@@ -1 +1 @@
1
- import{z as t}from"zod";import{VALIDATION_MESSAGES as i,VALIDATION_PATTERNS as c}from"../validation/patterns.js";const o=t.object({force:t.boolean().optional(),resolutionMap:t.record(t.string(),t.unknown()).optional()}).strict(),e=t.enum(["database","storage","compute","messaging","cdn","network","pattern","vpc-peer","vpc-peer-accepter","cross-plan-connection","organisation","buildkite"]),n=t.string().regex(c.PASCAL_CASE,i.PASCAL_CASE),r=t.record(t.string(),t.unknown()),g=t.object({type:e,name:n,properties:r,filePath:t.string().optional(),driftPolicy:o.optional(),branch:t.string().optional()}).strict(),b=t.object({type:e,name:n,filePath:t.string().optional(),force:t.boolean().optional(),branch:t.string().optional()}).strict(),h=t.object({type:e,name:n,properties:r,filePath:t.string().optional(),driftPolicy:o.optional(),branch:t.string().optional()}).strict(),a=t.object({line:t.number().int().positive(),column:t.number().int().positive(),context:t.string()}).strict(),s=t.object({added:t.number().int().nonnegative(),removed:t.number().int().nonnegative()}).strict(),p=t.object({type:e,name:t.string(),filePath:t.string(),start:t.number().int().nonnegative(),length:t.number().int().nonnegative(),managed:t.literal(!1).optional()}).strict(),u=t.object({filePath:t.string(),resources:t.array(p)}).strict(),S=t.object({content:t.string(),linesChanged:s,references:t.array(a).optional(),warnings:t.array(t.string()).optional()}).strict(),d=t.object({property:t.string(),base:t.unknown().optional(),theirs:t.unknown(),ours:t.unknown(),verdict:t.enum(["clean","no-op","compatible","conflict"])}).strict();export{g as AddOptionsSchema,S as CodemodSuccessSchema,o as DriftPolicySchema,s as LinesChangedSchema,h as ModifyOptionsSchema,d as PropertyDeltaSchema,a as ReferenceLocationSchema,b as RemoveOptionsSchema,p as ResourceListingEntrySchema,u as ResourceListingSchema,n as ResourceNameSchema,e as StatementTypeSchema};
1
+ import{z as t}from"zod";import{ResourceNameSchema as e}from"../schemas/baseSchemas.js";const o=t.object({force:t.boolean().optional(),resolutionMap:t.record(t.string(),t.unknown()).optional()}).strict(),n=t.enum(["database","storage","compute","messaging","cdn","network","pattern","vpc-peer","vpc-peer-accepter","cross-plan-connection","organisation","buildkite"]),r=t.record(t.string(),t.unknown()),l=t.object({type:n,name:e,properties:r,filePath:t.string().optional(),driftPolicy:o.optional(),branch:t.string().optional()}).strict(),m=t.object({type:n,name:e,filePath:t.string().optional(),force:t.boolean().optional(),branch:t.string().optional()}).strict(),g=t.object({type:n,name:e,properties:r,filePath:t.string().optional(),driftPolicy:o.optional(),branch:t.string().optional()}).strict(),i=t.object({line:t.number().int().positive(),column:t.number().int().positive(),context:t.string()}).strict(),c=t.object({added:t.number().int().nonnegative(),removed:t.number().int().nonnegative()}).strict(),a=t.object({type:n,name:t.string(),filePath:t.string(),start:t.number().int().nonnegative(),length:t.number().int().nonnegative(),managed:t.literal(!1).optional()}).strict(),b=t.object({filePath:t.string(),resources:t.array(a)}).strict(),h=t.object({content:t.string(),linesChanged:c,references:t.array(i).optional(),warnings:t.array(t.string()).optional()}).strict(),u=t.object({property:t.string(),base:t.unknown().optional(),theirs:t.unknown(),ours:t.unknown(),verdict:t.enum(["clean","no-op","compatible","conflict"])}).strict();export{l as AddOptionsSchema,h as CodemodSuccessSchema,o as DriftPolicySchema,c as LinesChangedSchema,g as ModifyOptionsSchema,u as PropertyDeltaSchema,i as ReferenceLocationSchema,m as RemoveOptionsSchema,a as ResourceListingEntrySchema,b as ResourceListingSchema,e as ResourceNameSchema,n as StatementTypeSchema};
@@ -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};
@@ -29,6 +29,21 @@ export declare function formatStringArray(values: readonly string[]): string;
29
29
  */
30
30
  export declare const PRODUCTION_ALERTS_TOPIC_IMPORT = "import:SharedAlarmTopicArn";
31
31
  export declare function emitProductionAlertsTopicSpread(indent?: string): string;
32
+ /**
33
+ * The `_N` connection env-key suffix scheme, shared by every connection
34
+ * emitter (database, storage, messaging) AND the codemod connection edit
35
+ * (`codemod/edits/connectResourceToCompute.ts`): the first connection of a
36
+ * type gets no suffix, the Nth gets `_N`. `index` is zero-based position.
37
+ * Drift between the two lanes silently desynchronises surgically-wired env
38
+ * keys from regenerated ones.
39
+ */
40
+ export declare function connectionEnvSuffix(index: number): string;
41
+ /**
42
+ * Inverse of {@link connectionEnvSuffix}: the 1-based ordinal a key encodes
43
+ * for `base` (`DATABASE_HOST` → 1, `DATABASE_HOST_2` → 2), or `undefined`
44
+ * when the key does not belong to that base's suffix scheme.
45
+ */
46
+ export declare function connectionKeyOrdinal(key: string, base: string): number | undefined;
32
47
  /**
33
48
  * Type guard to check if a value is a special code generation value
34
49
  */
@@ -1,8 +1,8 @@
1
- var u=Object.defineProperty;var n=(e,t)=>u(e,"name",{value:t,configurable:!0});import{toPascalCase as P,toKebab as T,toValidDatabaseName as h}from"@fjall/util";function c(e){return JSON.stringify(e)}n(c,"escapeStringLiteral");function g(e){return e.map(c).join(", ")}n(g,"formatStringArray");const b="import:SharedAlarmTopicArn";function _(e=" "){return`
2
- ${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(b)} } : {}),`}n(_,"emitProductionAlertsTopicSpread");function l(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.__identifier=="string"||typeof t.__expression=="string"||typeof t.__call=="string"}n(l,"isSpecialValue");function m(e){return e.replace(/[^a-zA-Z0-9]/g," ").split(" ").map((t,r)=>r===0?t.charAt(0).toLowerCase()+t.slice(1):t.charAt(0).toUpperCase()+t.slice(1)).join("")}n(m,"toVariableName");function $(e){return e.variableName??m(e.name)}n($,"getVariableName");function x(e,t){for(const r of e.database)if(r.name===t&&r.variableName)return r.variableName;for(const r of e.s3)if(r.name===t&&r.variableName)return r.variableName;for(const r of e.compute)if(r.name===t&&r.variableName)return r.variableName;for(const r of e.dynamodb??[])if(r.name===t&&r.variableName)return r.variableName;for(const r of e.sqs??[])if(r.name===t&&r.variableName)return r.variableName;return m(t)}n(x,"resolveResourceVariable");function d(e){const t=Object.entries(e);return t.length===0?!0:t.length>1?!1:t.every(([,r])=>typeof r=="string"||typeof r=="number"||typeof r=="boolean"||r===null)}n(d,"isSimpleObject");function f(e,t=" "){if(e==null)return"undefined";if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(l(e)){if("__identifier"in e)return e.__identifier;if("__expression"in e)return e.__expression;if("__call"in e)return e.__call}if(Array.isArray(e))return`[${e.map(r=>f(r,t)).join(", ")}]`;if(typeof e=="object"){const r=Object.entries(e).filter(([,a])=>a!==void 0);if(d(e)){const a=r.map(([s,p])=>`${s}: ${f(p,t)}`).join(", ");return a?`{ ${a} }`:"{}"}const o=t+" ",i=r.map(([a,s])=>`${o}${a}: ${f(s,o)}`).join(`,
1
+ var m=Object.defineProperty;var n=(e,r)=>m(e,"name",{value:r,configurable:!0});import{toPascalCase as T,toKebab as V,toValidDatabaseName as C}from"@fjall/util";function c(e){return JSON.stringify(e)}n(c,"escapeStringLiteral");function _(e){return e.map(c).join(", ")}n(_,"formatStringArray");const l="import:SharedAlarmTopicArn";function $(e=" "){return`
2
+ ${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(l)} } : {}),`}n($,"emitProductionAlertsTopicSpread");function y(e){return e===0?"":`_${String(e+1)}`}n(y,"connectionEnvSuffix");function x(e,r){if(e===r)return 1;if(!e.startsWith(`${r}_`))return;const t=e.slice(r.length+1);return/^\d+$/.test(t)?parseInt(t,10):void 0}n(x,"connectionKeyOrdinal");function b(e){if(typeof e!="object"||e===null)return!1;const r=e;return typeof r.__identifier=="string"||typeof r.__expression=="string"||typeof r.__call=="string"}n(b,"isSpecialValue");function u(e){return e.replace(/[^a-zA-Z0-9]/g," ").split(" ").map((r,t)=>t===0?r.charAt(0).toLowerCase()+r.slice(1):r.charAt(0).toUpperCase()+r.slice(1)).join("")}n(u,"toVariableName");function j(e){return e.variableName??u(e.name)}n(j,"getVariableName");function S(e,r){for(const t of e.database)if(t.name===r&&t.variableName)return t.variableName;for(const t of e.s3)if(t.name===r&&t.variableName)return t.variableName;for(const t of e.compute)if(t.name===r&&t.variableName)return t.variableName;for(const t of e.dynamodb??[])if(t.name===r&&t.variableName)return t.variableName;for(const t of e.sqs??[])if(t.name===r&&t.variableName)return t.variableName;return u(r)}n(S,"resolveResourceVariable");function d(e){const r=Object.entries(e);return r.length===0?!0:r.length>1?!1:r.every(([,t])=>typeof t=="string"||typeof t=="number"||typeof t=="boolean"||t===null)}n(d,"isSimpleObject");function a(e,r=" "){if(e==null)return"undefined";if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(b(e)){if("__identifier"in e)return e.__identifier;if("__expression"in e)return e.__expression;if("__call"in e)return e.__call}if(Array.isArray(e))return`[${e.map(t=>a(t,r)).join(", ")}]`;if(typeof e=="object"){const t=Object.entries(e).filter(([,f])=>f!==void 0);if(d(e)){const f=t.map(([s,p])=>`${s}: ${a(p,r)}`).join(", ");return f?`{ ${f} }`:"{}"}const o=r+" ",i=t.map(([f,s])=>`${o}${f}: ${a(s,o)}`).join(`,
3
3
  `);return i?`{
4
4
  ${i}
5
- ${t}}`:"{}"}return JSON.stringify(e)}n(f,"formatValue");function j(e,t=" "){return e.map(r=>{const o=r.value.kind==="expression"?r.value.source:f(r.value.value,t);return`
6
- ${t}${r.key}: ${o}`}).join(",")}n(j,"emitProjectedProps");function N(e,t,r,o="raw"){if(!e)return"";let i;switch(o){case"string":i=c(String(r));break;case"object":i=f(r);break;case"boolean-or-object":i=r===!1?"false":f(r);break;default:i=String(r)}return`
7
- ${t}: ${i},`}n(N,"buildProperty");function S(e,t=" "){return e?.length?e.map(r=>`
8
- ${t}${r.key}: ${r.sourceText},`).join(""):""}n(S,"emitExtraProperties");export{b as PRODUCTION_ALERTS_TOPIC_IMPORT,N as buildProperty,S as emitExtraProperties,_ as emitProductionAlertsTopicSpread,j as emitProjectedProps,c as escapeStringLiteral,g as formatStringArray,f as formatValue,$ as getVariableName,l as isSpecialValue,x as resolveResourceVariable,T as toKebab,P as toPascalCase,h as toValidDatabaseName,m as toVariableName};
5
+ ${r}}`:"{}"}return JSON.stringify(e)}n(a,"formatValue");function N(e,r=" "){return e.map(t=>{const o=t.value.kind==="expression"?t.value.source:a(t.value.value,r);return`
6
+ ${r}${t.key}: ${o}`}).join(",")}n(N,"emitProjectedProps");function O(e,r,t,o="raw"){if(!e)return"";let i;switch(o){case"string":i=c(String(t));break;case"object":i=a(t);break;case"boolean-or-object":i=t===!1?"false":a(t);break;default:i=String(t)}return`
7
+ ${r}: ${i},`}n(O,"buildProperty");function A(e,r=" "){return e?.length?e.map(t=>`
8
+ ${r}${t.key}: ${t.sourceText},`).join(""):""}n(A,"emitExtraProperties");export{l as PRODUCTION_ALERTS_TOPIC_IMPORT,O as buildProperty,y as connectionEnvSuffix,x as connectionKeyOrdinal,A as emitExtraProperties,$ as emitProductionAlertsTopicSpread,N as emitProjectedProps,c as escapeStringLiteral,_ as formatStringArray,a as formatValue,j as getVariableName,b as isSpecialValue,S as resolveResourceVariable,V as toKebab,T as toPascalCase,C as toValidDatabaseName,u as toVariableName};
@@ -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};
@@ -17,6 +17,26 @@ export declare const CREDENTIAL_KEYS: Readonly<{
17
17
  readonly USERNAME: "username";
18
18
  readonly PASSWORD: "password";
19
19
  }>;
20
+ /**
21
+ * The literal value emitted for `DATABASE_SSL`. Shared with the codemod
22
+ * connection edit (`codemod/edits/connectResourceToCompute.ts`) — the two
23
+ * emitters must write the same byte or surgically-wired apps diverge from
24
+ * regenerated ones.
25
+ */
26
+ export declare const DATABASE_SSL_VALUE = "true";
27
+ /**
28
+ * Construct accessor methods the emitted connection wiring calls on a bound
29
+ * database variable. Shared with the codemod connection edit
30
+ * (`codemod/edits/connectResourceToCompute.ts`) — the two emitters must call
31
+ * identical methods or surgically-wired apps fail at synth.
32
+ */
33
+ export declare const DATABASE_ACCESSORS: Readonly<{
34
+ readonly HOST: "getHostEndpoint";
35
+ readonly PORT: "getHostPort";
36
+ readonly NAME: "getDatabaseName";
37
+ readonly CREDENTIALS: "getCredentials";
38
+ readonly IMPORT: "getImport";
39
+ }>;
20
40
  export type DatabaseEnvVarEntry = {
21
41
  key: string;
22
42
  expression: string;
@@ -1,26 +1,26 @@
1
- var b=Object.defineProperty;var s=(e,n)=>b(e,"name",{value:n,configurable:!0});import{buildProperty as o,formatValue as p,getVariableName as f,emitExtraProperties as A,escapeStringLiteral as u,formatStringArray as y,emitProductionAlertsTopicSpread as m}from"./common.js";const l=Object.freeze({HOST:"DATABASE_HOST",PORT:"DATABASE_PORT",NAME:"DATABASE_NAME",SSL:"DATABASE_SSL",USERNAME:"DATABASE_USERNAME",PASSWORD:"DATABASE_PASSWORD"}),g=Object.freeze({USERNAME:"username",PASSWORD:"password"});function E(e,n){const r=n.connectedDatabase;return r?.length?e.database.filter(t=>r.includes(t.name)):[]}s(E,"getConnectedDatabases");function S(e,n){return`${e}.getCredentials().getImport(${u(n)})`}s(S,"getCredentialExpression");function $(e){const n=[],r=s((t,a,c)=>{n.push({key:t,expression:a,isSecret:c})},"addEntry");if(e.length===1){const t=f(e[0]);r(l.HOST,`${t}.getHostEndpoint()`,!1),r(l.PORT,`${t}.getHostPort()`,!1),r(l.NAME,`${t}.getDatabaseName()`,!1),r(l.SSL,'"true"',!1),r(l.USERNAME,S(t,g.USERNAME),!0),r(l.PASSWORD,S(t,g.PASSWORD),!0)}else for(const[t,a]of e.entries()){const c=f(a),i=t===0?"":`_${t+1}`;r(`${l.HOST}${i}`,`${c}.getHostEndpoint()`,!1),r(`${l.PORT}${i}`,`${c}.getHostPort()`,!1),r(`${l.NAME}${i}`,`${c}.getDatabaseName()`,!1),r(`${l.SSL}${i}`,'"true"',!1),r(`${l.USERNAME}${i}`,S(c,g.USERNAME),!0),r(`${l.PASSWORD}${i}`,S(c,g.PASSWORD),!0)}return n}s($,"generateDatabaseEnvVarEntries");function O(e){return`connections: [${e.map(r=>f(r)).join(", ")}],`}s(O,"formatConnectionsCode");function R(e){return e.expression==='"true"'?"true":{__expression:e.expression}}s(R,"toDatabaseEnvVarValue");function V(e,n){const r={},t={};if(!n.needsConnection||!n.connectedDatabase?.length)return{env:r,secrets:t};const a=E(e,n),c=$(a);for(const i of c){const d=R(i);i.isSecret?t[i.key]={__expression:i.expression}:r[i.key]=d}return{env:r,secrets:t}}s(V,"buildDatabaseEnvVars");function h(e){let n="";return n+=o(e.port!==void 0,"port",e.port),n+=o(e.deletionProtection!==void 0,"deletionProtection",e.deletionProtection),n+=o(e.snapshotIdentifier!==void 0,"snapshotIdentifier",e.snapshotIdentifier,"string"),n+=o(e.snapshotUsername!==void 0,"snapshotUsername",e.snapshotUsername,"string"),n+=o(e.monitoringInterval!==void 0,"monitoringInterval",e.monitoringInterval),n}s(h,"generateDatabaseSharedProps");function D(e){if(e.type!=="Instance")return"";let n="";return n+=o(e.instanceType!==void 0,"instanceType",e.instanceType,"string"),n+=o(e.allocatedStorage!==void 0,"allocatedStorage",e.allocatedStorage),n+=o(e.multiAz!==void 0,"multiAz",e.multiAz),n+=o(e.publiclyAccessible!==void 0,"publiclyAccessible",e.publiclyAccessible),n+=o(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=o(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=o(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=o(e.readReplica!==void 0,"readReplica",e.readReplica,"boolean-or-object"),n+=o(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=o(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n}s(D,"generateDatabaseInstanceProps");function x(e){if(e.type!=="Aurora"&&e.type!=="GlobalAurora")return"";let n="";return n+=o(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=o(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=o(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=o(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=o(e.writer!==void 0,"writer",e.writer,"object"),n+=o(e.readers!==void 0,"readers",e.readers,"boolean-or-object"),n+=o(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n+=o(e.preferredMaintenanceWindow!==void 0,"preferredMaintenanceWindow",e.preferredMaintenanceWindow,"string"),n}s(x,"generateDatabaseAuroraProps");function N(e){if(e.type!=="GlobalAurora")return"";let n="";return n+=o(e.primaryRegion!==void 0,"primaryRegion",e.primaryRegion,"string"),e.secondaryRegions!==void 0&&e.secondaryRegions.length>0&&(n+=`
2
- secondaryRegions: [${y(e.secondaryRegions)}],`),n+=o(e.globalClusterIdentifier!==void 0,"globalClusterIdentifier",e.globalClusterIdentifier,"string"),n+=o(e.enableGlobalWriteForwarding!==void 0,"enableGlobalWriteForwarding",e.enableGlobalWriteForwarding),n}s(N,"generateDatabaseGlobalAuroraProps");function T(e,n){return n.compute.some(r=>r.needsConnection&&r.connectedDatabase?.includes(e.name))}s(T,"databaseNeedsVariable");function j(e){if(e.database.length===0)return"";let n="";for(let r=0;r<e.database.length;r++){const t=e.database[r],a=f(t),c=T(t,e),i=r>0,d=c?`const ${a} = `:"";n+=`${i?`
3
- `:""}${d}app.addDatabase(
4
- DatabaseFactory.build(${u(t.name)}, {
1
+ var $=Object.defineProperty;var c=(e,n)=>$(e,"name",{value:n,configurable:!0});import{buildProperty as o,connectionEnvSuffix as y,formatValue as S,getVariableName as p,emitExtraProperties as b,escapeStringLiteral as a,formatStringArray as R,emitProductionAlertsTopicSpread as m}from"./common.js";const l=Object.freeze({HOST:"DATABASE_HOST",PORT:"DATABASE_PORT",NAME:"DATABASE_NAME",SSL:"DATABASE_SSL",USERNAME:"DATABASE_USERNAME",PASSWORD:"DATABASE_PASSWORD"}),A=Object.freeze({USERNAME:"username",PASSWORD:"password"}),g="true",u=Object.freeze({HOST:"getHostEndpoint",PORT:"getHostPort",NAME:"getDatabaseName",CREDENTIALS:"getCredentials",IMPORT:"getImport"});function D(e,n){const r=n.connectedDatabase;return r?.length?e.database.filter(t=>r.includes(t.name)):[]}c(D,"getConnectedDatabases");function E(e,n){return`${e}.${u.CREDENTIALS}().${u.IMPORT}(${a(n)})`}c(E,"getCredentialExpression");function T(e){const n=[],r=c((t,d,s)=>{n.push({key:t,expression:d,isSecret:s})},"addEntry");if(e.length===1){const t=p(e[0]);r(l.HOST,`${t}.${u.HOST}()`,!1),r(l.PORT,`${t}.${u.PORT}()`,!1),r(l.NAME,`${t}.${u.NAME}()`,!1),r(l.SSL,a(g),!1),r(l.USERNAME,E(t,A.USERNAME),!0),r(l.PASSWORD,E(t,A.PASSWORD),!0)}else for(const[t,d]of e.entries()){const s=p(d),i=y(t);r(`${l.HOST}${i}`,`${s}.${u.HOST}()`,!1),r(`${l.PORT}${i}`,`${s}.${u.PORT}()`,!1),r(`${l.NAME}${i}`,`${s}.${u.NAME}()`,!1),r(`${l.SSL}${i}`,a(g),!1),r(`${l.USERNAME}${i}`,E(s,A.USERNAME),!0),r(`${l.PASSWORD}${i}`,E(s,A.PASSWORD),!0)}return n}c(T,"generateDatabaseEnvVarEntries");function j(e){return`connections: [${e.map(r=>p(r)).join(", ")}],`}c(j,"formatConnectionsCode");function h(e){return e.expression===a(g)?g:{__expression:e.expression}}c(h,"toDatabaseEnvVarValue");function _(e,n){const r={},t={};if(!n.needsConnection||!n.connectedDatabase?.length)return{env:r,secrets:t};const d=D(e,n),s=T(d);for(const i of s){const f=h(i);i.isSecret?t[i.key]={__expression:i.expression}:r[i.key]=f}return{env:r,secrets:t}}c(_,"buildDatabaseEnvVars");function x(e){let n="";return n+=o(e.port!==void 0,"port",e.port),n+=o(e.deletionProtection!==void 0,"deletionProtection",e.deletionProtection),n+=o(e.snapshotIdentifier!==void 0,"snapshotIdentifier",e.snapshotIdentifier,"string"),n+=o(e.snapshotUsername!==void 0,"snapshotUsername",e.snapshotUsername,"string"),n+=o(e.monitoringInterval!==void 0,"monitoringInterval",e.monitoringInterval),n}c(x,"generateDatabaseSharedProps");function N(e){if(e.type!=="Instance")return"";let n="";return n+=o(e.instanceType!==void 0,"instanceType",e.instanceType,"string"),n+=o(e.allocatedStorage!==void 0,"allocatedStorage",e.allocatedStorage),n+=o(e.multiAz!==void 0,"multiAz",e.multiAz),n+=o(e.publiclyAccessible!==void 0,"publiclyAccessible",e.publiclyAccessible),n+=o(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=o(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=o(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=o(e.readReplica!==void 0,"readReplica",e.readReplica,"boolean-or-object"),n+=o(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=o(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n}c(N,"generateDatabaseInstanceProps");function P(e){if(e.type!=="Aurora"&&e.type!=="GlobalAurora")return"";let n="";return n+=o(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=o(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=o(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=o(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=o(e.writer!==void 0,"writer",e.writer,"object"),n+=o(e.readers!==void 0,"readers",e.readers,"boolean-or-object"),n+=o(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n+=o(e.preferredMaintenanceWindow!==void 0,"preferredMaintenanceWindow",e.preferredMaintenanceWindow,"string"),n}c(P,"generateDatabaseAuroraProps");function O(e){if(e.type!=="GlobalAurora")return"";let n="";return n+=o(e.primaryRegion!==void 0,"primaryRegion",e.primaryRegion,"string"),e.secondaryRegions!==void 0&&e.secondaryRegions.length>0&&(n+=`
2
+ secondaryRegions: [${R(e.secondaryRegions)}],`),n+=o(e.globalClusterIdentifier!==void 0,"globalClusterIdentifier",e.globalClusterIdentifier,"string"),n+=o(e.enableGlobalWriteForwarding!==void 0,"enableGlobalWriteForwarding",e.enableGlobalWriteForwarding),n}c(O,"generateDatabaseGlobalAuroraProps");function I(e,n){return n.compute.some(r=>r.needsConnection&&r.connectedDatabase?.includes(e.name))}c(I,"databaseNeedsVariable");function w(e){if(e.database.length===0)return"";let n="";for(let r=0;r<e.database.length;r++){const t=e.database[r],d=p(t),s=I(t,e),i=r>0,f=s?`const ${d} = `:"";n+=`${i?`
3
+ `:""}${f}app.addDatabase(
4
+ DatabaseFactory.build(${a(t.name)}, {
5
5
  vpc: app.getVpc(),
6
- type: ${u(t.type)},
7
- databaseName: ${u(t.databaseName)},`,t.engineExpression?n+=`
6
+ type: ${a(t.type)},
7
+ databaseName: ${a(t.databaseName)},`,t.engineExpression?n+=`
8
8
  engine: ${t.engineExpression},`:t.databaseEngine&&(n+=`
9
- databaseEngine: ${u(t.databaseEngine)},`),n+=h(t),n+=D(t),n+=x(t),n+=N(t),n+=A(t.extraProperties),t.alarms===!1?n+=`
9
+ databaseEngine: ${a(t.databaseEngine)},`),n+=x(t),n+=N(t),n+=P(t),n+=O(t),n+=b(t.extraProperties),t.alarms===!1?n+=`
10
10
  alarms: false,`:typeof t.alarms=="object"&&(n+=`
11
- alarms: ${p(t.alarms," ")},`),t.type!=="GlobalAurora"&&(n+=m()),n+=`
11
+ alarms: ${S(t.alarms," ")},`),t.type!=="GlobalAurora"&&(n+=m()),n+=`
12
12
  })
13
13
  );
14
- `}return n}s(j,"generateDatabaseCode");function w(e){if(!e.clickhouse||e.clickhouse.length===0)return"";let n="";for(let r=0;r<e.clickhouse.length;r++){const t=e.clickhouse[r],a=f(t),c=P(t,e),i=r>0?`
15
- `:"",d=c?`const ${a} = `:"";n+=`${i}${d}app.addDatabase(
16
- DatabaseFactory.build(${u(t.name)}, {
14
+ `}return n}c(w,"generateDatabaseCode");function W(e){if(!e.clickhouse||e.clickhouse.length===0)return"";let n="";for(let r=0;r<e.clickhouse.length;r++){const t=e.clickhouse[r],d=p(t),s=k(t,e),i=r>0?`
15
+ `:"",f=s?`const ${d} = `:"";n+=`${i}${f}app.addDatabase(
16
+ DatabaseFactory.build(${a(t.name)}, {
17
17
  type: "ClickHouse",
18
- databaseName: ${u(t.databaseName)},`,t.instanceType!==void 0&&(n+=`
19
- instanceType: ${u(t.instanceType)},`),t.coldTier!==void 0&&(n+=`
20
- coldTier: ${p(t.coldTier," ")},`),t.optimiseSchedule!==void 0&&(n+=`
21
- optimiseSchedule: ${p(t.optimiseSchedule," ")},`),t.backupSchedule!==void 0&&(n+=`
22
- backupSchedule: ${p(t.backupSchedule," ")},`),t.backupRetentionDays!==void 0&&(n+=`
23
- backupRetentionDays: ${t.backupRetentionDays},`),n+=A(t.extraProperties),n+=`
18
+ databaseName: ${a(t.databaseName)},`,t.instanceType!==void 0&&(n+=`
19
+ instanceType: ${a(t.instanceType)},`),t.coldTier!==void 0&&(n+=`
20
+ coldTier: ${S(t.coldTier," ")},`),t.optimiseSchedule!==void 0&&(n+=`
21
+ optimiseSchedule: ${S(t.optimiseSchedule," ")},`),t.backupSchedule!==void 0&&(n+=`
22
+ backupSchedule: ${S(t.backupSchedule," ")},`),t.backupRetentionDays!==void 0&&(n+=`
23
+ backupRetentionDays: ${t.backupRetentionDays},`),n+=b(t.extraProperties),n+=`
24
24
  })
25
25
  );
26
- `}return n}s(w,"generateClickHouseCode");function P(e,n){return n.compute.some(r=>r.connectedDatabase?.includes(e.name))}s(P,"clickhouseNeedsVariable");export{g as CREDENTIAL_KEYS,l as DATABASE_ENV_VARS,V as buildDatabaseEnvVars,T as databaseNeedsVariable,O as formatConnectionsCode,w as generateClickHouseCode,j as generateDatabaseCode,$ as generateDatabaseEnvVarEntries,E as getConnectedDatabases,R as toDatabaseEnvVarValue};
26
+ `}return n}c(W,"generateClickHouseCode");function k(e,n){return n.compute.some(r=>r.connectedDatabase?.includes(e.name))}c(k,"clickhouseNeedsVariable");export{A as CREDENTIAL_KEYS,u as DATABASE_ACCESSORS,l as DATABASE_ENV_VARS,g as DATABASE_SSL_VALUE,_ as buildDatabaseEnvVars,I as databaseNeedsVariable,j as formatConnectionsCode,W as generateClickHouseCode,w as generateDatabaseCode,T as generateDatabaseEnvVarEntries,D as getConnectedDatabases,h as toDatabaseEnvVarValue};
@@ -1 +1 @@
1
- var f=Object.defineProperty;var u=(s,e)=>f(s,"name",{value:e,configurable:!0});import{getVariableName as g}from"./common.js";const i=Object.freeze({URL:"QUEUE_URL",ARN:"QUEUE_ARN"});function p(s,e){const{connectedMessaging:n}=e;return n?.length?(s.sqs??[]).filter(t=>n.includes(t.name)):[]}u(p,"getConnectedMessaging");function a(s){const e=[];if(s.length===1){const n=s[0];if(!n)return e;const t=g(n);e.push({key:i.URL,expression:`${t}.getQueueUrl()`}),e.push({key:i.ARN,expression:`${t}.getQueueArn()`})}else for(const[n,t]of s.entries()){const r=g(t),o=n===0?"":`_${n+1}`;e.push({key:`${i.URL}${o}`,expression:`${r}.getQueueUrl()`}),e.push({key:`${i.ARN}${o}`,expression:`${r}.getQueueArn()`})}return e}u(a,"generateMessagingEnvVarEntries");function U(s,e){const n={},t={};if(!e.connectedMessaging?.length)return{env:n,secrets:t};const r=p(s,e),o=a(r);for(const c of o)n[c.key]={__expression:c.expression};return{env:n,secrets:t}}u(U,"buildMessagingEnvVars");export{i as MESSAGING_ENV_VARS,U as buildMessagingEnvVars,a as generateMessagingEnvVarEntries,p as getConnectedMessaging};
1
+ var g=Object.defineProperty;var u=(s,e)=>g(s,"name",{value:e,configurable:!0});import{connectionEnvSuffix as p,getVariableName as f}from"./common.js";const i=Object.freeze({URL:"QUEUE_URL",ARN:"QUEUE_ARN"});function a(s,e){const{connectedMessaging:n}=e;return n?.length?(s.sqs??[]).filter(t=>n.includes(t.name)):[]}u(a,"getConnectedMessaging");function x(s){const e=[];if(s.length===1){const n=s[0];if(!n)return e;const t=f(n);e.push({key:i.URL,expression:`${t}.getQueueUrl()`}),e.push({key:i.ARN,expression:`${t}.getQueueArn()`})}else for(const[n,t]of s.entries()){const r=f(t),o=p(n);e.push({key:`${i.URL}${o}`,expression:`${r}.getQueueUrl()`}),e.push({key:`${i.ARN}${o}`,expression:`${r}.getQueueArn()`})}return e}u(x,"generateMessagingEnvVarEntries");function U(s,e){const n={},t={};if(!e.connectedMessaging?.length)return{env:n,secrets:t};const r=a(s,e),o=x(r);for(const c of o)n[c.key]={__expression:c.expression};return{env:n,secrets:t}}u(U,"buildMessagingEnvVars");export{i as MESSAGING_ENV_VARS,U as buildMessagingEnvVars,x as generateMessagingEnvVarEntries,a as getConnectedMessaging};
@@ -8,6 +8,15 @@ import type { S3ResourcePlan, SQSResourcePlan, ApplicationResourcePlan, ComputeR
8
8
  export declare const STORAGE_ENV_VARS: Readonly<{
9
9
  readonly NAME: "BUCKET_NAME";
10
10
  }>;
11
+ /**
12
+ * Construct accessor methods the emitted connection wiring calls on a bound
13
+ * bucket variable. Shared with the codemod connection edit
14
+ * (`codemod/edits/connectResourceToCompute.ts`) — the two emitters must call
15
+ * identical methods or surgically-wired apps fail at synth.
16
+ */
17
+ export declare const STORAGE_ACCESSORS: Readonly<{
18
+ readonly BUCKET_NAME: "getBucketName";
19
+ }>;
11
20
  export type StorageEnvVarEntry = {
12
21
  key: string;
13
22
  expression: string;
@@ -1 +1 @@
1
- var g=Object.defineProperty;var a=(n,t)=>g(n,"name",{value:t,configurable:!0});import{getVariableName as i}from"./common.js";const f=Object.freeze({NAME:"BUCKET_NAME"});function l(n,t){const{connectedStorage:e}=t;return e?.length?n.s3.filter(r=>e.includes(r.name)):[]}a(l,"getConnectedStorage");function p(n){const t=[];if(n.length===1){const e=n[0];if(!e)return t;const r=i(e);t.push({key:f.NAME,expression:`${r}.getBucketName()`})}else for(const[e,r]of n.entries()){const o=i(r),s=e===0?"":`_${e+1}`;t.push({key:`${f.NAME}${s}`,expression:`${o}.getBucketName()`})}return t}a(p,"generateStorageEnvVarEntries");function m(n,t){const e={},r={};if(!t.connectedStorage?.length)return{env:e,secrets:r};const o=l(n,t),s=p(o);for(const u of s)e[u.key]={__expression:u.expression};return{env:e,secrets:r}}a(m,"buildStorageEnvVars");function E(n,t,e=[]){const r=n.map(c=>i(c)),o=t.map(c=>i(c)),s=e.map(c=>i(c));return`connections: [${[...r,...o,...s].join(", ")}],`}a(E,"formatAllConnectionsCode");export{f as STORAGE_ENV_VARS,m as buildStorageEnvVars,E as formatAllConnectionsCode,p as generateStorageEnvVarEntries,l as getConnectedStorage};
1
+ var p=Object.defineProperty;var i=(t,e)=>p(t,"name",{value:e,configurable:!0});import{connectionEnvSuffix as g,getVariableName as a}from"./common.js";const u=Object.freeze({NAME:"BUCKET_NAME"}),E=Object.freeze({BUCKET_NAME:"getBucketName"});function l(t,e){const{connectedStorage:n}=e;return n?.length?t.s3.filter(r=>n.includes(r.name)):[]}i(l,"getConnectedStorage");function x(t){const e=[];if(t.length===1){const n=t[0];if(!n)return e;const r=a(n);e.push({key:u.NAME,expression:`${r}.${E.BUCKET_NAME}()`})}else for(const[n,r]of t.entries()){const o=a(r),s=g(n);e.push({key:`${u.NAME}${s}`,expression:`${o}.${E.BUCKET_NAME}()`})}return e}i(x,"generateStorageEnvVarEntries");function S(t,e){const n={},r={};if(!e.connectedStorage?.length)return{env:n,secrets:r};const o=l(t,e),s=x(o);for(const f of s)n[f.key]={__expression:f.expression};return{env:n,secrets:r}}i(S,"buildStorageEnvVars");function N(t,e,n=[]){const r=t.map(c=>a(c)),o=e.map(c=>a(c)),s=n.map(c=>a(c));return`connections: [${[...r,...o,...s].join(", ")}],`}i(N,"formatAllConnectionsCode");export{E as STORAGE_ACCESSORS,u as STORAGE_ENV_VARS,S as buildStorageEnvVars,N as formatAllConnectionsCode,x as generateStorageEnvVarEntries,l as getConnectedStorage};
@@ -2,5 +2,6 @@ export { planApplicationResources, planServiceFromTierPreset, toUserServiceConfi
2
2
  export { type OpenNextResourceOptions, planOpenNextResources, } from "./openNextPlanning.js";
3
3
  export { type StaticSiteResourceOptions, planStaticSiteResources, } from "./staticSitePlanning.js";
4
4
  export { type ConnectionType, applyComputeConnections, applyServiceConnections, } from "./resourceConnections.js";
5
- export { type AddableResourceType, type AddResourceOptions, type DatabaseAddOptions, type ProxyAddOptions, type S3AddOptions, type NetworkAddOptions, type EcsComputeAddOptions, type LambdaComputeAddOptions, type CdnAddOptions, type TunnelAddOptions, addResourceToPlan, validateResourceAddition, listAvailableResources, } from "./resourceAddition.js";
5
+ export { type AddableResourceType, type AddResourceOptions, type DatabaseAddOptions, type ProxyAddOptions, type S3AddOptions, type NetworkAddOptions, type EcsComputeAddOptions, type LambdaComputeAddOptions, type CdnAddOptions, type TunnelAddOptions, addResourceToPlan, validateResourceAddition, listAvailableResources, isResourceNameTaken, resourceNameTakenMessage, } from "./resourceAddition.js";
6
6
  export { type ResourceChangeResult, generateResourceChange, } from "./generateResourceChange.js";
7
+ export { type RelationalDatabaseBuildOptions, type ClickHouseDatabaseBuildOptions, type S3BucketBuildOptions, type ProxyAdditionResolution, type ProxyPlanValue, buildRelationalResourcePlan, buildClickHouseResourcePlan, buildS3ResourcePlan, defaultRelationalDatabaseName, duplicateDatabaseNameMessage, resolveProxyAddition, pickDefined, } from "./planBuilders.js";
@@ -1 +1 @@
1
- import{planApplicationResources as o,planServiceFromTierPreset as t,toUserServiceConfigs as n,generateInfrastructureFromPlan as a}from"./resourcePlanning.js";import{planOpenNextResources as s}from"./openNextPlanning.js";import{planStaticSiteResources as c}from"./staticSitePlanning.js";import{applyComputeConnections as u,applyServiceConnections as m}from"./resourceConnections.js";import{addResourceToPlan as x,validateResourceAddition as R,listAvailableResources as d}from"./resourceAddition.js";import{generateResourceChange as C}from"./generateResourceChange.js";export{x as addResourceToPlan,u as applyComputeConnections,m as applyServiceConnections,a as generateInfrastructureFromPlan,C as generateResourceChange,d as listAvailableResources,o as planApplicationResources,s as planOpenNextResources,t as planServiceFromTierPreset,c as planStaticSiteResources,n as toUserServiceConfigs,R as validateResourceAddition};
1
+ import{planApplicationResources as a,planServiceFromTierPreset as r,toUserServiceConfigs as s,generateInfrastructureFromPlan as t}from"./resourcePlanning.js";import{planOpenNextResources as i}from"./openNextPlanning.js";import{planStaticSiteResources as c}from"./staticSitePlanning.js";import{applyComputeConnections as u,applyServiceConnections as m}from"./resourceConnections.js";import{addResourceToPlan as R,validateResourceAddition as f,listAvailableResources as x,isResourceNameTaken as P,resourceNameTakenMessage as b}from"./resourceAddition.js";import{generateResourceChange as v}from"./generateResourceChange.js";import{buildRelationalResourcePlan as S,buildClickHouseResourcePlan as N,buildS3ResourcePlan as k,defaultRelationalDatabaseName as A,duplicateDatabaseNameMessage as T,resolveProxyAddition as y,pickDefined as D}from"./planBuilders.js";export{R as addResourceToPlan,u as applyComputeConnections,m as applyServiceConnections,N as buildClickHouseResourcePlan,S as buildRelationalResourcePlan,k as buildS3ResourcePlan,A as defaultRelationalDatabaseName,T as duplicateDatabaseNameMessage,t as generateInfrastructureFromPlan,v as generateResourceChange,P as isResourceNameTaken,x as listAvailableResources,D as pickDefined,a as planApplicationResources,i as planOpenNextResources,r as planServiceFromTierPreset,c as planStaticSiteResources,y as resolveProxyAddition,b as resourceNameTakenMessage,s as toUserServiceConfigs,f as validateResourceAddition};
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Pure resource-plan builders shared by the CLI generator lane (full
3
+ * regeneration) and the surgical codemod lane. Both lanes MUST derive a new
4
+ * resource's plan shape from these builders — a second derivation would let
5
+ * preset expansion and option picking drift silently between the two paths.
6
+ */
7
+ import type { z } from "zod";
8
+ import type { AddProxyGeneratorOptions, DatabaseGeneratorSchema } from "../schemas/databaseSchemas.js";
9
+ import type { S3GeneratorOptions } from "../schemas/storageSchemas.js";
10
+ import type { ClickHouseResourcePlan, DatabaseResourcePlan, S3ResourcePlan } from "../schemas/resourceSchemas.js";
11
+ export declare function pickDefined<T extends Record<string, unknown>>(source: T, ...keys: Array<keyof T>): Partial<Pick<T, (typeof keys)[number]>>;
12
+ type ValidatedDatabaseOptions = z.infer<typeof DatabaseGeneratorSchema>;
13
+ export type RelationalDatabaseBuildOptions = Extract<ValidatedDatabaseOptions, {
14
+ databaseType: "Instance" | "Aurora" | "GlobalAurora";
15
+ }>;
16
+ export type ClickHouseDatabaseBuildOptions = Extract<ValidatedDatabaseOptions, {
17
+ databaseType: "ClickHouse";
18
+ }>;
19
+ export type S3BucketBuildOptions = S3GeneratorOptions;
20
+ export declare function buildRelationalResourcePlan(resourceName: string, options: RelationalDatabaseBuildOptions): DatabaseResourcePlan;
21
+ /** Default construct name both lanes use for a relational database add. */
22
+ export declare function defaultRelationalDatabaseName(appName: string): string;
23
+ /** Duplicate-`databaseName` refusal both lanes surface verbatim. */
24
+ export declare function duplicateDatabaseNameMessage(databaseName: string, appName: string): string;
25
+ export type ProxyPlanValue = Partial<Pick<AddProxyGeneratorOptions, "maxConnections" | "maxIdleConnections" | "connectionBorrowTimeout" | "requireTLS">>;
26
+ export type ProxyAdditionResolution = {
27
+ ok: true;
28
+ database: DatabaseResourcePlan;
29
+ proxyValue: ProxyPlanValue;
30
+ } | {
31
+ ok: false;
32
+ message: string;
33
+ };
34
+ /**
35
+ * Shared proxy-addition core for both lanes: target lookup by construct or
36
+ * database name, the two refusal messages, and the proxy config value.
37
+ * Drift here would let the two `fjall add proxy` paths disagree on which
38
+ * databases are eligible or which options survive.
39
+ */
40
+ export declare function resolveProxyAddition(databases: DatabaseResourcePlan[], validated: AddProxyGeneratorOptions): ProxyAdditionResolution;
41
+ export declare function buildClickHouseResourcePlan(resourceName: string, options: ClickHouseDatabaseBuildOptions): ClickHouseResourcePlan;
42
+ /**
43
+ * `existingBucketCount` feeds the scaffold's `bucket`/`bucket2`/… variable
44
+ * naming; the surgical lane strips `variableName` before emission (plan-only
45
+ * round-trip key) but passes the real count so both lanes stay one source.
46
+ */
47
+ export declare function buildS3ResourcePlan(constructName: string, options: S3BucketBuildOptions, existingBucketCount: number): S3ResourcePlan;
48
+ export {};
@@ -0,0 +1 @@
1
+ var c=Object.defineProperty;var t=(a,e)=>c(a,"name",{value:e,configurable:!0});import{STORAGE_PRESETS as u}from"../presets/storagePresets.js";function s(a,...e){const n={};for(const r of e)a[r]!==void 0&&(n[r]=a[r]);return n}t(s,"pickDefined");function b(a,e){const n={name:a,type:e.databaseType,databaseName:e.databaseName,...s(e,"databaseInsights","port","proxy","credentials","encryption","deletionProtection")};switch(e.databaseType){case"Instance":return{...n,...s(e,"instanceType","multiAz","readReplica","publiclyAccessible","backupRetention","allocatedStorage","snapshotIdentifier","snapshotUsername")};case"Aurora":return{...n,...s(e,"writer","readers","backupRetention","preferredMaintenanceWindow","monitoringInterval","snapshotIdentifier","snapshotUsername")};case"GlobalAurora":return{...n,primaryRegion:e.primaryRegion,...e.secondaryRegions&&e.secondaryRegions.length>0&&{secondaryRegions:e.secondaryRegions},...s(e,"globalClusterIdentifier","enableGlobalWriteForwarding","writer","readers","backupRetention","preferredMaintenanceWindow","monitoringInterval","snapshotIdentifier","snapshotUsername")};default:return e}}t(b,"buildRelationalResourcePlan");function m(a){return`${a}Database`}t(m,"defaultRelationalDatabaseName");function f(a,e){return`Database name '${a}' already exists in ${e}. Please choose a different database name.`}t(f,"duplicateDatabaseNameMessage");function p(a,e){const n=a.find(o=>o.name===e.databaseName||o.databaseName===e.databaseName);if(!n)return{ok:!1,message:`Database '${e.databaseName}' not found. Available databases: ${a.map(o=>o.name).join(", ")||"none"}`};if(n.proxy!==void 0&&n.proxy!==!1)return{ok:!1,message:`Database '${n.name}' already has RDS Proxy enabled.`};const r=s(e,"maxConnections","maxIdleConnections","connectionBorrowTimeout","requireTLS");return{ok:!0,database:n,proxyValue:Object.keys(r).length>0?r:{}}}t(p,"resolveProxyAddition");function y(a,e){return{name:a,type:"ClickHouse",databaseName:e.databaseName,...s(e,"instanceType","coldTier","optimiseSchedule","backupSchedule","backupRetentionDays")}}t(y,"buildClickHouseResourcePlan");function R(a,e,n){const r=e.storagePreset??"standard",o=u[r],i=n===0?"":`${n+1}`;return{name:a,bucketName:e.bucketName,variableName:`bucket${i}`,...o,...s(e,"publicReadAccess","websiteHosting","backupVaultTier","versioned","encryption","kmsKeyArn","cors")}}t(R,"buildS3ResourcePlan");export{y as buildClickHouseResourcePlan,b as buildRelationalResourcePlan,R as buildS3ResourcePlan,m as defaultRelationalDatabaseName,f as duplicateDatabaseNameMessage,s as pickDefined,p as resolveProxyAddition};
@@ -155,4 +155,7 @@ export declare function validateResourceAddition(plan: ApplicationResourcePlan,
155
155
  * fields wire the new resource to existing compute resources in the plan.
156
156
  */
157
157
  export declare function addResourceToPlan(plan: ApplicationResourcePlan, options: AddResourceOptions): Result<ApplicationResourcePlan, Error>;
158
+ export declare function isResourceNameTaken(plan: ApplicationResourcePlan, name: string): boolean;
159
+ /** Refusal message every lane surfaces verbatim when the gate fires. */
160
+ export declare function resourceNameTakenMessage(name: string): string;
158
161
  export {};