@fjall/generator 7.3.0 → 9.0.0
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 +28 -21
- package/dist/.minified +1 -1
- package/dist/src/ast/domain/astDomainParser.d.ts +2 -0
- package/dist/src/ast/domain/astDomainParser.js +1 -1
- package/dist/src/codemod/drift/snapshot.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 +25 -0
- package/dist/src/codemod/edits/moduleConstResolver.js +1 -0
- package/dist/src/codemod/edits/objectGraph.d.ts +34 -0
- package/dist/src/codemod/edits/objectGraph.js +1 -0
- package/dist/src/codemod/edits/secretsProvability.d.ts +48 -0
- package/dist/src/codemod/edits/secretsProvability.js +1 -0
- package/dist/src/codemod/edits/setContainerSecrets.d.ts +55 -0
- package/dist/src/codemod/edits/setContainerSecrets.js +1 -0
- package/dist/src/codemod/index.d.ts +2 -0
- package/dist/src/codemod/index.js +1 -1
- package/dist/src/codemod/registry.d.ts +1 -2
- 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/dns/bindParser.js +2 -2
- package/dist/src/dns/bindWriter.js +2 -2
- package/dist/src/dns/domainRecords.d.ts +4 -0
- package/dist/src/dns/domainRecords.js +1 -1
- package/dist/src/generation/common.d.ts +15 -0
- package/dist/src/generation/common.js +6 -6
- 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/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Result } from "../../types/Result.js";
|
|
2
|
+
import type { LinesChanged, ParseError } from "../types.js";
|
|
3
|
+
export interface SetContainerSecretsOptions {
|
|
4
|
+
/** ECS service `name` to target, e.g. "api". */
|
|
5
|
+
serviceName: string;
|
|
6
|
+
/** Container within that service. Defaults to the first. */
|
|
7
|
+
containerIndex?: number;
|
|
8
|
+
/** Names to declare. Already-declared names are left alone. */
|
|
9
|
+
add?: readonly string[];
|
|
10
|
+
/** Names to undeclare. Names not declared are ignored. */
|
|
11
|
+
remove?: readonly string[];
|
|
12
|
+
/**
|
|
13
|
+
* Path the caller's namespace implies. Compared against an explicitly
|
|
14
|
+
* declared `ssmSecretsPath` to surface a mismatch; never written — an
|
|
15
|
+
* absent declaration is the construct's own `/<app>/<cluster>/<service>`
|
|
16
|
+
* derivation and writing it back would duplicate that derivation here.
|
|
17
|
+
*/
|
|
18
|
+
expectedSsmSecretsPath?: string;
|
|
19
|
+
filePath?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface SetContainerSecretsSuccess {
|
|
22
|
+
/** Byte-identical to the input when `skipped` is true. */
|
|
23
|
+
content: string;
|
|
24
|
+
linesChanged: LinesChanged;
|
|
25
|
+
added: string[];
|
|
26
|
+
removed: string[];
|
|
27
|
+
skipped: boolean;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface ServiceNotFoundError {
|
|
31
|
+
kind: "ServiceNotFoundError";
|
|
32
|
+
serviceName: string;
|
|
33
|
+
knownServices: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface ContainerNotFoundError {
|
|
36
|
+
kind: "ContainerNotFoundError";
|
|
37
|
+
serviceName: string;
|
|
38
|
+
containerIndex: number;
|
|
39
|
+
containerCount: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `reason` is author-written text that may embed identifiers, property keys
|
|
43
|
+
* and secret NAMES read from the parsed source or CLI input — identifier-class
|
|
44
|
+
* data, never expression values (see security-standards § "Values, not
|
|
45
|
+
* identifiers"). It is never error-derived: interpolating a caught error's
|
|
46
|
+
* message here would silently make every consumer a leak. The CLI boundary
|
|
47
|
+
* masks defensively regardless.
|
|
48
|
+
*/
|
|
49
|
+
export interface UnsupportedSecretsShapeError {
|
|
50
|
+
kind: "UnsupportedSecretsShapeError";
|
|
51
|
+
serviceName: string;
|
|
52
|
+
reason: string;
|
|
53
|
+
}
|
|
54
|
+
export type SetContainerSecretsError = ParseError | ServiceNotFoundError | ContainerNotFoundError | UnsupportedSecretsShapeError;
|
|
55
|
+
export declare function setContainerSecrets(content: string, options: SetContainerSecretsOptions): Result<SetContainerSecretsSuccess, SetContainerSecretsError>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var x=Object.defineProperty;var d=(r,e)=>x(r,"name",{value:e,configurable:!0});import{failure as o,success as l}from"../../types/Result.js";import{DEFAULT_FILE_PATH as L,computeLinesDelta as O,extractProgramBody as I}from"../_internal.js";import{buildObjectProperty as R,detectQuoteStyle as T,parse as D,printFile as _}from"../fileRewriter/index.js";import{makeStringLiteral as q,toAstValue as B}from"./addResource/propertyBuilder.js";import{findLastPlainPropertyIndex as J,isArrayExpression as M,locateContainer as W,locateServiceByName as z,readStringProperty as H}from"./computeServiceLocator.js";import{buildModuleConstResolver as K}from"./moduleConstResolver.js";import{pushPropertyPreservingComma as Q}from"./objectGraph.js";import{checkSecretsImportConflicts as A,checkShadowingSpread as V,classifySecretsElement as Y,describeElements as U,keyProvablyAbsent as G}from"./secretsProvability.js";const P="secrets";function fe(r,e){const t=e.filePath??L,{serviceName:n}=e,i=e.containerIndex??0,g=e.add??[],b=e.remove??[],a=D(r,t);if(!a.success)return o(a.error);const y=I(a.data);if(y===void 0)return o({kind:"UnsupportedSecretsShapeError",serviceName:n,reason:"recast File is missing program.body"});const p=Z(y,n);if(!p.success)return o(p.error);const{service:f}=p.data,u=N(f,n,i);if(!u.success)return o(u.error);const h=ee(f,n,e.expectedSsmSecretsPath),k=K(y),m=re(u.data,n,k,{add:g,remove:b,quoteStyle:T(a.data)});if(!m.success)return o(m.error);const{added:C,removed:w}=m.data,E=[...h,...m.data.warnings];return C.length===0&&w.length===0?l({content:r,linesChanged:{added:0,removed:0},added:[],removed:[],skipped:!0,warnings:E}):l({...X(a.data,r),added:C,removed:w,skipped:!1,warnings:E})}d(fe,"setContainerSecrets");function X(r,e){const t=_(r,e);return{content:t,linesChanged:O(e,t)}}d(X,"printResult");function Z(r,e){const t=z(r,e);if(t.success)return l({service:t.data});const n=t.error;return n.kind==="AmbiguousService"?o(S(e,`${String(n.count)} services share the name "${e}" across ComputeFactory.build calls \u2014 the edit cannot be proven to target the right one. Edit the file by hand.`)):o({kind:"ServiceNotFoundError",serviceName:e,knownServices:n.knownServices})}d(Z,"locateService");function N(r,e,t){const n=W(r,t);if(n.success)return l(n.data);const i=n.error;switch(i.kind){case"NoContainersArray":return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Service has no `containers` array literal."});case"ContainersNotStaticArray":return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Service's `containers` is not a static array literal."});case"ContainerIndexOutOfRange":return o({kind:"ContainerNotFoundError",serviceName:e,containerIndex:t,containerCount:i.containerCount});case"ContainerNotObjectLiteral":return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:`Container ${String(t)} is not an object literal.`})}}d(N,"resolveContainer");function ee(r,e,t){if(t===void 0)return[];const n=H(r,"ssmSecretsPath");return n===void 0||n===t?[]:[`Service "${e}" declares ssmSecretsPath "${n}", but the secrets were written under "${t}". The task will read the declared path.`]}d(ee,"collectPathWarnings");function S(r,e){return{kind:"UnsupportedSecretsShapeError",serviceName:r,reason:e}}d(S,"unsupported");function re(r,e,t,n){const{add:i,remove:g,quoteStyle:b}=n,a=J(r,P);if(a===-1){if(!G(r,P,t))return o(S(e,"Container carries a spread, shorthand or computed key that could supply `secrets` invisibly, so an absent property cannot be proven. Declare `secrets` explicitly first."));if(g.length>0&&i.length===0)return l({added:[],removed:[],warnings:[]});const u=$(i),h=A(r,u,t);if(!h.ok)return o(S(e,h.reason));const k=te(r,e,u,b);return k.success?l({...k.data,warnings:h.warnings}):k}const p=r.properties[a]?.value;if(!M(p))return o(S(e,"`secrets` is not an array literal."));const f=V(r,a,t);return f.ok?ne(p,r,e,t,n):o(S(e,f.reason))}d(re,"applySecrets");function te(r,e,t,n){const i=$(t);if(i.length===0)return l({added:[],removed:[]});const g=B(i,n);if(g===void 0)return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Unable to build a `secrets` array literal."});const b=R(P,g,n);return Q(r,b),l({added:i,removed:[]})}d(te,"createSecretsArray");function ne(r,e,t,n,i){const{add:g,remove:b,quoteStyle:a}=i,y=r.elements.map(s=>Y(s,n)),p=y.filter(s=>s.kind==="unresolvable"),f=new Set(b);if(f.size>0){if(p.length>0)return o(S(t,`\`secrets\` contains ${U(p)}, which cannot be resolved to string literals in this file, so a removed name cannot be proven gone. Edit the array by hand.`));for(const s of y){if(s.kind!=="spread")continue;const v=s.names.filter(c=>f.has(c));if(v.length>0){const c=v.map(j=>JSON.stringify(j)).join(", "),F=v.length===1?"is":"are";return o(S(t,`${c} ${F} supplied by \`${s.description}\`, so this edit cannot undeclare it \u2014 the shared array may feed other services. Edit \`${s.description.slice(3)}\` by hand.`))}}}const u=[],h=[];r.elements=r.elements.filter((s,v)=>{const c=y[v];return c!==void 0&&(c.kind==="literal"||c.kind==="identifier")&&f.has(c.name)?(u.push(c.name),!1):(c!==void 0&&h.push(c),!0)});const k=new Set(h.flatMap(s=>s.kind==="unresolvable"?[]:s.kind==="spread"?[...s.names]:[s.name])),m=$(g).filter(s=>!k.has(s));if(m.length===0)return l({added:[],removed:u,warnings:[]});const C=h.filter(s=>s.kind==="unresolvable");if(C.length>0){const s=m.map(v=>JSON.stringify(v)).join(", ");return o(S(t,`\`secrets\` contains ${U(C)}, which cannot be resolved in this file, so ${s} cannot be proven absent \u2014 a duplicate name breaks \`fjall deploy\` at synth. Add it by hand.`))}const w=A(e,m,n);if(!w.ok)return o(S(t,w.reason));const E=[];for(const s of m)r.elements.push(q(s,a)),E.push(s);return l({added:E,removed:u,warnings:w.warnings})}d(ne,"mutateSecretsArray");function $(r){return[...new Set(r)]}d($,"dedupe");export{fe as setContainerSecrets};
|
|
@@ -2,6 +2,8 @@ export { addResource, type AddResourceCallContext, type AddResourceError, type A
|
|
|
2
2
|
export { removeResource, type RemoveResourceError, type RemoveResourceSuccess, } from "./edits/removeResource.js";
|
|
3
3
|
export { modifyResource, type ModifyResourceCallContext, type ModifyResourceError, type ModifyResourceSuccess, } from "./edits/modifyResource.js";
|
|
4
4
|
export { appendAccountToStage, type AppendAccountToStageError, type AppendAccountToStageOptions, type AppendAccountToStageSuccess, } from "./edits/appendAccountToStage.js";
|
|
5
|
+
export { setContainerSecrets, type SetContainerSecretsError, type SetContainerSecretsOptions, type SetContainerSecretsSuccess, } from "./edits/setContainerSecrets.js";
|
|
6
|
+
export { connectResourceToCompute, type ConnectableResourceType, type ConnectResourceError, type ConnectResourceOptions, type ConnectResourceSuccess, } from "./edits/connectResourceToCompute.js";
|
|
5
7
|
export { addVpcPeer, modifyVpcPeer, removeVpcPeer, type VpcPeerAddOptions, type VpcPeerModifyOptions, type VpcPeerOrchestratorSuccess, type VpcPeerRemoveOptions, } from "./edits/vpcPeer.js";
|
|
6
8
|
export { addVpcPeerAccepter, modifyVpcPeerAccepter, removeVpcPeerAccepter, type VpcPeerAccepterAddOptions, type VpcPeerAccepterModifyOptions, type VpcPeerAccepterOrchestratorSuccess, type VpcPeerAccepterRemoveOptions, } from "./edits/vpcPeerAccepter.js";
|
|
7
9
|
export { addCrossPlanConnection, modifyCrossPlanConnection, removeCrossPlanConnection, type CrossPlanConnectionAddOptions, type CrossPlanConnectionModifyOptions, type CrossPlanConnectionOrchestratorSuccess, type CrossPlanConnectionRemoveOptions, } from "./edits/crossPlanConnection.js";
|
|
@@ -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
|
|
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};
|
|
@@ -99,7 +99,7 @@ export interface StatementTypeEntry {
|
|
|
99
99
|
*/
|
|
100
100
|
emitGuard?: ReadonlyArray<EmitGuardRule>;
|
|
101
101
|
}
|
|
102
|
-
declare const FACTORY_IDENTIFIERS: {
|
|
102
|
+
export declare const FACTORY_IDENTIFIERS: {
|
|
103
103
|
readonly database: "DatabaseFactory";
|
|
104
104
|
readonly storage: "StorageFactory";
|
|
105
105
|
readonly compute: "ComputeFactory";
|
|
@@ -125,4 +125,3 @@ export declare const STATEMENT_REGISTRY: Record<StatementType, StatementTypeEntr
|
|
|
125
125
|
*/
|
|
126
126
|
export declare const REGISTERED_STATEMENT_TYPES: ReadonlyArray<StatementType>;
|
|
127
127
|
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
|
|
1
|
+
var C=Object.defineProperty;var n=(e,t)=>C(e,"name",{value:t,configurable:!0});import{z as d}from"zod";import{BuildkitePropsObjectSchema as v,CDNResourcePlanSchema as R,ComputeResourcePlanSchema as k,CrossPlanConnectionResourcePlanSchema as T,DatabaseResourcePlanSchema as A,NetworkResourcePlanSchema as E,NextJSPatternConfigSchema as w,OrganisationResourcePlanSchema as F,PayloadPatternConfigSchema as N,S3ResourcePlanSchema as M,SQSResourcePlanSchema as D,StaticSitePatternConfigSchema as _,VpcPeerAccepterResourcePlanSchema as x,VpcPeerResourcePlanSchema as O}from"../schemas/index.js";import{failure as W}from"../types/Result.js";import{isRecord as G}from"./_internal.js";import{AUTHOR_BY_HAND as c,requiresLiveValue as g,silentlyDropped as a,UNRESOLVED as m,whenAbsent as p}from"./emitGuard.js";const r={database:"DatabaseFactory",storage:"StorageFactory",compute:"ComputeFactory",messaging:"MessagingFactory",cdn:"CdnFactory",network:"NetworkFactory",pattern:"PatternFactory","vpc-peer":"VpcPeerFactory","vpc-peer-accepter":"VpcPeerAccepterFactory","cross-plan-connection":"CrossPlanConnectionFactory",organisation:"OrganisationFactory",buildkite:"BuildkiteFactory"};function s(e){const{name:t,...i}=e.shape;return d.object(i).partial().strict()}n(s,"fragmentOf");const I=s(A),B=s(M),j=(()=>{const{name:e,...t}=k.shape;return d.object(t).partial().strict()})(),L=s(D),V=s(R),Y=s(E),q=(()=>{const{name:e,type:t,cdn:i,...f}=N.shape,{name:ae,type:re,cdn:oe,...b}=w.shape,{name:se,type:ie,domain:ce,cdn:S,...P}=_.shape;return d.object({...f,...b,...P,cdn:d.union([i,S])}).partial().strict()})(),K=s(O),U=s(x),z=s(T),H=s(F),Q=s(v);function l(e,t){return W({kind:"SemanticQueryError",reason:`StatementTypeEntry.${e} for ${t} is not wired; existing types dispatch through the shared locator/generator.`})}n(l,"notWiredError");function $(e){return{factoryIdentifier:e,findByShape:n(()=>l("locator.findByShape",e),"findByShape"),validateContext:n(()=>l("locator.validateContext",e),"validateContext")}}n($,"createLocator");function J(e){return{build:n(()=>{const t=l("generator.build",e);throw new Error(t.success?"unreachable":t.error.reason)},"build")}}n(J,"createGenerator");const X=a("variableName","`variableName` is a plan-only round-trip key naming the `const <var> =` binding the scaffold emits; no construct reads it."),y=a("extraProperties","`extraProperties` is a plan-only round-trip key: the scaffold flattens each `{ key, sourceText }` entry into a sibling property, and no construct reads the array."),u="the connection keys are scaffold inputs, not construct props: the scaffold expands them into environment variables and a `connections: [...]` array, and the compute constructs read none of them.",Z=[{property:"deployment",refuseWhen:n(e=>(e.type==="lambda"||e.deployment!==void 0)&&e.deployment!=="container"&&e.code!==m,"refuseWhen"),reason:"a code-deployed Lambda requires `code: Code`, a CDK object built by `Code.fromAsset(...)` that no flag value can carry, so the statement takes the whole app's synth down with `Cannot read properties of undefined (reading 'bind')` \u2014 naming no resource. Use `--deployment container`, which is fully expressible, or write this compute in infrastructure.ts by hand."},a("codePath","`codePath` is the scaffold's input to `Code.fromAsset(...)`; no compute construct reads it, and a container Lambda takes its code from the image."),g("runtime","the construct expects a CDK `Runtime`, not a version string, and a container Lambda takes its runtime from the image (`Runtime.FROM_IMAGE`) regardless."),g("architecture","the construct expects a CDK `Architecture`, not a string: `--architecture ARM_64` emits an EMPTY `Architectures` list, whereas omitting the flag emits the correct default."),a("memory","the Lambda construct reads `memorySize`, so `--memory 1024` deploys a function at the 128 MB default."),a("ssmSecrets","the Lambda construct reads `secrets`, so `--ssmSecrets` deploys a function with no SSM wiring and no secrets environment at all."),a("scheduleExpression","`scheduleExpression` is not a compute prop: the scaffold turns it into a SEPARATE `app.addSchedule(...)` statement, which this command cannot emit."),a("needsConnection",u),a("connectedDatabase",u),a("connectedStorage",u),a("connectedMessaging",u),X,y],ee=[{property:"originType",refuseWhen:p("originType"),reason:"`Cdn` selects its origin implementation from an `originType` discriminator that the CDN vocabulary does not carry, so a distribution built from CDN properties throws `Unsupported CDN origin type: undefined` the moment `app.addCdn` materialises it. "+c},{property:"originType",refuseWhen:n(e=>e.originType==="s3"&&e.bucket!==m,"refuseWhen"),reason:"an s3 origin needs `bucket` to be an `IBucket` or a Fjall `Storage` \u2014 a live construct, not a name, and not a string; omitting it throws `Cannot read properties of undefined (reading 'bucketRegionalDomainName')` at synth. "+c},{property:"originType",refuseWhen:n(e=>e.originType==="alb"&&e.loadBalancer!==m,"refuseWhen"),reason:'an alb origin needs `loadBalancer` to be an `IApplicationLoadBalancer` or an ECS compute \u2014 a live construct, not a name, and not a string; a string reaches CloudFormation as `Supplied properties not correct for "OriginProperty"`. '+c},{property:"behaviours",refuseWhen:n(e=>Array.isArray(e.behaviours)&&e.behaviours.some(t=>G(t)&&t.originRef!==void 0),"refuseWhen"),reason:"the plan's `behaviours[].originRef` names another planned resource, while the construct's behaviour takes a live origin object; the plan shape throws `Cannot read properties of undefined (reading 'computeType')` at synth. "+c},a("customDomain","the distribution reads `domainNames`, so `--customDomain` deploys a distribution with no alias."),a("defaultOriginRef","`defaultOriginRef` names another planned resource for the scaffold to resolve into a live origin; no CDN construct reads it."),y],te=[{property:"name",refuseWhen:p("name"),reason:"every pattern construct requires a `name` PROPERTY in addition to its construct id, and `fjall add --name` binds the construct id, so no invocation can deliver it \u2014 `toPascalCase(props.name)` throws at synth and takes the whole app down. "+c},{property:"type",refuseWhen:p("type"),reason:"`PatternFactory.build` reads `PATTERN_REGISTRY[props.type]` before it even returns the thunk, and the pattern vocabulary carries no `type` discriminator. "+c}],ne=[{property:"peerAppName",refuseWhen:p("peerAppName"),reason:"`peerAppName` is required: it is the SSM prefix every remote lookup is built from, and omitting it does NOT fail \u2014 synth succeeds and the app deploys a peering connection pointed at `/fjall/default/undefined/vpc-id`. Pass `--peerAppName <remote app>`."},{property:"peerAccountId",refuseWhen:p("peerAccountId"),reason:"`peerAccountId` is required: omitting it does NOT fail, it deploys a VPC peering connection with no `PeerOwnerId`. Pass `--peerAccountId <12-digit account>`."}];function o(e,t,i={}){return{factoryIdentifier:e,locator:$(e),generator:J(e),schemaFragment:t,...i}}n(o,"createEntry");const h={database:o(r.database,I,{emitWrapper:{appMethod:"addDatabase"}}),storage:o(r.storage,B,{emitWrapper:{appMethod:"addStorage"}}),compute:o(r.compute,j,{emitWrapper:{appMethod:"addCompute"},emitGuard:Z}),messaging:o(r.messaging,L,{emitWrapper:{appMethod:"addMessaging"}}),cdn:o(r.cdn,V,{emitWrapper:{appMethod:"addCdn"},emitGuard:ee}),network:o(r.network,Y,{emitWrapper:{appMethod:"addNetwork"}}),pattern:o(r.pattern,q,{emitWrapper:{appMethod:"addPattern"},emitGuard:te}),"vpc-peer":o(r["vpc-peer"],K,{emitWrapper:{appMethod:"addVpcPeer"},emitGuard:ne}),"vpc-peer-accepter":o(r["vpc-peer-accepter"],U,{emitWrapper:{appMethod:"addVpcPeerAccepter"}}),"cross-plan-connection":o(r["cross-plan-connection"],z),organisation:o(r.organisation,H),buildkite:o(r.buildkite,Q,{emitWrapper:{appMethod:"addBuildkite",propsOverloadConstructId:"Buildkite"}})},ge=Object.keys(h);function ye(e){const t=Object.keys(h);for(const i of t)if(h[i].factoryIdentifier===e)return i}n(ye,"findTypeByIdentifier");export{r as FACTORY_IDENTIFIERS,ge as REGISTERED_STATEMENT_TYPES,h as STATEMENT_REGISTRY,ye as findTypeByIdentifier};
|
|
@@ -1,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
|
-
|
|
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{
|
|
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,2 +1,2 @@
|
|
|
1
|
-
var m=Object.defineProperty;var c=(e,n)=>m(e,"name",{value:n,configurable:!0});import{success as
|
|
2
|
-
`);let t,s=300;const i=[],r=[],o=[];for(const f of n){const l=f.trim();if(l===""||l.startsWith(";"))continue;if(l.toUpperCase().startsWith(d.FJALL_DELEGATE)){const a=$(l);a&&r.push(a);continue}const p=R(l);if(p==="")continue;const u=j(p);if(u.length===0)continue;const h=u[0].toUpperCase();if(h===d.ORIGIN){if(u.length<2)continue;t=C(u[1]);continue}if(h===d.TTL){if(u.length<2)continue;s=parseInt(u[1],10);continue}if(h===d.FJALL_CERT){const a=S(u);a&&o.push(a);continue}const g=w(u);g&&i.push(g)}return t?
|
|
1
|
+
var m=Object.defineProperty;var c=(e,n)=>m(e,"name",{value:n,configurable:!0});import{success as A,failure as I}from"../types/Result.js";import{DnsRecordTypeSchema as T,BIND_DIRECTIVES as d,ALIAS_PREFIX as E}from"./types.js";const v=new Set(T.options);function L(e){return v.has(e.toUpperCase())}c(L,"isRecordType");function C(e){return e.endsWith(".")?e.slice(0,-1):e}c(C,"stripTrailingDot");function R(e){let n=!1;for(let t=0;t<e.length;t++)if(e[t]==='"')n=!n;else if(e[t]===";"&&!n)return e.slice(0,t).trimEnd();return e}c(R,"stripInlineComment");function D(e,n){const t=e.slice(n).join(" "),s=[];let i="",r=!1;for(const o of t)o==='"'?(r&&(s.push(i),i=""),r=!r):r&&(i+=o);return s.join(" ")}c(D,"parseTxtValue");function $(e){const n=/;\s*auto\s*$/.test(e),s=e.replace(/;\s*auto\s*$/,"").trim().match(/^\$FJALL-DELEGATE\s+(\S+)\s+TO\s+(\S+)$/i);if(s)return{subdomain:s[1],targetAccount:s[2],auto:n}}c($,"parseDelegateDirective");function S(e){if(e.length<2)return;const n=e[1],t=e.slice(2);return{domainName:n,subjectAlternativeNames:t}}c(S,"parseCertDirective");function j(e){const n=[];let t="",s=!1;for(const i of e)i==='"'?(s=!s,t+=i):/\s/.test(i)&&!s?t.length>0&&(n.push(t),t=""):t+=i;return t.length>0&&n.push(t),n}c(j,"tokenise");function w(e){if(e.length<2)return;let n=0;const t=e[n++];let s,i;for(;n<e.length&&i===void 0;){const o=e[n].toUpperCase();if(o==="IN")n++;else if(L(o))i=o,n++;else if(/^\d+$/.test(e[n]))s=parseInt(e[n],10),n++;else return}if(!i)return;const r=e.slice(n);switch(i){case"MX":{if(r.length<2)return;const o=parseInt(r[0],10),f=r.slice(1).join(" ");return{name:t,type:i,ttl:s,value:f,priority:o}}case"SRV":{if(r.length<4)return;const o=parseInt(r[0],10),f=parseInt(r[1],10),l=parseInt(r[2],10),p=r[3];return{name:t,type:i,ttl:s,value:p,priority:o,weight:f,port:l}}case"TXT":{const o=D(e,n);return{name:t,type:i,ttl:s,value:o}}case"CAA":{const o=r.join(" ");return{name:t,type:i,ttl:s,value:o}}case"A":case"AAAA":{if(r.length===0)return;if(r[0].toUpperCase()==="ALIAS"){if(r.length<2)return;const f=r.slice(1).join(" ");return{name:t,type:i,ttl:s,value:`${E}${f}`}}return{name:t,type:i,ttl:s,value:r[0]}}default:return r.length===0?void 0:{name:t,type:i,ttl:s,value:r[0]}}}c(w,"parseRecord");function U(e){const n=e.split(`
|
|
2
|
+
`);let t,s=300;const i=[],r=[],o=[];for(const f of n){const l=f.trim();if(l===""||l.startsWith(";"))continue;if(l.toUpperCase().startsWith(d.FJALL_DELEGATE)){const a=$(l);a&&r.push(a);continue}const p=R(l);if(p==="")continue;const u=j(p);if(u.length===0)continue;const h=u[0].toUpperCase();if(h===d.ORIGIN){if(u.length<2)continue;t=C(u[1]);continue}if(h===d.TTL){if(u.length<2)continue;s=parseInt(u[1],10);continue}if(h===d.FJALL_CERT){const a=S(u);a&&o.push(a);continue}const g=w(u);g&&i.push(g)}return t?A({origin:t,ttl:s,records:i,delegations:r,certificates:o}):I(new Error("Missing $ORIGIN directive"))}c(U,"parseZoneFile");function _(e,n){if(!e.startsWith("fjall:"))return;const t=e.split(":");if(t.length<3)return;const s=t[1],i=t[2],r=`${s}:${i}`;return n.get(r)??n.get(e)}c(_,"resolveAlias");export{U as parseZoneFile,_ as resolveAlias};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var u=Object.defineProperty;var
|
|
1
|
+
var u=Object.defineProperty;var i=(t,n)=>u(t,"name",{value:n,configurable:!0});import{BIND_DIRECTIVES as $}from"./types.js";function l(t,n){return t.length>=n?t:t+" ".repeat(n-t.length)}i(l,"padRight");function o(t,n){const s=l(t.name,24),e=t.ttl!==void 0&&t.ttl!==n?`${t.ttl} `:"";switch(t.type){case"MX":return`${s} ${e}IN MX ${t.priority??10} ${t.value}`;case"SRV":return`${s} ${e}IN SRV ${t.priority??0} ${t.weight??0} ${t.port??0} ${t.value}`;case"TXT":return`${s} ${e}IN TXT "${t.value}"`;case"CAA":return`${s} ${e}IN CAA ${t.value}`;default:return`${s} ${e}IN ${t.type} ${t.value}`}}i(o,"formatRecord");function h(t){const n=[];if(n.push("; zone.bind \u2014 managed by fjall"),n.push(`${$.ORIGIN} ${t.origin}.`),n.push(`${$.TTL} ${t.ttl}`),n.push(""),t.certificates.length>0){for(const s of t.certificates){const a=[s.domainName,...s.subjectAlternativeNames];n.push(`${$.FJALL_CERT} ${a.join(" ")}`)}n.push("")}if(t.delegations.length>0){for(const s of t.delegations){const a=s.auto?" ; auto":"";n.push(`${$.FJALL_DELEGATE} ${s.subdomain} TO ${s.targetAccount}${a}`)}n.push("")}for(const s of t.records)n.push(o(s,t.ttl));return n.join(`
|
|
2
2
|
`)+`
|
|
3
|
-
`}
|
|
3
|
+
`}i(h,"generateZoneFile");export{h as generateZoneFile};
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
export declare const TypedFjallTargetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
3
|
kind: z.ZodLiteral<"ecs">;
|
|
4
4
|
appName: z.ZodString;
|
|
5
|
+
computeName: z.ZodOptional<z.ZodString>;
|
|
5
6
|
}, z.core.$strict>, z.ZodObject<{
|
|
6
7
|
kind: z.ZodLiteral<"cdn">;
|
|
7
8
|
appName: z.ZodString;
|
|
@@ -65,6 +66,7 @@ export declare const ParsedAliasRecordSchema: z.ZodObject<{
|
|
|
65
66
|
target: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
66
67
|
kind: z.ZodLiteral<"ecs">;
|
|
67
68
|
appName: z.ZodString;
|
|
69
|
+
computeName: z.ZodOptional<z.ZodString>;
|
|
68
70
|
}, z.core.$strict>, z.ZodObject<{
|
|
69
71
|
kind: z.ZodLiteral<"cdn">;
|
|
70
72
|
appName: z.ZodString;
|
|
@@ -102,6 +104,7 @@ export declare const ParsedDnsRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
102
104
|
target: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
103
105
|
kind: z.ZodLiteral<"ecs">;
|
|
104
106
|
appName: z.ZodString;
|
|
107
|
+
computeName: z.ZodOptional<z.ZodString>;
|
|
105
108
|
}, z.core.$strict>, z.ZodObject<{
|
|
106
109
|
kind: z.ZodLiteral<"cdn">;
|
|
107
110
|
appName: z.ZodString;
|
|
@@ -160,6 +163,7 @@ export declare const ParsedDomainRecordsSchema: z.ZodObject<{
|
|
|
160
163
|
target: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
161
164
|
kind: z.ZodLiteral<"ecs">;
|
|
162
165
|
appName: z.ZodString;
|
|
166
|
+
computeName: z.ZodOptional<z.ZodString>;
|
|
163
167
|
}, z.core.$strict>, z.ZodObject<{
|
|
164
168
|
kind: z.ZodLiteral<"cdn">;
|
|
165
169
|
appName: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as e}from"zod";const r=e.discriminatedUnion("kind",[e.object({kind:e.literal("ecs"),appName:e.string()}).strict(),e.object({kind:e.literal("cdn"),appName:e.string()}).strict(),e.object({kind:e.literal("bucket"),bucketName:e.string()}).strict(),e.object({kind:e.literal("custom"),dnsName:e.string(),hostedZoneId:e.string()}).strict()]),m=r.options.map(t=>t.shape.kind.value),a=e.enum(["A","AAAA"]),n=e.enum(["route53","external-delegated","external-records"]),g=e.enum(["zone","full"]),o=e.object({kind:e.literal("standard"),type:e.enum(["A","AAAA","CNAME","MX","TXT","NS","SRV","CAA"]),name:e.string(),value:e.union([e.string(),e.array(e.string())]),ttl:e.number().int().positive().optional()}).strict(),i=e.object({kind:e.literal("alias"),type:a,name:e.string(),target:r}).strict(),s=e.discriminatedUnion("kind",[o,i]),d=e.object({domainName:e.string(),subjectAlternativeNames:e.array(e.string()).optional(),transparencyLogging:e.boolean().optional(),cloudFront:e.boolean().optional()}).strict(),c=e.object({subdomain:e.string(),toAccount:e.string(),auto:e.boolean().optional()}).strict(),p=e.object({zoneName:e.string(),registrar:n,hostedZoneId:e.string().optional(),delegatedSubdomain:e.string().optional(),adoptedNameServers:e.array(e.string().min(1)).min(1).optional(),records:e.array(s),certificates:e.array(d),delegations:e.array(c)}).strict().refine(t=>t.registrar!=="external-delegated"||t.delegatedSubdomain!==void 0,{message:"external-delegated requires delegatedSubdomain"}).refine(t=>t.registrar!=="external-records"||t.delegations.length===0,{message:"external-records forbids delegations"}).refine(t=>t.registrar==="external-delegated"||t.adoptedNameServers===void 0,{message:"adoptedNameServers requires registrar external-delegated"}).refine(t=>t.registrar!=="external-delegated"||t.hostedZoneId===void 0==(t.adoptedNameServers===void 0),{message:"external-delegated adoption requires hostedZoneId and adoptedNameServers together (both-or-neither)"});export{a as AliasRecordTypeSchema,g as DomainDeployPhaseSchema,n as DomainRegistrarSchema,i as ParsedAliasRecordSchema,d as ParsedCertificateSchema,s as ParsedDnsRecordSchema,p as ParsedDomainRecordsSchema,o as ParsedStandardRecordSchema,c as ParsedSubdomainDelegationSchema,m as TYPED_FJALL_TARGET_KINDS,r as TypedFjallTargetSchema};
|
|
1
|
+
import{z as e}from"zod";const r=e.discriminatedUnion("kind",[e.object({kind:e.literal("ecs"),appName:e.string(),computeName:e.string().min(1).optional()}).strict(),e.object({kind:e.literal("cdn"),appName:e.string()}).strict(),e.object({kind:e.literal("bucket"),bucketName:e.string()}).strict(),e.object({kind:e.literal("custom"),dnsName:e.string(),hostedZoneId:e.string()}).strict()]),m=r.options.map(t=>t.shape.kind.value),a=e.enum(["A","AAAA"]),n=e.enum(["route53","external-delegated","external-records"]),g=e.enum(["zone","full"]),o=e.object({kind:e.literal("standard"),type:e.enum(["A","AAAA","CNAME","MX","TXT","NS","SRV","CAA"]),name:e.string(),value:e.union([e.string(),e.array(e.string())]),ttl:e.number().int().positive().optional()}).strict(),i=e.object({kind:e.literal("alias"),type:a,name:e.string(),target:r}).strict(),s=e.discriminatedUnion("kind",[o,i]),d=e.object({domainName:e.string(),subjectAlternativeNames:e.array(e.string()).optional(),transparencyLogging:e.boolean().optional(),cloudFront:e.boolean().optional()}).strict(),c=e.object({subdomain:e.string(),toAccount:e.string(),auto:e.boolean().optional()}).strict(),p=e.object({zoneName:e.string(),registrar:n,hostedZoneId:e.string().optional(),delegatedSubdomain:e.string().optional(),adoptedNameServers:e.array(e.string().min(1)).min(1).optional(),records:e.array(s),certificates:e.array(d),delegations:e.array(c)}).strict().refine(t=>t.registrar!=="external-delegated"||t.delegatedSubdomain!==void 0,{message:"external-delegated requires delegatedSubdomain"}).refine(t=>t.registrar!=="external-records"||t.delegations.length===0,{message:"external-records forbids delegations"}).refine(t=>t.registrar==="external-delegated"||t.adoptedNameServers===void 0,{message:"adoptedNameServers requires registrar external-delegated"}).refine(t=>t.registrar!=="external-delegated"||t.hostedZoneId===void 0==(t.adoptedNameServers===void 0),{message:"external-delegated adoption requires hostedZoneId and adoptedNameServers together (both-or-neither)"});export{a as AliasRecordTypeSchema,g as DomainDeployPhaseSchema,n as DomainRegistrarSchema,i as ParsedAliasRecordSchema,d as ParsedCertificateSchema,s as ParsedDnsRecordSchema,p as ParsedDomainRecordsSchema,o as ParsedStandardRecordSchema,c as ParsedSubdomainDelegationSchema,m as TYPED_FJALL_TARGET_KINDS,r as TypedFjallTargetSchema};
|
|
@@ -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
|
|
2
|
-
${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(
|
|
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
|
-
${
|
|
6
|
-
${
|
|
7
|
-
${
|
|
8
|
-
${
|
|
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};
|
|
@@ -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
|
|
2
|
-
secondaryRegions: [${
|
|
3
|
-
`:""}${
|
|
4
|
-
DatabaseFactory.build(${
|
|
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: ${
|
|
7
|
-
databaseName: ${
|
|
6
|
+
type: ${a(t.type)},
|
|
7
|
+
databaseName: ${a(t.databaseName)},`,t.engineExpression?n+=`
|
|
8
8
|
engine: ${t.engineExpression},`:t.databaseEngine&&(n+=`
|
|
9
|
-
databaseEngine: ${
|
|
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: ${
|
|
11
|
+
alarms: ${S(t.alarms," ")},`),t.type!=="GlobalAurora"&&(n+=m()),n+=`
|
|
12
12
|
})
|
|
13
13
|
);
|
|
14
|
-
`}return n}
|
|
15
|
-
`:"",
|
|
16
|
-
DatabaseFactory.build(${
|
|
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: ${
|
|
19
|
-
instanceType: ${
|
|
20
|
-
coldTier: ${
|
|
21
|
-
optimiseSchedule: ${
|
|
22
|
-
backupSchedule: ${
|
|
23
|
-
backupRetentionDays: ${t.backupRetentionDays},`),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}
|
|
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
|
|
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
|
|
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
|
|
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 {};
|