@fjall/generator 14.1.0 → 14.3.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 +50 -45
- package/dist/.minified +1 -1
- package/dist/src/ast/astTestHelpers.d.ts +2 -0
- package/dist/src/ast/domain/astDomainParser.d.ts +24 -0
- package/dist/src/ast/domain/astDomainParser.js +1 -1
- package/dist/src/ast/index.d.ts +1 -1
- package/dist/src/ast/index.js +1 -1
- package/dist/src/ast/parsers/resources/astCdnParser.js +1 -1
- package/dist/src/ast/parsers/resources/astComputeParser.js +1 -1
- package/dist/src/codemod/drift/index.d.ts +1 -1
- package/dist/src/codemod/drift/index.js +1 -1
- package/dist/src/codemod/drift/snapshot.d.ts +33 -1
- package/dist/src/codemod/drift/snapshot.js +1 -1
- package/dist/src/codemod/drift/types.d.ts +16 -1
- package/dist/src/codemod/drift/types.js +1 -1
- package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +8 -0
- package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -1
- package/dist/src/codemod/edits/addResource/siblingEmission.d.ts +61 -0
- package/dist/src/codemod/edits/addResource/siblingEmission.js +1 -0
- package/dist/src/codemod/edits/addResource.js +1 -1
- package/dist/src/codemod/edits/connectResourceToCompute.js +1 -1
- package/dist/src/codemod/edits/ensureImports.d.ts +18 -0
- package/dist/src/codemod/edits/ensureImports.js +1 -1
- package/dist/src/codemod/edits/modifyResource.js +1 -1
- package/dist/src/codemod/edits/resourceStatementLocator.d.ts +3 -0
- package/dist/src/codemod/edits/resourceStatementLocator.js +1 -1
- package/dist/src/codemod/edits/siblingBindingResolution.d.ts +54 -1
- package/dist/src/codemod/edits/siblingBindingResolution.js +1 -1
- package/dist/src/codemod/emitGuard.d.ts +2 -30
- package/dist/src/codemod/emitGuard.js +1 -1
- package/dist/src/codemod/emitProjection.d.ts +31 -2
- package/dist/src/codemod/emitProjection.js +1 -1
- package/dist/src/codemod/fileRewriter/builders.d.ts +18 -0
- package/dist/src/codemod/fileRewriter/builders.js +1 -1
- package/dist/src/codemod/fileRewriter/index.d.ts +1 -1
- package/dist/src/codemod/fileRewriter/index.js +1 -1
- package/dist/src/codemod/index.d.ts +3 -2
- package/dist/src/codemod/index.js +1 -1
- package/dist/src/codemod/llmFallback/index.d.ts +1 -1
- package/dist/src/codemod/llmFallback/index.js +1 -1
- package/dist/src/codemod/llmFallback/shouldTryFallback.d.ts +9 -0
- package/dist/src/codemod/llmFallback/shouldTryFallback.js +1 -1
- package/dist/src/codemod/registry.d.ts +26 -27
- package/dist/src/codemod/registry.js +1 -1
- package/dist/src/codemod/validationGate/gates/projection.js +1 -1
- package/dist/src/dns/domainFileGenerator.js +8 -3
- package/dist/src/dns/domainRecords.d.ts +30 -0
- package/dist/src/dns/domainRecords.js +1 -1
- package/dist/src/dns/tsEmitter.js +9 -9
- package/dist/src/generation/common.js +8 -8
- package/dist/src/generation/connectionWiring.d.ts +83 -0
- package/dist/src/generation/connectionWiring.js +1 -0
- package/dist/src/generation/database.d.ts +3 -34
- package/dist/src/generation/database.js +20 -20
- package/dist/src/generation/index.d.ts +1 -0
- package/dist/src/generation/index.js +1 -1
- package/dist/src/generation/infrastructure.d.ts +11 -0
- package/dist/src/generation/infrastructure.js +38 -28
- package/dist/src/generation/messagingConnections.d.ts +1 -4
- package/dist/src/generation/messagingConnections.js +1 -1
- package/dist/src/generation/storageConnections.d.ts +1 -12
- package/dist/src/generation/storageConnections.js +1 -1
- package/dist/src/planning/resourceAddition.d.ts +3 -0
- package/dist/src/planning/resourceAddition.js +1 -1
- package/dist/src/projection/compute.d.ts +31 -0
- package/dist/src/projection/compute.js +1 -0
- package/dist/src/projection/index.d.ts +3 -2
- package/dist/src/projection/index.js +1 -1
- package/dist/src/projection/project.d.ts +16 -1
- package/dist/src/projection/project.js +1 -1
- package/dist/src/projection/roundTripKeys.d.ts +12 -0
- package/dist/src/projection/roundTripKeys.js +1 -0
- package/dist/src/projection/tables.d.ts +13 -9
- package/dist/src/projection/tables.js +1 -1
- package/dist/src/projection/types.d.ts +204 -4
- package/dist/src/projection/unresolved.d.ts +17 -0
- package/dist/src/projection/unresolved.js +1 -0
- package/dist/src/schemas/applicationSchemas.d.ts +2 -0
- package/dist/src/schemas/cdnSchemas.d.ts +4 -0
- package/dist/src/schemas/cdnSchemas.js +1 -1
- package/dist/src/schemas/computeSchemas.js +1 -1
- package/dist/src/validation/validationMessages.d.ts +1 -0
- package/dist/src/validation/validationMessages.js +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{addResource as o}from"./edits/addResource.js";import{removeResource as c}from"./edits/removeResource.js";import{modifyResource as
|
|
1
|
+
import{addResource as o}from"./edits/addResource.js";import{removeResource as c}from"./edits/removeResource.js";import{modifyResource as a}from"./edits/modifyResource.js";import{appendAccountToStage as s}from"./edits/appendAccountToStage.js";import{setContainerSecrets as E}from"./edits/setContainerSecrets.js";import{connectResourceToCompute as d}from"./edits/connectResourceToCompute.js";import{addVpcPeer as u,modifyVpcPeer as f,removeVpcPeer as R}from"./edits/vpcPeer.js";import{addVpcPeerAccepter as T,modifyVpcPeerAccepter as P,removeVpcPeerAccepter as x}from"./edits/vpcPeerAccepter.js";import{addCrossPlanConnection as C,modifyCrossPlanConnection as v,removeCrossPlanConnection as N}from"./edits/crossPlanConnection.js";import{resolveDriftPolicy as V}from"./edits/driftPolicy.js";import{listResources as h}from"./listResources.js";import{resolveConstructByLiteralProperty as y}from"./semanticIndex/index.js";import{parse as G}from"./fileRewriter/parse.js";import{CrossPlanConnectionResourcePlanSchema as F,VpcPeerAccepterResourcePlanSchema as g,VpcPeerResourcePlanSchema as U}from"../schemas/index.js";import{detectDrift as L,mergeProperties as M,RESOURCE_SNAPSHOT_SCHEMA_VERSION as B,ResourceSnapshotSchema as j,snapshotProperties as H}from"./drift/index.js";import{computeLinesDelta as Y}from"./_internal.js";import{ResourceNameSchema as w,StatementTypeSchema as z}from"./types.js";import{REGISTERED_STATEMENT_TYPES as Q,STATEMENT_REGISTRY as W}from"./registry.js";import{evaluateEmitGuard as Z,UNRESOLVED as $}from"./emitGuard.js";import{projectionRefusals as re}from"./emitProjection.js";import{CODEMOD_ERROR_KINDS as te}from"./telemetry/errorKinds.js";import{buildEgressBlockedEvent as pe,buildFiredEvent as ae,buildGateFailedEvent as me,buildGatePassedEvent as se,buildRejectedEvent as ne,buildSucceededEvent as Ee,buildTimeoutEvent as le,estimateCostUsd as de,FALLBACK_EVENTS as ie,GATE_EVENTS as ue,gateFallbackOutput as fe,matchFallbackTrigger as Re,PARSE_GATE as Se,RUNTIME_GATE as Te,runFallback as Pe,shouldTryFallback as xe,UNATTRIBUTED_ORGANISATION as Ae}from"./llmFallback/index.js";export{te as CODEMOD_ERROR_KINDS,F as CrossPlanConnectionResourcePlanSchema,ie as FALLBACK_EVENTS,ue as GATE_EVENTS,Se as PARSE_GATE,Q as REGISTERED_STATEMENT_TYPES,B as RESOURCE_SNAPSHOT_SCHEMA_VERSION,Te as RUNTIME_GATE,w as ResourceNameSchema,j as ResourceSnapshotSchema,W as STATEMENT_REGISTRY,z as StatementTypeSchema,Ae as UNATTRIBUTED_ORGANISATION,$ as UNRESOLVED,g as VpcPeerAccepterResourcePlanSchema,U as VpcPeerResourcePlanSchema,C as addCrossPlanConnection,o as addResource,u as addVpcPeer,T as addVpcPeerAccepter,s as appendAccountToStage,pe as buildEgressBlockedEvent,ae as buildFiredEvent,me as buildGateFailedEvent,se as buildGatePassedEvent,ne as buildRejectedEvent,Ee as buildSucceededEvent,le as buildTimeoutEvent,Y as computeLinesDelta,d as connectResourceToCompute,L as detectDrift,de as estimateCostUsd,Z as evaluateEmitGuard,fe as gateFallbackOutput,h as listResources,Re as matchFallbackTrigger,M as mergeProperties,v as modifyCrossPlanConnection,a as modifyResource,f as modifyVpcPeer,P as modifyVpcPeerAccepter,G as parse,re as projectionRefusals,N as removeCrossPlanConnection,c as removeResource,R as removeVpcPeer,x as removeVpcPeerAccepter,y as resolveConstructByLiteralProperty,V as resolveDriftPolicy,Pe as runFallback,E as setContainerSecrets,xe as shouldTryFallback,H as snapshotProperties};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { runFallback, type FallbackClients, type RunFallbackInput, } from "./runFallback.js";
|
|
2
2
|
export { gateFallbackOutput, type GateEventAction, type GateFallbackParams, } from "./gateFallbackOutput.js";
|
|
3
|
-
export { shouldTryFallback, type FallbackDecision, type FallbackGuardConfig, } from "./shouldTryFallback.js";
|
|
3
|
+
export { matchFallbackTrigger, shouldTryFallback, type FallbackDecision, type FallbackGuardConfig, } from "./shouldTryFallback.js";
|
|
4
4
|
export { buildEgressBlockedEvent, buildFiredEvent, buildGateFailedEvent, buildGatePassedEvent, buildRejectedEvent, buildSucceededEvent, buildTimeoutEvent, estimateCostUsd, FALLBACK_EVENTS, GATE_EVENTS, UNATTRIBUTED_ORGANISATION, type FallbackEgressBlockedEvent, type FallbackFiredEvent, type FallbackRejectedEvent, type FallbackSucceededEvent, type FallbackTelemetryEvent, type FallbackTimeoutEvent, type GateFailedEvent, type GatePassedEvent, type TelemetrySource, } from "./telemetryEvents.js";
|
|
5
5
|
export { PARSE_GATE, RUNTIME_GATE } from "./types.js";
|
|
6
6
|
export type { AnthropicClientProvider, AnthropicContentBlock, AnthropicResponse, ApplyResult, EgressStage, FallbackInput, FallbackIntent, FallbackOp, FallbackOutput, FallbackTelemetry, MorphClientProvider, MorphResponse, StrReplaceOp, TriggerReason, } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{runFallback as
|
|
1
|
+
import{runFallback as l}from"./runFallback.js";import{gateFallbackOutput as d}from"./gateFallbackOutput.js";import{matchFallbackTrigger as a,shouldTryFallback as o}from"./shouldTryFallback.js";import{buildEgressBlockedEvent as T,buildFiredEvent as i,buildGateFailedEvent as b,buildGatePassedEvent as c,buildRejectedEvent as A,buildSucceededEvent as m,buildTimeoutEvent as n,estimateCostUsd as s,FALLBACK_EVENTS as v,GATE_EVENTS as F,UNATTRIBUTED_ORGANISATION as p}from"./telemetryEvents.js";import{PARSE_GATE as N,RUNTIME_GATE as f}from"./types.js";export{v as FALLBACK_EVENTS,F as GATE_EVENTS,N as PARSE_GATE,f as RUNTIME_GATE,p as UNATTRIBUTED_ORGANISATION,T as buildEgressBlockedEvent,i as buildFiredEvent,b as buildGateFailedEvent,c as buildGatePassedEvent,A as buildRejectedEvent,m as buildSucceededEvent,n as buildTimeoutEvent,s as estimateCostUsd,d as gateFallbackOutput,a as matchFallbackTrigger,l as runFallback,o as shouldTryFallback};
|
|
@@ -11,3 +11,12 @@ export type FallbackDecision = {
|
|
|
11
11
|
shouldTry: false;
|
|
12
12
|
};
|
|
13
13
|
export declare function shouldTryFallback(error: CodemodError, config: FallbackGuardConfig): FallbackDecision;
|
|
14
|
+
/**
|
|
15
|
+
* The trigger kind a failure would fall back under, or undefined when no
|
|
16
|
+
* amount of enablement could make the fallback attempt it.
|
|
17
|
+
*
|
|
18
|
+
* Pure and local — no config, no I/O. Consumers whose enablement lookup costs
|
|
19
|
+
* something (the CLI reads org config over the network) ask this first, so a
|
|
20
|
+
* failure the fallback can never handle stays free.
|
|
21
|
+
*/
|
|
22
|
+
export declare function matchFallbackTrigger(error: CodemodError): TriggerReason | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var o=Object.defineProperty;var n=(r,e)=>o(r,"name",{value:e,configurable:!0});const t={shouldTry:!1};function i(r,e){if(!e.envEnabled||!e.orgAllowsFallback)return t;const l=
|
|
1
|
+
var o=Object.defineProperty;var n=(r,e)=>o(r,"name",{value:e,configurable:!0});const t={shouldTry:!1};function i(r,e){if(!e.envEnabled||!e.orgAllowsFallback)return t;const l=a(r);return l===void 0?t:{shouldTry:!0,trigger:l}}n(i,"shouldTryFallback");function a(r){switch(r.kind){case"TemplateLiteralNameError":return"template-literal-name";case"ResourceNotFoundError":return"resource-not-found";case"ControlFlowClassifierError":return r.reason==="anonymous-helper"?"control-flow-unclassifiable":void 0;case"DriftUnmergeableError":return"drift-unmergeable";default:return}}n(a,"matchFallbackTrigger");export{a as matchFallbackTrigger,i as shouldTryFallback};
|
|
@@ -30,18 +30,19 @@ export interface StatementTypeEntry {
|
|
|
30
30
|
/**
|
|
31
31
|
* The ADD path's required-aware input contract: the plan schema minus
|
|
32
32
|
* `name`, WITHOUT `.partial()`, so a first-time add must carry every
|
|
33
|
-
* required plan key (`database` demands `type` + `databaseName`
|
|
34
|
-
* as satisfying the per-key
|
|
35
|
-
* delta contract for MODIFY.
|
|
33
|
+
* required plan key (`database` demands `type` + `databaseName`; `compute`
|
|
34
|
+
* demands `type` + `needsConnection`) as well as satisfying the per-key
|
|
35
|
+
* shapes. `schemaFragment` stays the partial delta contract for MODIFY.
|
|
36
36
|
*
|
|
37
37
|
* Declared ONLY for guard-free types, and that is a rule, not a
|
|
38
|
-
* convenience: a guarded type's required plan keys
|
|
39
|
-
* scaffold-consumed keys its own guard
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* type's projection and deletes its guard table, declare
|
|
44
|
-
* the same edit — the schema-gate XOR test pins the
|
|
38
|
+
* convenience: a guarded type's required plan keys would be exactly the
|
|
39
|
+
* scaffold-consumed keys its own guard refuses to write — the catch-22
|
|
40
|
+
* `compute` sat in until its projection landed (its guard `silentlyDropped`
|
|
41
|
+
* the required `needsConnection`, so demanding it at the gate was
|
|
42
|
+
* unsatisfiable; the projection's expansion now CONSUMES it). When an
|
|
43
|
+
* increment lands a type's projection and deletes its guard table, declare
|
|
44
|
+
* `addContract` in the same edit — the schema-gate XOR test pins the
|
|
45
|
+
* pairing. `vpc-peer`, the one guarded type left, correctly declares none.
|
|
45
46
|
*
|
|
46
47
|
* Absent = the schema gate applies `schemaFragment` to adds too
|
|
47
48
|
* (unknown-key and per-key-shape checks only, no required demand).
|
|
@@ -87,21 +88,19 @@ export interface StatementTypeEntry {
|
|
|
87
88
|
* ONLY for types the plan→construct projection cannot describe. Where it
|
|
88
89
|
* can (`src/projection/tables.ts`), the disagreement is TRANSLATED at
|
|
89
90
|
* emission and no rule belongs here — `emitProjection.ts` reports what is
|
|
90
|
-
* left from the projection's own `unprojectable` list
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
91
|
+
* left from the projection's own `unprojectable` list; a live sibling
|
|
92
|
+
* binding is expressible through a `live` rule (`cdn`'s origin), a second
|
|
93
|
+
* statement through a sibling projection (`compute`'s schedule), a merged
|
|
94
|
+
* prop through a fragment expansion (`compute`'s connection keys), and a
|
|
95
|
+
* key combination through a `crossKey` rule. What survives is `vpc-peer`
|
|
96
|
+
* alone: required-key conditions whose absence deploys silently wrong
|
|
97
|
+
* infrastructure.
|
|
94
98
|
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* always wrong.
|
|
101
|
-
* · SILENTLY DROPPED — the construct never reads the plan key, so the
|
|
102
|
-
* resource deploys without the behaviour that was requested. Proven
|
|
103
|
-
* per key: zero `props.<key>` reads anywhere in
|
|
104
|
-
* @fjall/components-infrastructure.
|
|
99
|
+
* The one class rules still cover: a required key whose ABSENCE deploys
|
|
100
|
+
* silently wrong infrastructure — synth succeeds, the deploy is green, and
|
|
101
|
+
* the emitted resource points at garbage (`vpc-peer`'s two required
|
|
102
|
+
* members). Refusing at write time is the only net, because `cdk.json`
|
|
103
|
+
* runs `infrastructure.ts` through tsx, which does not typecheck.
|
|
105
104
|
*
|
|
106
105
|
* Deliberately NOT covered: INCOMPLETE input, where the vocabulary can
|
|
107
106
|
* express a working call and the operator has not yet — that is
|
|
@@ -114,9 +113,9 @@ export interface StatementTypeEntry {
|
|
|
114
113
|
* Absent = every expressible property shape for this type reaches a
|
|
115
114
|
* synthesising statement. That is a claim, not an oversight, and it is now
|
|
116
115
|
* true two ways: `network` and `buildkite` have outright plan/construct
|
|
117
|
-
* parity, while `database`, `storage` and `
|
|
118
|
-
* projection. The components-infrastructure materialisation
|
|
119
|
-
* both.
|
|
116
|
+
* parity, while `database`, `storage`, `messaging` and `compute` reach it
|
|
117
|
+
* through the projection. The components-infrastructure materialisation
|
|
118
|
+
* contract pins both.
|
|
120
119
|
*/
|
|
121
120
|
emitGuard?: ReadonlyArray<EmitGuardRule>;
|
|
122
121
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var R=Object.defineProperty;var r=(e,t)=>R(e,"name",{value:t,configurable:!0});import{DEPLOYABLE_PATTERN_TYPES as I,PATTERN_TYPE_VALUES as N,isPatternType as M,patternConstructId as m}from"@fjall/util";import{z as s}from"zod";import{BuildkitePropsObjectSchema as u,CDNResourcePlanSchema as l,ComputeResourcePlanSchema as g,CrossPlanConnectionResourcePlanSchema as h,DatabaseResourcePlanSchema as y,NetworkResourcePlanSchema as P,NextJSPatternConfigSchema as v,OrganisationResourcePlanSchema as S,PayloadPatternConfigSchema as w,S3ResourcePlanSchema as C,SQSResourcePlanSchema as f,StaticSitePatternConfigSchema as O,VpcPeerAccepterResourcePlanSchema as F,VpcPeerResourcePlanSchema as W}from"../schemas/index.js";import{failure as x}from"../types/Result.js";import{whenAbsent as b}from"./emitGuard.js";const n={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 c(e){const{name:t,...a}=e.shape;return s.object(a).partial().strict()}r(c,"fragmentOf");function p(e){const{name:t,...a}=e.shape;return s.object(a).strict()}r(p,"completeFragmentOf");const j=c(y),B=c(C),V=(()=>{const{name:e,...t}=g.shape;return s.object(t).partial().strict()})(),D=(()=>{const{name:e,...t}=g.shape;return s.object(t).strict()})(),Y=c(f),G=c(l),L=c(P),E=(()=>{const{name:e,type:t,cdn:a,...A}=w.shape,{name:te,type:re,cdn:ae,...T}=v.shape,{name:ne,type:oe,domain:ce,cdn:_,...k}=O.shape;return{...A,...T,...k,cdn:s.union([a,_]),type:s.enum(I)}})(),q=s.object(E).partial().strict(),Q=s.object(E).partial().required({type:!0}).strict(),U={emitConstructId:r((e,t)=>M(t.type)?m(e,t.type):e,"emitConstructId"),locateCandidates:r(e=>[e,...N.map(t=>m(e,t))],"locateCandidates")},$=c(W),z=c(F),J=c(h),H=c(S),K=c(u);function d(e,t){return x({kind:"SemanticQueryError",reason:`StatementTypeEntry.${e} for ${t} is not wired; existing types dispatch through the shared locator/generator.`})}r(d,"notWiredError");function X(e){return{factoryIdentifier:e,findByShape:r(()=>d("locator.findByShape",e),"findByShape"),validateContext:r(()=>d("locator.validateContext",e),"validateContext")}}r(X,"createLocator");function Z(e){return{build:r(()=>{const t=d("generator.build",e);throw new Error(t.success?"unreachable":t.error.reason)},"build")}}r(Z,"createGenerator");const ee=[{property:"peerAppName",refuseWhen:b("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:b("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,a={}){return{factoryIdentifier:e,locator:X(e),generator:Z(e),schemaFragment:t,...a}}r(o,"createEntry");const i={database:o(n.database,j,{emitWrapper:{appMethod:"addDatabase"},addContract:p(y)}),storage:o(n.storage,B,{emitWrapper:{appMethod:"addStorage"},addContract:p(C)}),compute:o(n.compute,V,{emitWrapper:{appMethod:"addCompute"},addContract:D}),messaging:o(n.messaging,Y,{emitWrapper:{appMethod:"addMessaging"},addContract:p(f)}),cdn:o(n.cdn,G,{emitWrapper:{appMethod:"addCdn"},addContract:p(l)}),network:o(n.network,L,{emitWrapper:{appMethod:"addNetwork"},addContract:p(P)}),pattern:o(n.pattern,q,{emitWrapper:{appMethod:"addPattern"},addContract:Q,statementIdentity:U}),"vpc-peer":o(n["vpc-peer"],$,{emitWrapper:{appMethod:"addVpcPeer"},emitGuard:ee}),"vpc-peer-accepter":o(n["vpc-peer-accepter"],z,{emitWrapper:{appMethod:"addVpcPeerAccepter"},addContract:p(F)}),"cross-plan-connection":o(n["cross-plan-connection"],J,{addContract:p(h)}),organisation:o(n.organisation,H,{addContract:p(S)}),buildkite:o(n.buildkite,K,{emitWrapper:{appMethod:"addBuildkite",propsOverloadConstructId:"Buildkite"},addContract:p(u)})},le=Object.keys(i);function ge(e,t,a){return i[e].statementIdentity?.emitConstructId(t,a)??t}r(ge,"constructIdFor");function he(e,t){return i[e].statementIdentity?.locateCandidates(t)??[t]}r(he,"locateNamesFor");function ye(e){const t=Object.keys(i);for(const a of t)if(i[a].factoryIdentifier===e)return a}r(ye,"findTypeByIdentifier");export{n as FACTORY_IDENTIFIERS,le as REGISTERED_STATEMENT_TYPES,i as STATEMENT_REGISTRY,ge as constructIdFor,ye as findTypeByIdentifier,he as locateNamesFor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var N=Object.defineProperty;var d=(r,t)=>N(r,"name",{value:t,configurable:!0});import{failure as c,success as p}from"../../../types/Result.js";import{isProjectableType as v,TYPE_PROJECTIONS as k}from"../../../projection/index.js";import{extractProgramBody as O}from"../../_internal.js";import{findConfigObject as w}from"../../drift/snapshot.js";import{bodyCarriesSibling as E,siblingCallPropsObject as K}from"../../edits/addResource/siblingEmission.js";import{astToLiteral as S,isNodeShape as T,NON_LITERAL as x,readKeyName as j}from"../../edits/modifyResource/literalConversion.js";import{parse as M}from"../../fileRewriter/parse.js";import{constructIdFor as C,STATEMENT_REGISTRY as L}from"../../registry.js";import{locateByShape as R}from"../../semanticIndex/locateByShape.js";function _(r){if(!v(r))return[];const t=k[r].keys??{};return Object.entries(t).flatMap(([e,i])=>i.kind==="live"?[{planKey:e,constructKey:i.as??e,reason:i.reason,wants:"live binding"}]:i.kind==="structured"?[{planKey:e,constructKey:i.as??e,reason:i.reason,wants:"structured CDK expression"}]:[])}d(_,"shapeCheckedKeys");function u(r){return p({action:"reject",diagnostics:r})}d(u,"rejectOutcome");function A(r,t){if(r.plan.op!=="modify"||t?.expansion===void 0)return;const e=t.expansion;if(!e.keys.some(f=>r.plan.properties[f]!==void 0))return;const i=e.derive(r.plan.properties,{resourceName:r.plan.name,editingExisting:!0}),[o]=i.unprojectable;if(o!==void 0)return c({kind:"InvalidPropertyError",property:o.key,reason:o.reason})}d(A,"expansionModifyParity");const W={id:"projection",run(r){const{type:t,name:e,op:i}=r.plan,o=v(t)?k[t]:void 0,f=A(r,o);if(f!==void 0)return f;const I=o?.siblings!==void 0?o.siblings.keys.filter(n=>r.plan.properties[n]!==void 0):[];let y=[];if(I.length>0&&o?.siblings!==void 0){const n=o.siblings.derive(r.plan.properties,{resourceName:e}),[s]=n.unprojectable;if(s!==void 0)return c({kind:"InvalidPropertyError",property:s.key,reason:s.reason});const[a]=n.siblings;if(i!=="add"&&a!==void 0)return c({kind:"InvalidPropertyError",property:a.planKey,reason:`\`${a.planKey}\` expands into its own \`app.${a.appMethod}("${a.constructId}", \u2026)\` statement, and a modify edits exactly one statement \u2014 the deterministic lane refuses this edit and the fallback lane holds the same line.`});y=n.siblings}const m=_(t),h=i==="add"&&L[t].statementIdentity!==void 0;if(m.length===0&&!h&&y.length===0)return p({action:"proceed"});const l=B(r);if(!l.success)return l;if(l.data===void 0)return u(`could not resolve the emitted config object for ${t} "${e}"; the output cannot be verified against the projection contract`);const{symbolName:b,configObject:g,body:$}=l.data;for(const n of m){const s=P(g,n.constructKey);if(s!==void 0&&(s.type==="StringLiteral"||s.type==="TemplateLiteral"))return c({kind:"InvalidPropertyError",property:n.constructKey,reason:`the ${t} construct reads a ${n.wants} here and the output wrote a ${s.type==="StringLiteral"?"string":"template"} literal; ${n.reason}`})}for(const n of y){if(!E($,n))return u(`the \`${n.planKey}\` key expands into a second statement \`app.${n.appMethod}("${n.constructId}", \u2026)\` and the output does not carry it \u2014 the primary resource would deploy with the expansion silently missing`);if(n.props.length===0)continue;const s=K($,n);if(s===void 0)return u(`the \`${n.planKey}\` expansion statement \`app.${n.appMethod}("${n.constructId}", \u2026)\` carries no readable props object, so it cannot be verified against the props the projection derives (${n.props.map(a=>`\`${a.key}\``).join(", ")})`);for(const a of n.props)if(P(s,a.key)===void 0)return u(`the \`${n.planKey}\` expansion statement \`app.${n.appMethod}("${n.constructId}", \u2026)\` omits the derived prop \`${a.key}\` \u2014 the deterministic lane always emits it, and without it the expansion deploys wrong or incomplete infrastructure`)}if(h){const n=G(g),s=C(t,e,n);if(b!==s)return u(`output writes construct id "${b}" where the ${t} identity derivation for "${e}" requires "${s}" \u2014 an id the deterministic lane never emits (the type declares an identity precisely because non-derived ids collide or go unaddressable at synth)`)}return p({action:"proceed"})}};function B(r){const t=R(r.content,{type:r.plan.type,name:r.plan.name});if(!t.success)return c(t.error);if(t.data===void 0)return p(void 0);const e=M(r.content,t.data.filePath);if(!e.success)return c(e.error);const i=O(e.data);if(i===void 0)return p(void 0);const o=w(i,{start:t.data.start,length:t.data.length});return o===void 0?p(void 0):p({symbolName:t.data.symbolName,configObject:o,body:i})}d(B,"locateEmittedStatement");function P(r,t){for(const e of r.properties)if(!(e.type!=="Property"&&e.type!=="ObjectProperty")&&!(e.shorthand===!0||e.computed===!0)&&j(e.key)===t&&e.value!==void 0&&T(e.value))return e.value}d(P,"readPropertyValueNode");function G(r){const t={};for(const e of r.properties){if(e.type!=="Property"&&e.type!=="ObjectProperty"||e.shorthand===!0||e.computed===!0)continue;const i=j(e.key);if(i===void 0||e.value===void 0)continue;const o=S(e.value);o!==x&&(t[i]=o)}return t}d(G,"literalPropertiesOf");export{W as projectionGate};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var p=Object.defineProperty;var o=(t,e)=>p(t,"name",{value:e,configurable:!0});import{getDomainStackName as g}from"@fjall/util";import{toPascalCase as
|
|
1
|
+
var p=Object.defineProperty;var o=(t,e)=>p(t,"name",{value:e,configurable:!0});import{getDomainStackName as g}from"@fjall/util";import{toPascalCase as h}from"../generation/common.js";import{GENERATOR_VERSION as d}from"../version.js";function I(t){const{domainName:e,hostedZoneId:r,records:n=[]}=t,a=t.basePath??`fjall/domains/${e}`;return[{path:`${a}/infrastructure.ts`,content:w({domainName:e,records:n,hostedZoneId:r})},{path:`${a}/package.json`,content:f(e)},{path:`${a}/tsconfig.json`,content:y},{path:`${a}/cdk.json`,content:N},{path:`${a}/cdk.context.json`,content:S},{path:`${a}/.gitignore`,content:k}]}o(I,"generateDomainFiles");function w(t){const{domainName:e,records:r,hostedZoneId:n}=t,a=h(e.split(".").join("")),i=g(e),c=r.map(s=>{const m=s.ttl!==void 0?`, ttl: ${s.ttl}`:"";return` { type: ${JSON.stringify(s.type)}, name: ${JSON.stringify(s.name)}, value: ${JSON.stringify(s.value)}${m} },`}),l=c.length>0?`[
|
|
2
2
|
${c.join(`
|
|
3
3
|
`)}
|
|
4
4
|
]`:"[]",u=n?` hostedZoneId: ${JSON.stringify(n)},
|
|
@@ -19,7 +19,12 @@ const stack = app.getStack(${JSON.stringify(i)}).getStack();
|
|
|
19
19
|
new Domain(stack, ${JSON.stringify(a)}, {
|
|
20
20
|
registrar: "route53",
|
|
21
21
|
zoneName: ${JSON.stringify(e)},
|
|
22
|
-
${u}
|
|
22
|
+
${u} // Position-independent record logical IDs (fresh-zone default): records
|
|
23
|
+
// can be inserted, removed, or reordered freely. Never remove this line
|
|
24
|
+
// once the zone has deployed \u2014 flipping the mode renames every record's
|
|
25
|
+
// logical ID (a deliberate two-deploy migration, never a casual edit).
|
|
26
|
+
recordIds: "stable",
|
|
27
|
+
certificates: [
|
|
23
28
|
{ domainName: ${JSON.stringify(e)} },
|
|
24
29
|
// Serving this zone through CloudFront (staticsite/cdn)? Add a viewer
|
|
25
30
|
// certificate with cloudFront: true \u2014 it is minted in us-east-1 (the
|
|
@@ -39,7 +44,7 @@ ${u} certificates: [
|
|
|
39
44
|
// and adoptedNameServers (both together) on the child Domain \u2014 the literals
|
|
40
45
|
// feed the parent NS UPSERT because an imported zone exposes no name-server
|
|
41
46
|
// attribute at synth.
|
|
42
|
-
`}o(
|
|
47
|
+
`}o(w,"generateDefaultInfrastructureTs");function f(t){return`{
|
|
43
48
|
"name": ${JSON.stringify(`domain-${t}`)},
|
|
44
49
|
"version": "${d}",
|
|
45
50
|
"type": "module",
|
|
@@ -40,6 +40,14 @@ export declare const DomainDeployPhaseSchema: z.ZodEnum<{
|
|
|
40
40
|
full: "full";
|
|
41
41
|
}>;
|
|
42
42
|
export type DomainDeployPhase = z.infer<typeof DomainDeployPhaseSchema>;
|
|
43
|
+
/**
|
|
44
|
+
* Per-record construct-id override (`recordIds: "stable"` collision escape
|
|
45
|
+
* hatch) — mirrors `StandardRecord.id` / `AliasRecord.id` in
|
|
46
|
+
* @fjall/components-infrastructure, which validates the same shape (it
|
|
47
|
+
* becomes a CloudFormation logical-ID segment).
|
|
48
|
+
*/
|
|
49
|
+
export declare const RecordConstructIdSchema: z.ZodString;
|
|
50
|
+
export type RecordConstructId = z.infer<typeof RecordConstructIdSchema>;
|
|
43
51
|
export declare const ParsedStandardRecordSchema: z.ZodObject<{
|
|
44
52
|
kind: z.ZodLiteral<"standard">;
|
|
45
53
|
type: z.ZodEnum<{
|
|
@@ -55,6 +63,7 @@ export declare const ParsedStandardRecordSchema: z.ZodObject<{
|
|
|
55
63
|
name: z.ZodString;
|
|
56
64
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
57
65
|
ttl: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
id: z.ZodOptional<z.ZodString>;
|
|
58
67
|
}, z.core.$strict>;
|
|
59
68
|
export declare const ParsedAliasRecordSchema: z.ZodObject<{
|
|
60
69
|
kind: z.ZodLiteral<"alias">;
|
|
@@ -78,6 +87,7 @@ export declare const ParsedAliasRecordSchema: z.ZodObject<{
|
|
|
78
87
|
dnsName: z.ZodString;
|
|
79
88
|
hostedZoneId: z.ZodString;
|
|
80
89
|
}, z.core.$strict>], "kind">;
|
|
90
|
+
id: z.ZodOptional<z.ZodString>;
|
|
81
91
|
}, z.core.$strict>;
|
|
82
92
|
export declare const ParsedDnsRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
83
93
|
kind: z.ZodLiteral<"standard">;
|
|
@@ -94,6 +104,7 @@ export declare const ParsedDnsRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
94
104
|
name: z.ZodString;
|
|
95
105
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
96
106
|
ttl: z.ZodOptional<z.ZodNumber>;
|
|
107
|
+
id: z.ZodOptional<z.ZodString>;
|
|
97
108
|
}, z.core.$strict>, z.ZodObject<{
|
|
98
109
|
kind: z.ZodLiteral<"alias">;
|
|
99
110
|
type: z.ZodEnum<{
|
|
@@ -116,6 +127,7 @@ export declare const ParsedDnsRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
116
127
|
dnsName: z.ZodString;
|
|
117
128
|
hostedZoneId: z.ZodString;
|
|
118
129
|
}, z.core.$strict>], "kind">;
|
|
130
|
+
id: z.ZodOptional<z.ZodString>;
|
|
119
131
|
}, z.core.$strict>], "kind">;
|
|
120
132
|
export declare const ParsedCertificateSchema: z.ZodObject<{
|
|
121
133
|
domainName: z.ZodString;
|
|
@@ -128,6 +140,18 @@ export declare const ParsedSubdomainDelegationSchema: z.ZodObject<{
|
|
|
128
140
|
toAccount: z.ZodString;
|
|
129
141
|
auto: z.ZodOptional<z.ZodBoolean>;
|
|
130
142
|
}, z.core.$strict>;
|
|
143
|
+
/**
|
|
144
|
+
* Construct-id scheme for the records list — mirrors
|
|
145
|
+
* `DomainCommonProps.recordIds`. `"stable"` derives position-independent
|
|
146
|
+
* logical IDs (records can be inserted/removed/reordered freely);
|
|
147
|
+
* `"indexed"`/absent is the legacy position-coupled formula (append-only
|
|
148
|
+
* lists, byte-frozen for deployed stacks). Fresh imports emit `"stable"`.
|
|
149
|
+
*/
|
|
150
|
+
export declare const RecordIdsModeSchema: z.ZodEnum<{
|
|
151
|
+
stable: "stable";
|
|
152
|
+
indexed: "indexed";
|
|
153
|
+
}>;
|
|
154
|
+
export type RecordIdsMode = z.infer<typeof RecordIdsModeSchema>;
|
|
131
155
|
export declare const ParsedDomainRecordsSchema: z.ZodObject<{
|
|
132
156
|
zoneName: z.ZodString;
|
|
133
157
|
registrar: z.ZodEnum<{
|
|
@@ -135,6 +159,10 @@ export declare const ParsedDomainRecordsSchema: z.ZodObject<{
|
|
|
135
159
|
"external-delegated": "external-delegated";
|
|
136
160
|
"external-records": "external-records";
|
|
137
161
|
}>;
|
|
162
|
+
recordIds: z.ZodOptional<z.ZodEnum<{
|
|
163
|
+
stable: "stable";
|
|
164
|
+
indexed: "indexed";
|
|
165
|
+
}>>;
|
|
138
166
|
hostedZoneId: z.ZodOptional<z.ZodString>;
|
|
139
167
|
delegatedSubdomain: z.ZodOptional<z.ZodString>;
|
|
140
168
|
adoptedNameServers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -153,6 +181,7 @@ export declare const ParsedDomainRecordsSchema: z.ZodObject<{
|
|
|
153
181
|
name: z.ZodString;
|
|
154
182
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
155
183
|
ttl: z.ZodOptional<z.ZodNumber>;
|
|
184
|
+
id: z.ZodOptional<z.ZodString>;
|
|
156
185
|
}, z.core.$strict>, z.ZodObject<{
|
|
157
186
|
kind: z.ZodLiteral<"alias">;
|
|
158
187
|
type: z.ZodEnum<{
|
|
@@ -175,6 +204,7 @@ export declare const ParsedDomainRecordsSchema: z.ZodObject<{
|
|
|
175
204
|
dnsName: z.ZodString;
|
|
176
205
|
hostedZoneId: z.ZodString;
|
|
177
206
|
}, z.core.$strict>], "kind">;
|
|
207
|
+
id: z.ZodOptional<z.ZodString>;
|
|
178
208
|
}, z.core.$strict>], "kind">>;
|
|
179
209
|
certificates: z.ZodArray<z.ZodObject<{
|
|
180
210
|
domainName: 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(),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()]),
|
|
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()]),p=r.options.map(t=>t.shape.kind.value),n=e.enum(["A","AAAA"]),o=e.enum(["route53","external-delegated","external-records"]),u=e.enum(["zone","full"]),a=e.string().regex(/^[A-Za-z][A-Za-z0-9]*$/),i=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(),id:a.optional()}).strict(),s=e.object({kind:e.literal("alias"),type:n,name:e.string(),target:r,id:a.optional()}).strict(),d=e.discriminatedUnion("kind",[i,s]),c=e.object({domainName:e.string(),subjectAlternativeNames:e.array(e.string()).optional(),transparencyLogging:e.boolean().optional(),cloudFront:e.boolean().optional()}).strict(),l=e.object({subdomain:e.string(),toAccount:e.string(),auto:e.boolean().optional()}).strict(),m=e.enum(["indexed","stable"]),x=e.object({zoneName:e.string(),registrar:o,recordIds:m.optional(),hostedZoneId:e.string().optional(),delegatedSubdomain:e.string().optional(),adoptedNameServers:e.array(e.string().min(1)).min(1).optional(),records:e.array(d),certificates:e.array(c),delegations:e.array(l)}).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{n as AliasRecordTypeSchema,u as DomainDeployPhaseSchema,o as DomainRegistrarSchema,s as ParsedAliasRecordSchema,c as ParsedCertificateSchema,d as ParsedDnsRecordSchema,x as ParsedDomainRecordsSchema,i as ParsedStandardRecordSchema,l as ParsedSubdomainDelegationSchema,a as RecordConstructIdSchema,m as RecordIdsModeSchema,p as TYPED_FJALL_TARGET_KINDS,r as TypedFjallTargetSchema};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var A=Object.defineProperty;var o=(e,n)=>A(e,"name",{value:n,configurable:!0});import{getDomainStackName as k,toPascalCase as D}from"@fjall/util";const O=["A","AAAA","CNAME","MX","TXT","NS","SRV","CAA"],
|
|
2
|
-
`):e,
|
|
3
|
-
`):n;return t.localeCompare(
|
|
1
|
+
var A=Object.defineProperty;var o=(e,n)=>A(e,"name",{value:n,configurable:!0});import{getDomainStackName as k,toPascalCase as D}from"@fjall/util";const O=["A","AAAA","CNAME","MX","TXT","NS","SRV","CAA"],J=new Map(O.map((e,n)=>[e,n]));function b(e,n){return e==="@"&&n!=="@"?-1:e!=="@"&&n==="@"?1:e.localeCompare(n)}o(b,"compareName");function C(e,n){const t=Array.isArray(e)?e.join(`
|
|
2
|
+
`):e,i=Array.isArray(n)?n.join(`
|
|
3
|
+
`):n;return t.localeCompare(i)}o(C,"compareValue");function p(e){const n=e.kind==="standard"?0:1,t=J.get(e.type)??99;return[n,t,e.name]}o(p,"recordSortKey");function R(e){return[...e].sort((n,t)=>{const[i,c,f]=p(n),[s,d,m]=p(t);if(i!==s)return i-s;if(c!==d)return c-d;const u=b(f,m);return u!==0?u:n.kind==="standard"&&t.kind==="standard"?C(n.value,t.value):0})}o(R,"sortRecords");function I(e){return Array.isArray(e)?`[${e.map(t=>JSON.stringify(t)).join(", ")}]`:JSON.stringify(e)}o(I,"formatValue");function P(e){const n=[`type: ${JSON.stringify(e.type)}`,`name: ${JSON.stringify(e.name)}`];return e.id!==void 0&&n.push(`id: ${JSON.stringify(e.id)}`),n.push(`value: ${I(e.value)}`),e.ttl!==void 0&&n.push(`ttl: ${e.ttl}`),`{ ${n.join(", ")} }`}o(P,"emitStandardRecord");function v(e){switch(e.kind){case"ecs":return e.computeName===void 0?`fjallApp(${JSON.stringify(e.appName)})`:`fjallApp(${JSON.stringify(e.appName)}, ${JSON.stringify(e.computeName)})`;case"cdn":return`fjallCdn(${JSON.stringify(e.appName)})`;case"bucket":return`fjallBucket(${JSON.stringify(e.bucketName)})`;case"custom":return`aliasTo(${JSON.stringify(e.dnsName)}, ${JSON.stringify(e.hostedZoneId)})`}}o(v,"emitAliasTarget");function x(e){const n=[`type: ${JSON.stringify(e.type)}`,`name: ${JSON.stringify(e.name)}`];return e.id!==void 0&&n.push(`id: ${JSON.stringify(e.id)}`),n.push(`target: ${v(e.target)}`),`{ ${n.join(", ")} }`}o(x,"emitAliasRecord");function T(e){return e.kind==="standard"?P(e):x(e)}o(T,"emitRecordObjectText");function w(e){return` ${T(e)},`}o(w,"emitRecord");function z(e){const n=[`domainName: ${JSON.stringify(e.domainName)}`];if(e.subjectAlternativeNames&&e.subjectAlternativeNames.length>0){const t=e.subjectAlternativeNames.map(i=>JSON.stringify(i)).join(", ");n.push(`subjectAlternativeNames: [${t}]`)}return e.transparencyLogging!==void 0&&n.push(`transparencyLogging: ${e.transparencyLogging}`),e.cloudFront!==void 0&&n.push(`cloudFront: ${e.cloudFront}`),` { ${n.join(", ")} },`}o(z,"emitCertificate");function B(e,n){if(n.length===0)return"";const t=["","// Delegations (D8 \u2014 child writes NS; no parent-side records here):"];for(const i of n)t.push(`// ${i.subdomain}.${e} \u2192 deploy a Domain { registrar: "external-delegated",`,`// zoneName: ${JSON.stringify(e)}, delegatedSubdomain: ${JSON.stringify(i.subdomain)} }`,`// in account ${JSON.stringify(i.toAccount)}; the CLI injects parentDelegationRoleArn`,"// (ManagedDomainBinding.delegationRoleArn) and the child UPSERTs its NS into this zone.");return t.join(`
|
|
4
4
|
`)+`
|
|
5
5
|
`}o(B,"emitDelegationGuidance");function F(e){const n={fjallApp:!1,fjallCdn:!1,fjallBucket:!1,aliasTo:!1};for(const t of e)if(t.kind==="alias")switch(t.target.kind){case"ecs":n.fjallApp=!0;break;case"cdn":n.fjallCdn=!0;break;case"bucket":n.fjallBucket=!0;break;case"custom":n.aliasTo=!0;break}return n}o(F,"computeUsedHelpers");function L(e){const n=["App","Domain"];return e.aliasTo&&n.push("aliasTo"),e.fjallApp&&n.push("fjallApp"),e.fjallBucket&&n.push("fjallBucket"),e.fjallCdn&&n.push("fjallCdn"),`import {
|
|
6
|
-
${n.map(
|
|
6
|
+
${n.map(i=>` ${i},`).join(`
|
|
7
7
|
`)}
|
|
8
|
-
} from "@fjall/components-infrastructure";`}o(L,"emitImports");function E(e){return D(e.split(".").join(""))}o(E,"safeZoneName");function g(e,n){if(e==="@")return e;const t=e.endsWith(".")?e.slice(0,-1):e;return t===n?"@":t.endsWith(`.${n}`)?t.slice(0,-(n.length+1)):e}o(g,"toRelativeRecordName");function Z(e){return e.registrar==="external-delegated"&&e.delegatedSubdomain?`${e.delegatedSubdomain}.${e.zoneName}`:e.zoneName}o(Z,"effectiveZoneName");function y(e,n,t){if(n.length===0)return` ${e}: [],`;const
|
|
8
|
+
} from "@fjall/components-infrastructure";`}o(L,"emitImports");function E(e){return D(e.split(".").join(""))}o(E,"safeZoneName");function g(e,n){if(e==="@")return e;const t=e.endsWith(".")?e.slice(0,-1):e;return t===n?"@":t.endsWith(`.${n}`)?t.slice(0,-(n.length+1)):e}o(g,"toRelativeRecordName");function Z(e){return e.registrar==="external-delegated"&&e.delegatedSubdomain?`${e.delegatedSubdomain}.${e.zoneName}`:e.zoneName}o(Z,"effectiveZoneName");function y(e,n,t){if(n.length===0)return` ${e}: [],`;const i=n.map(t).join(`
|
|
9
9
|
`);return` ${e}: [
|
|
10
|
-
${
|
|
11
|
-
],`}o(y,"emitBlock");function K(e,n={}){const t=k(n.componentName??e.zoneName),
|
|
10
|
+
${i}
|
|
11
|
+
],`}o(y,"emitBlock");function K(e,n={}){const t=k(n.componentName??e.zoneName),i=E(n.componentName??e.zoneName),c=F(e.records),f=L(c),s=Z(e),d=e.records.map(a=>a.kind==="standard"?{...a,name:g(a.name,s)}:{...a,name:g(a.name,s)}),m=R(d),u=[...e.certificates].sort((a,l)=>a.domainName.localeCompare(l.domainName)),h=[...e.delegations].sort((a,l)=>a.subdomain.localeCompare(l.subdomain)),r=[];if(e.recordIds!==void 0&&r.push(` recordIds: ${JSON.stringify(e.recordIds)},`),e.hostedZoneId&&r.push(` hostedZoneId: ${JSON.stringify(e.hostedZoneId)},`),e.adoptedNameServers&&e.adoptedNameServers.length>0){const a=e.adoptedNameServers.map(l=>JSON.stringify(l)).join(", ");r.push(` adoptedNameServers: [${a}],`)}e.delegatedSubdomain&&r.push(` delegatedSubdomain: ${JSON.stringify(e.delegatedSubdomain)},`),e.registrar==="external-delegated"&&r.push(" // D8 child-writes delegation + two-phase deploy: both values arrive"," // via CDK context, injected by the Fjall CLI at deploy time (see the"," // reads above `new Domain`). Set a literal parentDelegationRoleArn"," // here only for out-of-band deploys.",' ...(domainDeployPhase === "zone" || domainDeployPhase === "full"'," ? { phase: domainDeployPhase }"," : {}),",' ...(typeof parentDelegationRoleArn === "string" &&',' parentDelegationRoleArn !== ""'," ? { parentDelegationRoleArn }"," : {}),");const N=y("certificates",u,z),S=y("records",m,w),$=e.registrar==="external-records"?"":B(e.zoneName,h),j=e.registrar==="external-delegated"?`
|
|
12
12
|
// Injected by the Fjall CLI at deploy time (D8) \u2014 do not set these by hand.
|
|
13
13
|
const domainDeployPhase: unknown = app.node.tryGetContext(
|
|
14
14
|
"fjall:domainDeployPhase"
|
|
@@ -25,7 +25,7 @@ if (
|
|
|
25
25
|
const parentDelegationRoleArn: unknown = app.node.tryGetContext(
|
|
26
26
|
"fjall:parentDelegationRoleArn"
|
|
27
27
|
);
|
|
28
|
-
`:"";return`${
|
|
28
|
+
`:"";return`${f}
|
|
29
29
|
|
|
30
30
|
// Fjall-managed domain \u2014 edit this file to add or change records. See https://docs.fjall.io/resources/networking/domain for the Domain construct API.
|
|
31
31
|
|
|
@@ -35,7 +35,7 @@ const app = App.getApp(${JSON.stringify(t)});
|
|
|
35
35
|
// CloudFormation stack name. Do not rename it.
|
|
36
36
|
const stack = app.getStack(${JSON.stringify(t)}).getStack();
|
|
37
37
|
${j}
|
|
38
|
-
new Domain(stack, ${JSON.stringify(
|
|
38
|
+
new Domain(stack, ${JSON.stringify(i)}, {
|
|
39
39
|
registrar: ${JSON.stringify(e.registrar)},
|
|
40
40
|
zoneName: ${JSON.stringify(e.zoneName)},
|
|
41
41
|
${r.length>0?r.join(`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(
|
|
3
|
-
`);return
|
|
4
|
-
${
|
|
5
|
-
${
|
|
6
|
-
${
|
|
7
|
-
${
|
|
8
|
-
${
|
|
1
|
+
var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,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 g(e){return e.map(c).join(", ")}n(g,"formatStringArray");const d="import:SharedAlarmTopicArn";function _(e=" "){return`
|
|
2
|
+
${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(d)} } : {}),`}n(_,"emitProductionAlertsTopicSpread");function $(e){return e===0?"":`_${String(e+1)}`}n($,"connectionEnvSuffix");function x(e,t){if(e===t)return 1;if(!e.startsWith(`${t}_`))return;const r=e.slice(t.length+1);return/^\d+$/.test(r)?parseInt(r,10):void 0}n(x,"connectionKeyOrdinal");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 u(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(u,"toVariableName");function j(e){return e.variableName??u(e.name)}n(j,"getVariableName");function S(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 u(t)}n(S,"resolveResourceVariable");function b(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(b,"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(b(e)){const a=r.map(([s,m])=>`${s}: ${f(m,t)}`).join(", ");return a?`{ ${a} }`:"{}"}const i=t+" ",o=r.map(([a,s])=>`${i}${a}: ${f(s,i)}`).join(`,
|
|
3
|
+
`);return o?`{
|
|
4
|
+
${o}
|
|
5
|
+
${t}}`:"{}"}return JSON.stringify(e)}n(f,"formatValue");function h(e,t=" "){return e.map(i=>{const o=r(i);return`
|
|
6
|
+
${t}${i.key}: ${o}`}).join(",");function r(i){switch(i.value.kind){case"expression":return i.value.source;case"structured":throw new Error(`emitProjectedProps cannot render the structured value for "${i.key}" \u2014 structured expressions are emitted by the codemod's AST serialiser only.`);case"literal":return f(i.value.value,t)}}}n(h,"emitProjectedProps");function N(e,t,r,i="raw"){if(!e)return"";let o;switch(i){case"string":o=c(String(r));break;case"object":o=f(r);break;case"boolean-or-object":o=r===!1?"false":f(r);break;default:o=String(r)}return`
|
|
7
|
+
${t}: ${o},`}n(N,"buildProperty");function A(e,t=" "){return e?.length?e.map(r=>`
|
|
8
|
+
${t}${r.key}: ${r.sourceText},`).join(""):""}n(A,"emitExtraProperties");export{d as PRODUCTION_ALERTS_TOPIC_IMPORT,N as buildProperty,$ as connectionEnvSuffix,x as connectionKeyOrdinal,A as emitExtraProperties,_ as emitProductionAlertsTopicSpread,h as emitProjectedProps,c as escapeStringLiteral,g as formatStringArray,f as formatValue,j as getVariableName,l as isSpecialValue,S as resolveResourceVariable,V as toKebab,T as toPascalCase,C as toValidDatabaseName,u as toVariableName};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export declare const DATABASE_ENV_VARS: Readonly<{
|
|
2
|
+
readonly HOST: "DATABASE_HOST";
|
|
3
|
+
readonly PORT: "DATABASE_PORT";
|
|
4
|
+
readonly NAME: "DATABASE_NAME";
|
|
5
|
+
readonly SSL: "DATABASE_SSL";
|
|
6
|
+
readonly USERNAME: "DATABASE_USERNAME";
|
|
7
|
+
readonly PASSWORD: "DATABASE_PASSWORD";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const CREDENTIAL_KEYS: Readonly<{
|
|
10
|
+
readonly USERNAME: "username";
|
|
11
|
+
readonly PASSWORD: "password";
|
|
12
|
+
}>;
|
|
13
|
+
/** The literal value emitted for `DATABASE_SSL`. */
|
|
14
|
+
export declare const DATABASE_SSL_VALUE = "true";
|
|
15
|
+
/**
|
|
16
|
+
* Construct accessor methods the emitted connection wiring calls on a bound
|
|
17
|
+
* database variable.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DATABASE_ACCESSORS: Readonly<{
|
|
20
|
+
readonly HOST: "getHostEndpoint";
|
|
21
|
+
readonly PORT: "getHostPort";
|
|
22
|
+
readonly NAME: "getDatabaseName";
|
|
23
|
+
readonly CREDENTIALS: "getCredentials";
|
|
24
|
+
readonly IMPORT: "getImport";
|
|
25
|
+
}>;
|
|
26
|
+
export declare const STORAGE_ENV_VARS: Readonly<{
|
|
27
|
+
readonly NAME: "BUCKET_NAME";
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Construct accessor methods the emitted connection wiring calls on a bound
|
|
31
|
+
* bucket variable.
|
|
32
|
+
*/
|
|
33
|
+
export declare const STORAGE_ACCESSORS: Readonly<{
|
|
34
|
+
readonly BUCKET_NAME: "getBucketName";
|
|
35
|
+
}>;
|
|
36
|
+
export declare const MESSAGING_ENV_VARS: Readonly<{
|
|
37
|
+
readonly URL: "QUEUE_URL";
|
|
38
|
+
readonly ARN: "QUEUE_ARN";
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Construct accessor methods the emitted connection wiring calls on a bound
|
|
42
|
+
* queue variable.
|
|
43
|
+
*/
|
|
44
|
+
export declare const MESSAGING_ACCESSORS: Readonly<{
|
|
45
|
+
readonly URL: "getQueueUrl";
|
|
46
|
+
readonly ARN: "getQueueArn";
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Emission order for `connections: [...]` — databases, then storage, then
|
|
50
|
+
* messaging. `formatAllConnectionsCode` and the connect edit's insertion
|
|
51
|
+
* ranks both derive from this tuple so a surgical insert never reorders what
|
|
52
|
+
* a later full regeneration would emit.
|
|
53
|
+
*/
|
|
54
|
+
export declare const CONNECTION_TYPE_ORDER: readonly ["database", "storage", "messaging"];
|
|
55
|
+
export type ConnectionResourceType = (typeof CONNECTION_TYPE_ORDER)[number];
|
|
56
|
+
/** How a wiring entry's value is produced from the bound resource variable. */
|
|
57
|
+
export type ConnectionWiringValue = {
|
|
58
|
+
kind: "accessor";
|
|
59
|
+
method: string;
|
|
60
|
+
} | {
|
|
61
|
+
kind: "credential";
|
|
62
|
+
credentialKey: string;
|
|
63
|
+
} | {
|
|
64
|
+
kind: "literal";
|
|
65
|
+
value: string;
|
|
66
|
+
};
|
|
67
|
+
export interface ConnectionWiringEntry {
|
|
68
|
+
key: string;
|
|
69
|
+
target: "environment" | "secretsImport";
|
|
70
|
+
value: ConnectionWiringValue;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The wiring entries a single connection of `resourceType` contributes, in
|
|
74
|
+
* canonical emission order. `suffix` is the `_N` scheme value for this
|
|
75
|
+
* connection's ordinal (`connectionEnvSuffix`).
|
|
76
|
+
*/
|
|
77
|
+
export declare function buildConnectionWiringEntries(resourceType: ConnectionResourceType, suffix: string): ConnectionWiringEntry[];
|
|
78
|
+
/**
|
|
79
|
+
* Render a wiring value as generated source for the scaffold lane. The
|
|
80
|
+
* connect edit builds the equivalent AST nodes from the same
|
|
81
|
+
* {@link ConnectionWiringValue} shapes.
|
|
82
|
+
*/
|
|
83
|
+
export declare function renderWiringValueSource(value: ConnectionWiringValue, variableName: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var N=Object.defineProperty;var r=(t,e)=>N(t,"name",{value:e,configurable:!0});import{escapeStringLiteral as o}from"./common.js";const E=Object.freeze({HOST:"DATABASE_HOST",PORT:"DATABASE_PORT",NAME:"DATABASE_NAME",SSL:"DATABASE_SSL",USERNAME:"DATABASE_USERNAME",PASSWORD:"DATABASE_PASSWORD"}),c=Object.freeze({USERNAME:"username",PASSWORD:"password"}),O="true",n=Object.freeze({HOST:"getHostEndpoint",PORT:"getHostPort",NAME:"getDatabaseName",CREDENTIALS:"getCredentials",IMPORT:"getImport"}),T=Object.freeze({NAME:"BUCKET_NAME"}),_=Object.freeze({BUCKET_NAME:"getBucketName"}),R=Object.freeze({URL:"QUEUE_URL",ARN:"QUEUE_ARN"}),s=Object.freeze({URL:"getQueueUrl",ARN:"getQueueArn"}),g=["database","storage","messaging"],A=r((t,e)=>({key:t,target:"environment",value:e}),"environmentEntry"),a=r((t,e)=>({key:t,target:"secretsImport",value:{kind:"credential",credentialKey:e}}),"secretEntry"),S=r(t=>({kind:"accessor",method:t}),"accessor");function D(t,e){switch(t){case"database":return[A(`${E.HOST}${e}`,S(n.HOST)),A(`${E.PORT}${e}`,S(n.PORT)),A(`${E.NAME}${e}`,S(n.NAME)),A(`${E.SSL}${e}`,{kind:"literal",value:O}),a(`${E.USERNAME}${e}`,c.USERNAME),a(`${E.PASSWORD}${e}`,c.PASSWORD)];case"storage":return[A(`${T.NAME}${e}`,S(_.BUCKET_NAME))];case"messaging":return[A(`${R.URL}${e}`,S(s.URL)),A(`${R.ARN}${e}`,S(s.ARN))]}}r(D,"buildConnectionWiringEntries");function M(t,e){switch(t.kind){case"accessor":return`${e}.${t.method}()`;case"credential":return`${e}.${n.CREDENTIALS}().${n.IMPORT}(${o(t.credentialKey)})`;case"literal":return o(t.value)}}r(M,"renderWiringValueSource");export{g as CONNECTION_TYPE_ORDER,c as CREDENTIAL_KEYS,n as DATABASE_ACCESSORS,E as DATABASE_ENV_VARS,O as DATABASE_SSL_VALUE,s as MESSAGING_ACCESSORS,R as MESSAGING_ENV_VARS,_ as STORAGE_ACCESSORS,T as STORAGE_ENV_VARS,D as buildConnectionWiringEntries,M as renderWiringValueSource};
|
|
@@ -5,38 +5,7 @@
|
|
|
5
5
|
* RDS Instance, Aurora, and GlobalAurora configurations.
|
|
6
6
|
*/
|
|
7
7
|
import type { DatabaseResourcePlan, ApplicationResourcePlan, ComputeResourcePlan } from "../schemas/resourceSchemas.js";
|
|
8
|
-
export
|
|
9
|
-
readonly HOST: "DATABASE_HOST";
|
|
10
|
-
readonly PORT: "DATABASE_PORT";
|
|
11
|
-
readonly NAME: "DATABASE_NAME";
|
|
12
|
-
readonly SSL: "DATABASE_SSL";
|
|
13
|
-
readonly USERNAME: "DATABASE_USERNAME";
|
|
14
|
-
readonly PASSWORD: "DATABASE_PASSWORD";
|
|
15
|
-
}>;
|
|
16
|
-
export declare const CREDENTIAL_KEYS: Readonly<{
|
|
17
|
-
readonly USERNAME: "username";
|
|
18
|
-
readonly PASSWORD: "password";
|
|
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
|
-
}>;
|
|
8
|
+
export { CREDENTIAL_KEYS, DATABASE_ACCESSORS, DATABASE_ENV_VARS, DATABASE_SSL_VALUE, } from "./connectionWiring.js";
|
|
40
9
|
export type DatabaseEnvVarEntry = {
|
|
41
10
|
key: string;
|
|
42
11
|
expression: string;
|
|
@@ -51,8 +20,8 @@ export interface DatabaseEnvVars {
|
|
|
51
20
|
*/
|
|
52
21
|
export declare function getConnectedDatabases(plan: ApplicationResourcePlan, compute: ComputeResourcePlan): DatabaseResourcePlan[];
|
|
53
22
|
/**
|
|
54
|
-
* Generate database environment variable entries for a list of connected
|
|
55
|
-
*
|
|
23
|
+
* Generate database environment variable entries for a list of connected
|
|
24
|
+
* databases from the shared wiring vocabulary (`connectionWiring.ts`).
|
|
56
25
|
* Credential entries are always marked as secrets (isSecret: true).
|
|
57
26
|
*/
|
|
58
27
|
export declare function generateDatabaseEnvVarEntries(connectedDatabases: DatabaseResourcePlan[]): DatabaseEnvVarEntry[];
|