@fjall/generator 25.0.0 → 27.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.
@@ -9,15 +9,15 @@
9
9
  "package.json",
10
10
  "tsconfig.json"
11
11
  ],
12
- "hash": "6d81781923e177038bb9a5337333169cbfefbf92333371e66e09ee752fb67d19",
12
+ "hash": "fc678406c28d0397211136dd597378188eb14a8e783e02d3ec2710d26e2a94a2",
13
13
  "files": {
14
14
  "src/ast/astTestHelpers.ts": "026cac849eb88bdb",
15
- "src/ast/domain/astDomainParser.ts": "a88b990396db0a46",
15
+ "src/ast/domain/astDomainParser.ts": "12107a9864c6670c",
16
16
  "src/ast/index.ts": "48c73220502e5201",
17
17
  "src/ast/mutation/astCodeInjection.ts": "c1ebf483fb1e2332",
18
18
  "src/ast/mutation/astExpressionEvaluator.ts": "6082789268b91212",
19
19
  "src/ast/mutation/astSurgicalModification.ts": "9c512e11e8239c4d",
20
- "src/ast/parsers/common/astCommonParser.ts": "d4c19453e9a75cac",
20
+ "src/ast/parsers/common/astCommonParser.ts": "9f0f4c1a061aa8bd",
21
21
  "src/ast/parsers/common/astStatementClassifier.ts": "d5cfd1f8d5e35132",
22
22
  "src/ast/parsers/common/astStatementQueries.ts": "e40e31e0fcdc15e3",
23
23
  "src/ast/parsers/orchestrator/astInfrastructureParser.ts": "07fd7a94796ebf5f",
@@ -31,7 +31,7 @@
31
31
  "src/ast/parsers/resources/astDynamoDBParser.ts": "809c2c633447b388",
32
32
  "src/ast/parsers/resources/astMessagingParser.ts": "b185ec22e6b96943",
33
33
  "src/ast/parsers/resources/astNetworkParser.ts": "8697dccb454eac7d",
34
- "src/ast/parsers/resources/astPatternParser.ts": "b9c8cbfd593d8fa6",
34
+ "src/ast/parsers/resources/astPatternParser.ts": "490afd32a307eeb8",
35
35
  "src/ast/parsers/resources/astScheduleParser.ts": "dbdac640c75b8bd3",
36
36
  "src/ast/parsers/resources/astStorageParser.ts": "309bc3257f46cfdf",
37
37
  "src/aws/regions.ts": "a028bcb92b0e41d9",
@@ -115,9 +115,9 @@
115
115
  "src/dns/bindParser.ts": "2b463c4dd1395ae5",
116
116
  "src/dns/bindWriter.ts": "c296911ce5aef77c",
117
117
  "src/dns/domainFileGenerator.ts": "f2d0ba8cca5ab1c9",
118
- "src/dns/domainRecords.ts": "8bdfcb0b3b32a000",
118
+ "src/dns/domainRecords.ts": "27b4cbabbf600d4f",
119
119
  "src/dns/index.ts": "5a0173ea07707af3",
120
- "src/dns/tsEmitter.ts": "8e56a893773c1c07",
120
+ "src/dns/tsEmitter.ts": "381ef9f38758c025",
121
121
  "src/dns/types.ts": "82d6db9d7d26dbc2",
122
122
  "src/generation/common.ts": "50bbd875b9dd737e",
123
123
  "src/generation/compute.ts": "068f6fa241838b25",
@@ -171,7 +171,7 @@
171
171
  "src/schemas/messagingSchemas.ts": "2c1975fac903fd1b",
172
172
  "src/schemas/networkSchemas.ts": "c3a5f30e440dd2f8",
173
173
  "src/schemas/organisationSchemas.ts": "50d793aa7ff7f749",
174
- "src/schemas/patternSchemas.ts": "8f9de91fca0571d3",
174
+ "src/schemas/patternSchemas.ts": "72059b2d20a34a87",
175
175
  "src/schemas/resourceSchemas.ts": "cd050813242ea213",
176
176
  "src/schemas/securityBoundary.ts": "54d216807103bab8",
177
177
  "src/schemas/sharedTypes.ts": "45210e600bea393e",
@@ -181,11 +181,11 @@
181
181
  "src/validation/patterns.ts": "f9629eafdad7ac3e",
182
182
  "src/validation/validationMessages.ts": "b03413b3953c3e79",
183
183
  "src/validation/validationPatterns.ts": "865f3d688975b7c8",
184
- "src/version.ts": "02f8fccc72ba033d",
184
+ "src/version.ts": "27d20fa96e33a5e1",
185
185
  "../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
186
- "package.json": "9de423232f97e01c",
186
+ "package.json": "a1a453165ab6dbe2",
187
187
  "tsconfig.json": "1929cf3f99fe9b1e"
188
188
  },
189
- "outputHash": "369bcc2b8a51df82c5d654f8a08c0510549639868f801918f269d7995b72c54a",
189
+ "outputHash": "9704dc856ba29ba486e23d1bdc49d7d2c0180dcc5a1b17e0dae7ca79f56d6692",
190
190
  "outputFileCount": 343
191
191
  }
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 171 files minified at 2026-08-31T01:55:55.929Z
1
+ 171 files minified at 2026-08-31T09:47:18.065Z
@@ -346,6 +346,11 @@ export declare function parseAndConvert(code: string): {
346
346
  security?: {
347
347
  headers?: boolean | undefined;
348
348
  contentSecurityPolicy?: string | undefined;
349
+ hsts?: false | {
350
+ maxAgeDays?: number | undefined;
351
+ includeSubdomains?: boolean | undefined;
352
+ preload?: boolean | undefined;
353
+ } | undefined;
349
354
  } | undefined;
350
355
  domain?: string | undefined;
351
356
  zoneName?: string | undefined;
@@ -1,6 +1,7 @@
1
1
  import * as ts from "typescript";
2
2
  import { type Result } from "../../types/Result.js";
3
3
  import { type DnsRecordType } from "../../dns/types.js";
4
+ import { type TypedFjallTarget } from "../../dns/domainRecords.js";
4
5
  /** One-of match for a single `new Domain(...)` call in an infrastructure file. */
5
6
  export interface DomainCallMatch {
6
7
  readonly callExpression: ts.NewExpression;
@@ -23,24 +24,18 @@ export interface DomainCallMatch {
23
24
  /** The `id` argument — second arg — as a string literal if resolvable. */
24
25
  readonly constructIdLiteral: string | undefined;
25
26
  }
26
- /** Parsed target expression for a single `AliasRecord.target`. */
27
- export type ParsedFjallTarget = {
28
- readonly kind: "ecs";
29
- readonly appName: string;
30
- /** Second `fjallApp` argument — present only for a multi-ALB app. */
31
- readonly computeName?: string;
32
- } | {
33
- readonly kind: "cdn";
34
- readonly appName: string;
35
- } | {
36
- readonly kind: "bucket";
37
- readonly appName: string;
38
- readonly bucketName: string;
39
- } | {
40
- readonly kind: "custom";
41
- readonly dnsName: string;
42
- readonly hostedZoneId: string;
43
- } | {
27
+ /**
28
+ * Parsed target expression for a single `AliasRecord.target`: every variant
29
+ * the eject schema accepts, plus the two the parser alone can produce for a
30
+ * call it cannot turn into one.
31
+ *
32
+ * The resolvable half is DERIVED from `TypedFjallTargetSchema`, not
33
+ * redeclared. Both sites describe the same domain concept and must move
34
+ * together — a variant or qualifier added to the schema and not here would
35
+ * compile cleanly on both sides while `parseTarget` silently stopped being
36
+ * able to produce it, and nothing in the round trip would fail.
37
+ */
38
+ export type ParsedFjallTarget = TypedFjallTarget | {
44
39
  readonly kind: "unresolved";
45
40
  readonly sourceText: string;
46
41
  } | {
@@ -1 +1 @@
1
- var T=Object.defineProperty;var u=(n,e)=>T(n,"name",{value:e,configurable:!0});import*as m from"typescript";import{parseObjectLiteral as E,asString as f,asStringUnion as h,asStringArray as k,asBoolean as N,asNumber as L,isCallRef as j,isParsedObject as S}from"../parsers/common/astCommonParser.js";import{success as l,failure as a}from"../../types/Result.js";import{DnsRecordTypeSchema as O}from"../../dns/types.js";import{DomainRegistrarSchema as C,DomainDeployPhaseSchema as Z,AliasRecordTypeSchema as F,RecordConstructIdSchema as V,RecordIdsModeSchema as P,TYPED_FJALL_TARGET_KINDS as z}from"../../dns/domainRecords.js";const x=C.options,D=Z.options,I=P.options,M=O.options,q=F.options;function B(n){const e=[],t=u(r=>{if(m.isNewExpression(r)&&J(r.expression)){const d=U(r);d!==void 0&&e.push(d)}m.forEachChild(r,t)},"visit");if(t(n),e.length===0)return l(void 0);if(e.length>1)return a(new Error(`Expected exactly one 'new Domain(...)' call per infrastructure file, found ${e.length}`));const i=e[0];return i?l(i):l(void 0)}u(B,"findDomainConstructCall");function J(n){return m.isIdentifier(n)&&n.text==="Domain"}u(J,"isDomainIdentifier");function U(n){const e=n.arguments;if(!e||e.length<3)return;const t=e[0],i=e[1],r=e[2];if(!t||!i||!r||!m.isObjectLiteralExpression(r))return;const d=G(n);if(d===void 0)return;const o=Y(n),s=m.isStringLiteral(i)?i.text:void 0;return{callExpression:n,containingStatement:d,propsObjectLiteral:r,domainVarId:o,scopeArgumentText:t.getText(),constructIdLiteral:s}}u(U,"buildMatch");function G(n){let e=n;for(;e!==void 0;){if(m.isExpressionStatement(e)||m.isVariableStatement(e))return e;e=e.parent}}u(G,"findContainingTopLevelStatement");function Y(n){let e=n.parent;for(;e!==void 0;){if(m.isVariableDeclaration(e)&&m.isIdentifier(e.name)&&e.initializer===n)return e.name.text;e=e.parent}}u(Y,"extractDomainVarId");function w(n){switch(n.kind){case"registrar_required":return"'registrar' property is required";case"registrar_unsupported":return`'registrar' must be one of ${x.join(", ")}, got ${JSON.stringify(n.value)}`;case"missing_field":return`'${n.field}' property is required`;case"invalid_literal":return`'${n.field}' ${n.reason}`;case"removed_field":return`'${n.field}' was removed from the Domain API \u2014 ${n.cure}`}}u(w,"errorMessage");const K="declare the delegated child as its own Domain with registrar: 'external-delegated' and set 'parentDelegationRoleArn' (the CLI injects it via ManagedDomainBinding.delegationRoleArn); the child UPSERTs its NS records into the parent zone";function H(n){const e=E(n),t=h(e.registrar,x);if(t===void 0){const c=e.registrar;if(c===void 0)return a({kind:"registrar_required"});const p=typeof c=="string"?c:y(c);return a({kind:"registrar_unsupported",value:p})}const i=f(e.zoneName);if(i===void 0)return a({kind:"missing_field",field:"zoneName"});const r=h(e.recordIds,I);if(e.recordIds!==void 0&&r===void 0)return a({kind:"invalid_literal",field:"recordIds",reason:`must be one of ${I.map(c=>`'${c}'`).join(", ")}`});const d=Q(e.records);if(!d.success)return d;const o=te(e.certificates);if(!o.success)return o;if(e.delegations!==void 0)return a({kind:"removed_field",field:"delegations",cure:K});const s={zoneName:i,recordIds:r,description:f(e.description),costAllocationEnvironment:f(e.costAllocationEnvironment),tags:re(e.tags),records:d.data,certificates:o.data};switch(t){case"route53":return l({...s,registrar:t,hostedZoneId:f(e.hostedZoneId)});case"external-delegated":{const c=f(e.delegatedSubdomain);if(c===void 0)return a({kind:"missing_field",field:"delegatedSubdomain"});const p=f(e.hostedZoneId);if(e.hostedZoneId!==void 0&&p===void 0)return a({kind:"invalid_literal",field:"hostedZoneId",reason:"must be a literal string zone id on external-delegated \u2014 dynamic expressions cannot be round-tripped"});const _=k(e.adoptedNameServers);if(e.adoptedNameServers!==void 0&&_===void 0)return a({kind:"invalid_literal",field:"adoptedNameServers",reason:"must be an array of literal NS hostname strings \u2014 the parent NS UPSERT writes them verbatim"});if(p===void 0!=(_===void 0))return a({kind:"invalid_literal",field:p===void 0?"hostedZoneId":"adoptedNameServers",reason:"adopting an existing child zone requires hostedZoneId and adoptedNameServers together (both-or-neither) \u2014 an imported zone exposes no name-server attribute at synth"});const A=f(e.parentDelegationRoleArn);if(e.parentDelegationRoleArn!==void 0&&A===void 0)return a({kind:"invalid_literal",field:"parentDelegationRoleArn",reason:"must be a literal string ARN (VD2-a) \u2014 the CLI injects it via ManagedDomainBinding.delegationRoleArn; dynamic expressions such as Fn.importValue are not supported"});const b=h(e.phase,D);return e.phase!==void 0&&b===void 0?a({kind:"invalid_literal",field:"phase",reason:`must be one of ${D.map($=>`'${$}'`).join(", ")}`}):l({...s,registrar:t,delegatedSubdomain:c,hostedZoneId:p,adoptedNameServers:_,parentDelegationRoleArn:A,phase:b})}case"external-records":return l({...s,registrar:t})}}u(H,"parseDomainProps");function ue(n){return w(n)}u(ue,"parseDomainErrorMessage");function ce(n,e,t){const i=m.createSourceFile(e,n,m.ScriptTarget.Latest,!0,m.ScriptKind.TS),r=B(i);if(!r.success)return a(new Error(r.error.message));if(r.data===void 0)return a(new Error(`Domain '${t}': no 'new Domain(...)' call found in ${e} \u2014 the file is not a Fjall domain component.`));const d=H(r.data.propsObjectLiteral);return d.success?l(d.data):a(new Error(`Domain '${t}': infrastructure.ts could not be parsed (${d.error.kind}).`))}u(ce,"parseDomainInfrastructureSource");function Q(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"records",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const i=n[t];if(!S(i))return a({kind:"invalid_literal",field:`records[${t}]`,reason:"must be an object literal"});const r=W(i,t);if(!r.success)return r;e.push(r.data)}return l(e)}u(Q,"parseRecordsArray");function W(n,e){const t=f(n.type),i=f(n.name);if(t===void 0)return a({kind:"missing_field",field:`records[${e}].type`});if(i===void 0)return a({kind:"missing_field",field:`records[${e}].name`});const r=f(n.id);if(n.id!==void 0&&(r===void 0||!V.safeParse(r).success))return a({kind:"invalid_literal",field:`records[${e}].id`,reason:"must be a literal alphanumeric string starting with a letter \u2014 it becomes a CloudFormation logical-ID segment"});if(n.target!==void 0){if(!q.some(p=>p===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`alias records must have type 'A' or 'AAAA', got '${t}'`});const c=ee(n.target);return l({kind:"alias",type:t,name:i,target:c,...r!==void 0?{id:r}:{}})}if(!M.some(c=>c===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`unsupported record type '${t}'`});const d=X(n.value);if(d===void 0)return a({kind:"invalid_literal",field:`records[${e}].value`,reason:`must be a string or array of strings (got ${JSON.stringify(n.value)})`});const o=L(n.ttl),s={kind:"standard",type:t,name:i,value:d,...o!==void 0?{ttl:o}:{},...r!==void 0?{id:r}:{}};return l(s)}u(W,"parseRecord");function X(n){if(n===void 0)return;if(typeof n=="string")return n;const e=k(n);if(e!==void 0)return e}u(X,"parseRecordValue");function ee(n){if(j(n))return ne(n);if(S(n)){const e=h(n.kind,z);if(e==="ecs"||e==="cdn"){const t=f(n.appName);if(t!==void 0)return{kind:e,appName:t}}if(e==="bucket"){const t=f(n.appName),i=f(n.bucketName);if(t!==void 0&&i!==void 0)return{kind:e,appName:t,bucketName:i}}if(e==="custom"){const t=f(n.dnsName),i=f(n.hostedZoneId);if(t!==void 0&&i!==void 0)return{kind:e,dnsName:t,hostedZoneId:i}}}return{kind:"unresolved",sourceText:y(n)}}u(ee,"parseTarget");function ne(n){const e=n.__call.trim(),t=e.match(/^([A-Za-z_][\w$]*)\s*\(([\s\S]*)\)\s*$/);if(!t)return{kind:"unresolved",sourceText:e};const i=t[1],r=t[2]??"",d=v(r);switch(i){case"fjallApp":{const o=g(d,0);if(o===void 0)return{kind:"dynamic",sourceText:e};if(d.length<2)return{kind:"ecs",appName:o};const s=g(d,1);return s===void 0?{kind:"dynamic",sourceText:e}:{kind:"ecs",appName:o,computeName:s}}case"fjallCdn":{const o=g(d,0);return o===void 0?{kind:"dynamic",sourceText:e}:{kind:"cdn",appName:o}}case"fjallBucket":{if(d.length<2)return{kind:"unresolved",sourceText:e};const o=g(d,0),s=g(d,1);return o===void 0||s===void 0?{kind:"dynamic",sourceText:e}:{kind:"bucket",appName:o,bucketName:s}}case"aliasTo":{if(d.length>=2){const o=g(d,0),s=g(d,1);return o!==void 0&&s!==void 0?{kind:"custom",dnsName:o,hostedZoneId:s}:{kind:"dynamic",sourceText:e}}if(d.length===1){const o=d[0]?.trim()??"",s=R(o,"dnsName"),c=R(o,"hostedZoneId");return s!==void 0&&c!==void 0?{kind:"custom",dnsName:s,hostedZoneId:c}:{kind:"dynamic",sourceText:e}}return{kind:"unresolved",sourceText:e}}default:return{kind:"unresolved",sourceText:e}}}u(ne,"resolveCallRefTarget");function v(n){const e=[];let t=0,i=null,r="";for(let o=0;o<n.length;o++){const s=n[o];if(i!==null){if(r+=s,s==="\\"&&o+1<n.length){const c=n[o+1];c!==void 0&&(r+=c,o+=1);continue}s===i&&(i=null);continue}if(s==='"'||s==="'"||s==="`"){i=s,r+=s;continue}if(s==="("||s==="{"||s==="["){t+=1,r+=s;continue}if(s===")"||s==="}"||s==="]"){t-=1,r+=s;continue}if(s===","&&t===0){e.push(r.trim()),r="";continue}r+=s}const d=r.trim();return d.length>0&&e.push(d),e}u(v,"splitTopLevelArgs");function g(n,e){const t=n[e];if(t===void 0)return;const i=t.trim();if(i.length<2)return;const r=i[0],d=i[i.length-1];if(r===d&&!(r!=='"'&&r!=="'"&&r!=="`"))return i.slice(1,-1)}u(g,"extractStringLiteralArg");function R(n,e){const t=n.trim().replace(/^\{|\}$/g,""),i=v(t);for(const r of i){const d=r.indexOf(":");if(d<0||r.slice(0,d).trim().replace(/["'`]/g,"")!==e)continue;const s=r.slice(d+1).trim();return g([s],0)}}u(R,"extractObjectFieldString");function te(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"certificates",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const i=n[t];if(typeof i=="string"){e.push({domainName:i});continue}if(!S(i))return a({kind:"invalid_literal",field:`certificates[${t}]`,reason:"must be a string or object literal"});const r=f(i.domainName);if(r===void 0)return a({kind:"missing_field",field:`certificates[${t}].domainName`});const d=k(i.subjectAlternativeNames),o=N(i.transparencyLogging),s=N(i.cloudFront);if(i.cloudFront!==void 0&&s===void 0)return a({kind:"invalid_literal",field:`certificates[${t}].cloudFront`,reason:"must be a boolean literal \u2014 the CloudFront designation drives the zone-level us-east-1 export contract and cannot be round-tripped from a dynamic expression"});e.push({domainName:r,...d!==void 0?{subjectAlternativeNames:d}:{},...o!==void 0?{transparencyLogging:o}:{},...s!==void 0?{cloudFront:s}:{}})}return l(e)}u(te,"parseCertificatesArray");function re(n){if(n===void 0||!S(n))return;const e={};for(const[t,i]of Object.entries(n)){const r=f(i);r!==void 0&&(e[t]=r)}return Object.keys(e).length===0?void 0:e}u(re,"parseStringRecord");function y(n){if(n===void 0)return"undefined";if(n===null)return"null";if(typeof n=="string")return JSON.stringify(n);if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return`[${n.map(e=>y(e)).join(", ")}]`;if(typeof n=="object"){if("__call"in n)return String(n.__call);if("__identifier"in n)return String(n.__identifier);if("__expression"in n)return String(n.__expression);if("__unknown"in n)return String(n.__unknown)}return String(n)}u(y,"stringifyParsedValue");export{B as findDomainConstructCall,ue as parseDomainErrorMessage,ce as parseDomainInfrastructureSource,H as parseDomainProps,v as splitTopLevelArgs};
1
+ var T=Object.defineProperty;var u=(n,e)=>T(n,"name",{value:e,configurable:!0});import*as m from"typescript";import{parseObjectLiteral as E,asString as f,asStringUnion as h,asStringArray as _,asBoolean as N,asNumber as L,isCallRef as j,isParsedObject as k}from"../parsers/common/astCommonParser.js";import{success as l,failure as a}from"../../types/Result.js";import{DnsRecordTypeSchema as O}from"../../dns/types.js";import{DomainRegistrarSchema as C,DomainDeployPhaseSchema as Z,AliasRecordTypeSchema as F,RecordConstructIdSchema as V,RecordIdsModeSchema as P,TYPED_FJALL_TARGET_KINDS as z}from"../../dns/domainRecords.js";const x=C.options,D=Z.options,I=P.options,M=O.options,q=F.options;function B(n){const e=[],t=u(r=>{if(m.isNewExpression(r)&&J(r.expression)){const d=U(r);d!==void 0&&e.push(d)}m.forEachChild(r,t)},"visit");if(t(n),e.length===0)return l(void 0);if(e.length>1)return a(new Error(`Expected exactly one 'new Domain(...)' call per infrastructure file, found ${e.length}`));const i=e[0];return i?l(i):l(void 0)}u(B,"findDomainConstructCall");function J(n){return m.isIdentifier(n)&&n.text==="Domain"}u(J,"isDomainIdentifier");function U(n){const e=n.arguments;if(!e||e.length<3)return;const t=e[0],i=e[1],r=e[2];if(!t||!i||!r||!m.isObjectLiteralExpression(r))return;const d=G(n);if(d===void 0)return;const o=Y(n),s=m.isStringLiteral(i)?i.text:void 0;return{callExpression:n,containingStatement:d,propsObjectLiteral:r,domainVarId:o,scopeArgumentText:t.getText(),constructIdLiteral:s}}u(U,"buildMatch");function G(n){let e=n;for(;e!==void 0;){if(m.isExpressionStatement(e)||m.isVariableStatement(e))return e;e=e.parent}}u(G,"findContainingTopLevelStatement");function Y(n){let e=n.parent;for(;e!==void 0;){if(m.isVariableDeclaration(e)&&m.isIdentifier(e.name)&&e.initializer===n)return e.name.text;e=e.parent}}u(Y,"extractDomainVarId");function w(n){switch(n.kind){case"registrar_required":return"'registrar' property is required";case"registrar_unsupported":return`'registrar' must be one of ${x.join(", ")}, got ${JSON.stringify(n.value)}`;case"missing_field":return`'${n.field}' property is required`;case"invalid_literal":return`'${n.field}' ${n.reason}`;case"removed_field":return`'${n.field}' was removed from the Domain API \u2014 ${n.cure}`}}u(w,"errorMessage");const K="declare the delegated child as its own Domain with registrar: 'external-delegated' and set 'parentDelegationRoleArn' (the CLI injects it via ManagedDomainBinding.delegationRoleArn); the child UPSERTs its NS records into the parent zone";function H(n){const e=E(n),t=h(e.registrar,x);if(t===void 0){const c=e.registrar;if(c===void 0)return a({kind:"registrar_required"});const g=typeof c=="string"?c:y(c);return a({kind:"registrar_unsupported",value:g})}const i=f(e.zoneName);if(i===void 0)return a({kind:"missing_field",field:"zoneName"});const r=h(e.recordIds,I);if(e.recordIds!==void 0&&r===void 0)return a({kind:"invalid_literal",field:"recordIds",reason:`must be one of ${I.map(c=>`'${c}'`).join(", ")}`});const d=Q(e.records);if(!d.success)return d;const o=te(e.certificates);if(!o.success)return o;if(e.delegations!==void 0)return a({kind:"removed_field",field:"delegations",cure:K});const s={zoneName:i,recordIds:r,description:f(e.description),costAllocationEnvironment:f(e.costAllocationEnvironment),tags:re(e.tags),records:d.data,certificates:o.data};switch(t){case"route53":return l({...s,registrar:t,hostedZoneId:f(e.hostedZoneId)});case"external-delegated":{const c=f(e.delegatedSubdomain);if(c===void 0)return a({kind:"missing_field",field:"delegatedSubdomain"});const g=f(e.hostedZoneId);if(e.hostedZoneId!==void 0&&g===void 0)return a({kind:"invalid_literal",field:"hostedZoneId",reason:"must be a literal string zone id on external-delegated \u2014 dynamic expressions cannot be round-tripped"});const S=_(e.adoptedNameServers);if(e.adoptedNameServers!==void 0&&S===void 0)return a({kind:"invalid_literal",field:"adoptedNameServers",reason:"must be an array of literal NS hostname strings \u2014 the parent NS UPSERT writes them verbatim"});if(g===void 0!=(S===void 0))return a({kind:"invalid_literal",field:g===void 0?"hostedZoneId":"adoptedNameServers",reason:"adopting an existing child zone requires hostedZoneId and adoptedNameServers together (both-or-neither) \u2014 an imported zone exposes no name-server attribute at synth"});const A=f(e.parentDelegationRoleArn);if(e.parentDelegationRoleArn!==void 0&&A===void 0)return a({kind:"invalid_literal",field:"parentDelegationRoleArn",reason:"must be a literal string ARN (VD2-a) \u2014 the CLI injects it via ManagedDomainBinding.delegationRoleArn; dynamic expressions such as Fn.importValue are not supported"});const b=h(e.phase,D);return e.phase!==void 0&&b===void 0?a({kind:"invalid_literal",field:"phase",reason:`must be one of ${D.map($=>`'${$}'`).join(", ")}`}):l({...s,registrar:t,delegatedSubdomain:c,hostedZoneId:g,adoptedNameServers:S,parentDelegationRoleArn:A,phase:b})}case"external-records":return l({...s,registrar:t})}}u(H,"parseDomainProps");function ue(n){return w(n)}u(ue,"parseDomainErrorMessage");function ce(n,e,t){const i=m.createSourceFile(e,n,m.ScriptTarget.Latest,!0,m.ScriptKind.TS),r=B(i);if(!r.success)return a(new Error(r.error.message));if(r.data===void 0)return a(new Error(`Domain '${t}': no 'new Domain(...)' call found in ${e} \u2014 the file is not a Fjall domain component.`));const d=H(r.data.propsObjectLiteral);return d.success?l(d.data):a(new Error(`Domain '${t}': infrastructure.ts could not be parsed (${d.error.kind}).`))}u(ce,"parseDomainInfrastructureSource");function Q(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"records",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const i=n[t];if(!k(i))return a({kind:"invalid_literal",field:`records[${t}]`,reason:"must be an object literal"});const r=W(i,t);if(!r.success)return r;e.push(r.data)}return l(e)}u(Q,"parseRecordsArray");function W(n,e){const t=f(n.type),i=f(n.name);if(t===void 0)return a({kind:"missing_field",field:`records[${e}].type`});if(i===void 0)return a({kind:"missing_field",field:`records[${e}].name`});const r=f(n.id);if(n.id!==void 0&&(r===void 0||!V.safeParse(r).success))return a({kind:"invalid_literal",field:`records[${e}].id`,reason:"must be a literal alphanumeric string starting with a letter \u2014 it becomes a CloudFormation logical-ID segment"});if(n.target!==void 0){if(!q.some(g=>g===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`alias records must have type 'A' or 'AAAA', got '${t}'`});const c=ee(n.target);return l({kind:"alias",type:t,name:i,target:c,...r!==void 0?{id:r}:{}})}if(!M.some(c=>c===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`unsupported record type '${t}'`});const d=X(n.value);if(d===void 0)return a({kind:"invalid_literal",field:`records[${e}].value`,reason:`must be a string or array of strings (got ${JSON.stringify(n.value)})`});const o=L(n.ttl),s={kind:"standard",type:t,name:i,value:d,...o!==void 0?{ttl:o}:{},...r!==void 0?{id:r}:{}};return l(s)}u(W,"parseRecord");function X(n){if(n===void 0)return;if(typeof n=="string")return n;const e=_(n);if(e!==void 0)return e}u(X,"parseRecordValue");function ee(n){if(j(n))return ne(n);if(k(n)){const e=h(n.kind,z);if(e==="ecs"||e==="cdn"){const t=f(n.appName);if(t!==void 0)return{kind:e,appName:t}}if(e==="bucket"){const t=f(n.appName),i=f(n.bucketName);if(t!==void 0&&i!==void 0)return{kind:e,appName:t,bucketName:i}}if(e==="custom"){const t=f(n.dnsName),i=f(n.hostedZoneId);if(t!==void 0&&i!==void 0)return{kind:e,dnsName:t,hostedZoneId:i}}}return{kind:"unresolved",sourceText:y(n)}}u(ee,"parseTarget");function ne(n){const e=n.__call.trim(),t=e.match(/^([A-Za-z_][\w$]*)\s*\(([\s\S]*)\)\s*$/);if(!t)return{kind:"unresolved",sourceText:e};const i=t[1],r=t[2]??"",d=v(r);switch(i){case"fjallApp":{const o=p(d,0);if(o===void 0)return{kind:"dynamic",sourceText:e};if(d.length<2)return{kind:"ecs",appName:o};const s=p(d,1);return s===void 0?{kind:"dynamic",sourceText:e}:{kind:"ecs",appName:o,computeName:s}}case"fjallCdn":{const o=p(d,0);if(o===void 0)return{kind:"dynamic",sourceText:e};if(d.length<2)return{kind:"cdn",appName:o};const s=p(d,1);return s===void 0?{kind:"dynamic",sourceText:e}:{kind:"cdn",appName:o,cdnName:s}}case"fjallBucket":{if(d.length<2)return{kind:"unresolved",sourceText:e};const o=p(d,0),s=p(d,1);return o===void 0||s===void 0?{kind:"dynamic",sourceText:e}:{kind:"bucket",appName:o,bucketName:s}}case"aliasTo":{if(d.length>=2){const o=p(d,0),s=p(d,1);return o!==void 0&&s!==void 0?{kind:"custom",dnsName:o,hostedZoneId:s}:{kind:"dynamic",sourceText:e}}if(d.length===1){const o=d[0]?.trim()??"",s=R(o,"dnsName"),c=R(o,"hostedZoneId");return s!==void 0&&c!==void 0?{kind:"custom",dnsName:s,hostedZoneId:c}:{kind:"dynamic",sourceText:e}}return{kind:"unresolved",sourceText:e}}default:return{kind:"unresolved",sourceText:e}}}u(ne,"resolveCallRefTarget");function v(n){const e=[];let t=0,i=null,r="";for(let o=0;o<n.length;o++){const s=n[o];if(i!==null){if(r+=s,s==="\\"&&o+1<n.length){const c=n[o+1];c!==void 0&&(r+=c,o+=1);continue}s===i&&(i=null);continue}if(s==='"'||s==="'"||s==="`"){i=s,r+=s;continue}if(s==="("||s==="{"||s==="["){t+=1,r+=s;continue}if(s===")"||s==="}"||s==="]"){t-=1,r+=s;continue}if(s===","&&t===0){e.push(r.trim()),r="";continue}r+=s}const d=r.trim();return d.length>0&&e.push(d),e}u(v,"splitTopLevelArgs");function p(n,e){const t=n[e];if(t===void 0)return;const i=t.trim();if(i.length<2)return;const r=i[0],d=i[i.length-1];if(r===d&&!(r!=='"'&&r!=="'"&&r!=="`"))return i.slice(1,-1)}u(p,"extractStringLiteralArg");function R(n,e){const t=n.trim().replace(/^\{|\}$/g,""),i=v(t);for(const r of i){const d=r.indexOf(":");if(d<0||r.slice(0,d).trim().replace(/["'`]/g,"")!==e)continue;const s=r.slice(d+1).trim();return p([s],0)}}u(R,"extractObjectFieldString");function te(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"certificates",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const i=n[t];if(typeof i=="string"){e.push({domainName:i});continue}if(!k(i))return a({kind:"invalid_literal",field:`certificates[${t}]`,reason:"must be a string or object literal"});const r=f(i.domainName);if(r===void 0)return a({kind:"missing_field",field:`certificates[${t}].domainName`});const d=_(i.subjectAlternativeNames),o=N(i.transparencyLogging),s=N(i.cloudFront);if(i.cloudFront!==void 0&&s===void 0)return a({kind:"invalid_literal",field:`certificates[${t}].cloudFront`,reason:"must be a boolean literal \u2014 the CloudFront designation drives the zone-level us-east-1 export contract and cannot be round-tripped from a dynamic expression"});e.push({domainName:r,...d!==void 0?{subjectAlternativeNames:d}:{},...o!==void 0?{transparencyLogging:o}:{},...s!==void 0?{cloudFront:s}:{}})}return l(e)}u(te,"parseCertificatesArray");function re(n){if(n===void 0||!k(n))return;const e={};for(const[t,i]of Object.entries(n)){const r=f(i);r!==void 0&&(e[t]=r)}return Object.keys(e).length===0?void 0:e}u(re,"parseStringRecord");function y(n){if(n===void 0)return"undefined";if(n===null)return"null";if(typeof n=="string")return JSON.stringify(n);if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return`[${n.map(e=>y(e)).join(", ")}]`;if(typeof n=="object"){if("__call"in n)return String(n.__call);if("__identifier"in n)return String(n.__identifier);if("__expression"in n)return String(n.__expression);if("__unknown"in n)return String(n.__unknown)}return String(n)}u(y,"stringifyParsedValue");export{B as findDomainConstructCall,ue as parseDomainErrorMessage,ce as parseDomainInfrastructureSource,H as parseDomainProps,v as splitTopLevelArgs};
@@ -1 +1 @@
1
- var x=Object.defineProperty;var r=(n,e)=>x(n,"name",{value:e,configurable:!0});import*as s from"typescript";import{constIncludes as d}from"../../../schemas/constants.js";function f(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}r(f,"isPlainObject");function a(n){return f(n)&&"__identifier"in n}r(a,"isIdentifierRef");function y(n){return f(n)&&"__expression"in n}r(y,"isExpressionRef");function l(n){return f(n)&&"__call"in n}r(l,"isCallRef");function p(n){return f(n)&&!("__identifier"in n)&&!("__expression"in n)&&!("__call"in n)&&!("__unknown"in n)}r(p,"isParsedObject");function m(n){return typeof n=="string"?n:void 0}r(m,"asString");function A(n){return typeof n=="number"?n:void 0}r(A,"asNumber");function g(n){return typeof n=="boolean"?n:void 0}r(g,"asBoolean");function h(n){if(!Array.isArray(n))return;const e=[];for(const t of n)typeof t=="string"&&e.push(t);return e.length>0?e:void 0}r(h,"asStringArray");function j(n,e){const t=m(n);if(t!==void 0)return d(e,t)?t:void 0}r(j,"asStringUnion");function O(n){const e={};for(const[t,i]of Object.entries(n))i!==void 0&&(e[t]=i);return e}r(O,"omitUndefined");function u(n){if(n===null)return"null";if(n===void 0)return"undefined";if(typeof n=="string")return JSON.stringify(n);if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return`[${n.map(u).join(", ")}]`;if(!f(n))return String(n);if(a(n))return n.__identifier;if(y(n))return n.__expression;if(l(n))return n.__call;if("__unknown"in n&&typeof n.__unknown=="string")return n.__unknown;const e=Object.entries(n);return e.length===0?"{}":`{ ${e.map(([i,o])=>`${i}: ${u(o)}`).join(", ")} }`}r(u,"parsedValueToSourceText");function C(n,e){const t=[];for(const[i,o]of Object.entries(n))e.has(i)||o===void 0||t.push({key:i,sourceText:u(o)});return t}r(C,"captureExtraProperties");function E(n,e){return s.isPropertyAssignment(n)&&s.isIdentifier(n.name)&&n.name.text===e}r(E,"isNamedProperty");function P(n){return s.isCallExpression(n)&&s.isPropertyAccessExpression(n.expression)&&n.expression.name.text==="getApp"&&s.isIdentifier(n.expression.expression)&&n.expression.expression.text==="App"}r(P,"isAppGetAppCall");function S(n,e){const{expression:t}=n;return s.isPropertyAccessExpression(t)&&t.name.text===e&&n.arguments.length>0}r(S,"isFactoryMethodCall");function I(n,e){let t;const i=r(o=>{t===void 0&&(t=e(o),t===void 0&&s.forEachChild(o,i))},"visit");return i(n),t}r(I,"findFirstInAst");function k(n,e){const t=[],i=r(o=>{const c=e(o);c!==null&&t.push(c),s.forEachChild(o,i)},"visit");return i(n),t}r(k,"collectFromAst");function F(n,e){return s.isCallExpression(n)&&s.isPropertyAccessExpression(n.expression)&&n.expression.name.text==="build"&&s.isIdentifier(n.expression.expression)&&n.expression.expression.text===e}r(F,"isFactoryBuildCall");function V(n){const e=n.parent;if(s.isVariableDeclaration(e)&&s.isIdentifier(e.name))return e.name.text}r(V,"extractVariableName");const w=r(()=>n=>n,"typed");function N(n){if(n!=null){if(n===!1)return!1;if(typeof n=="object"&&!Array.isArray(n))return n}}r(N,"asObjectOrFalse");function T(n,e){return n===!1?!1:p(n)?e(n):void 0}r(T,"parseBooleanOrConfig");function $(n,e){return p(n)?e(n):void 0}r($,"parseOptionalConfig");function B(n,e,t){const i=n[e];return p(i)?t(i):void 0}r(B,"extractSubConfig");import{parseObjectLiteral as L,evaluateExpression as U,findVariableValue as G,findObjectDeclaration as J,evaluatePropertyAccess as M,resolveTemplateLiteral as q}from"../../mutation/astExpressionEvaluator.js";export{g as asBoolean,A as asNumber,N as asObjectOrFalse,m as asString,h as asStringArray,j as asStringUnion,C as captureExtraProperties,k as collectFromAst,U as evaluateExpression,M as evaluatePropertyAccess,B as extractSubConfig,V as extractVariableName,I as findFirstInAst,J as findObjectDeclaration,G as findVariableValue,P as isAppGetAppCall,l as isCallRef,y as isExpressionRef,F as isFactoryBuildCall,S as isFactoryMethodCall,a as isIdentifierRef,E as isNamedProperty,p as isParsedObject,f as isPlainObject,O as omitUndefined,T as parseBooleanOrConfig,L as parseObjectLiteral,$ as parseOptionalConfig,u as parsedValueToSourceText,q as resolveTemplateLiteral,w as typed};
1
+ var x=Object.defineProperty;var r=(n,e)=>x(n,"name",{value:e,configurable:!0});import*as s from"typescript";import{constIncludes as d}from"../../../schemas/constants.js";function f(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}r(f,"isPlainObject");function a(n){return f(n)&&"__identifier"in n}r(a,"isIdentifierRef");function y(n){return f(n)&&"__expression"in n}r(y,"isExpressionRef");function l(n){return f(n)&&"__call"in n}r(l,"isCallRef");function p(n){return f(n)&&!("__identifier"in n)&&!("__expression"in n)&&!("__call"in n)&&!("__unknown"in n)}r(p,"isParsedObject");function m(n){return typeof n=="string"?n:void 0}r(m,"asString");function A(n){return typeof n=="number"?n:void 0}r(A,"asNumber");function g(n){return typeof n=="boolean"?n:void 0}r(g,"asBoolean");function h(n){if(!Array.isArray(n))return;const e=[];for(const t of n){if(typeof t!="string")return;e.push(t)}return e.length>0?e:void 0}r(h,"asStringArray");function j(n,e){const t=m(n);if(t!==void 0)return d(e,t)?t:void 0}r(j,"asStringUnion");function O(n){const e={};for(const[t,i]of Object.entries(n))i!==void 0&&(e[t]=i);return e}r(O,"omitUndefined");function u(n){if(n===null)return"null";if(n===void 0)return"undefined";if(typeof n=="string")return JSON.stringify(n);if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return`[${n.map(u).join(", ")}]`;if(!f(n))return String(n);if(a(n))return n.__identifier;if(y(n))return n.__expression;if(l(n))return n.__call;if("__unknown"in n&&typeof n.__unknown=="string")return n.__unknown;const e=Object.entries(n);return e.length===0?"{}":`{ ${e.map(([i,o])=>`${i}: ${u(o)}`).join(", ")} }`}r(u,"parsedValueToSourceText");function C(n,e){const t=[];for(const[i,o]of Object.entries(n))e.has(i)||o===void 0||t.push({key:i,sourceText:u(o)});return t}r(C,"captureExtraProperties");function E(n,e){return s.isPropertyAssignment(n)&&s.isIdentifier(n.name)&&n.name.text===e}r(E,"isNamedProperty");function P(n){return s.isCallExpression(n)&&s.isPropertyAccessExpression(n.expression)&&n.expression.name.text==="getApp"&&s.isIdentifier(n.expression.expression)&&n.expression.expression.text==="App"}r(P,"isAppGetAppCall");function S(n,e){const{expression:t}=n;return s.isPropertyAccessExpression(t)&&t.name.text===e&&n.arguments.length>0}r(S,"isFactoryMethodCall");function I(n,e){let t;const i=r(o=>{t===void 0&&(t=e(o),t===void 0&&s.forEachChild(o,i))},"visit");return i(n),t}r(I,"findFirstInAst");function k(n,e){const t=[],i=r(o=>{const c=e(o);c!==null&&t.push(c),s.forEachChild(o,i)},"visit");return i(n),t}r(k,"collectFromAst");function F(n,e){return s.isCallExpression(n)&&s.isPropertyAccessExpression(n.expression)&&n.expression.name.text==="build"&&s.isIdentifier(n.expression.expression)&&n.expression.expression.text===e}r(F,"isFactoryBuildCall");function V(n){const e=n.parent;if(s.isVariableDeclaration(e)&&s.isIdentifier(e.name))return e.name.text}r(V,"extractVariableName");const w=r(()=>n=>n,"typed");function N(n){if(n!=null){if(n===!1)return!1;if(typeof n=="object"&&!Array.isArray(n))return n}}r(N,"asObjectOrFalse");function T(n,e){return n===!1?!1:p(n)?e(n):void 0}r(T,"parseBooleanOrConfig");function $(n,e){return p(n)?e(n):void 0}r($,"parseOptionalConfig");function B(n,e,t){const i=n[e];return p(i)?t(i):void 0}r(B,"extractSubConfig");import{parseObjectLiteral as L,evaluateExpression as U,findVariableValue as G,findObjectDeclaration as J,evaluatePropertyAccess as M,resolveTemplateLiteral as q}from"../../mutation/astExpressionEvaluator.js";export{g as asBoolean,A as asNumber,N as asObjectOrFalse,m as asString,h as asStringArray,j as asStringUnion,C as captureExtraProperties,k as collectFromAst,U as evaluateExpression,M as evaluatePropertyAccess,B as extractSubConfig,V as extractVariableName,I as findFirstInAst,J as findObjectDeclaration,G as findVariableValue,P as isAppGetAppCall,l as isCallRef,y as isExpressionRef,F as isFactoryBuildCall,S as isFactoryMethodCall,a as isIdentifierRef,E as isNamedProperty,p as isParsedObject,f as isPlainObject,O as omitUndefined,T as parseBooleanOrConfig,L as parseObjectLiteral,$ as parseOptionalConfig,u as parsedValueToSourceText,q as resolveTemplateLiteral,w as typed};
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import * as ts from "typescript";
8
8
  import type { ApplicationResourcePlan } from "../../../schemas/resourceSchemas.js";
9
+ import type { StaticSiteHstsConfig } from "../../../schemas/patternSchemas.js";
9
10
  import { type CloudFrontPriceClass, type StaticSiteRouting } from "@fjall/util";
10
11
  /** Parsed Lambda function configuration */
11
12
  export interface ParsedLambdaConfig {
@@ -103,6 +104,7 @@ export interface ParsedStaticSitePatternConfig {
103
104
  security?: {
104
105
  headers?: boolean;
105
106
  contentSecurityPolicy?: string;
107
+ hsts?: false | StaticSiteHstsConfig;
106
108
  };
107
109
  domain?: string;
108
110
  zoneName?: string;
@@ -1 +1 @@
1
- var v=Object.defineProperty;var s=(t,e)=>v(t,"name",{value:e,configurable:!0});import*as x from"typescript";import{CLOUDFRONT_PRICE_CLASS_VALUES as P,STATIC_SITE_ROUTING_VALUES as _}from"@fjall/util";import{asBoolean as y,asNumber as c,asString as a,asStringArray as N,asStringUnion as g,asObjectOrFalse as h,collectFromAst as z,extractSubConfig as u,extractVariableName as D,isFactoryBuildCall as L,isFactoryMethodCall as E,isParsedObject as A,isPlainObject as F,parseObjectLiteral as G,parseOptionalConfig as m,typed as b}from"../common/astCommonParser.js";import{parseDeadLetterQueueConfig as C}from"./astMessagingParser.js";const R=["Instance","Aurora"],T=["postgresql","mysql"];function O(t){if(!A(t))return;const e={...t.memorySize!==void 0&&{memorySize:c(t.memorySize)},...t.timeout!==void 0&&{timeout:c(t.timeout)},...t.ephemeralStorageSize!==void 0&&{ephemeralStorageSize:c(t.ephemeralStorageSize)}};return Object.keys(e).length>0?e:void 0}s(O,"parseLambdaConfig");function U(t){return u(t,"database",e=>({type:g(e.type,R),databaseName:a(e.databaseName),databaseEngine:g(e.databaseEngine,T),deletionProtection:y(e.deletionProtection),backupRetention:c(e.backupRetention),port:c(e.port),publiclyAccessible:y(e.publiclyAccessible),allowedIpCidr:a(e.allowedIpCidr),instanceType:a(e.instanceType),allocatedStorage:c(e.allocatedStorage),multiAz:y(e.multiAz),allowVpcAccess:y(e.allowVpcAccess),monitoringInterval:c(e.monitoringInterval),preferredMaintenanceWindow:a(e.preferredMaintenanceWindow),snapshotIdentifier:a(e.snapshotIdentifier),snapshotUsername:a(e.snapshotUsername),readReplica:h(e.readReplica),writer:m(e.writer,b()),readers:h(e.readers),databaseInsights:h(e.databaseInsights),proxy:h(e.proxy),credentials:m(e.credentials,b()),encryption:m(e.encryption,b())}))}s(U,"extractPatternDatabaseConfig");function k(t){return u(t,"compute",e=>({server:m(e.server,O),imageOptimisation:m(e.imageOptimisation,O),revalidation:m(e.revalidation,O)}))}s(k,"extractPatternComputeConfig");function V(t){const e=s(n=>({versioned:y(n.versioned)}),"parseVersionedConfig");return u(t,"storage",n=>({assets:m(n.assets,e),cache:m(n.cache,e),media:m(n.media,e)}))}s(V,"extractPatternStorageConfig");function j(t){return u(t,"messaging",e=>({revalidationQueue:m(e.revalidationQueue,n=>({visibilityTimeout:c(n.visibilityTimeout),messageRetentionPeriod:c(n.messageRetentionPeriod),maxMessageSize:c(n.maxMessageSize),deadLetterQueue:C(n.deadLetterQueue)}))}))}s(j,"extractPatternMessagingConfig");function w(t){return u(t,"cdn",e=>({domainNames:N(e.domainNames),certificateArn:a(e.certificateArn)}))}s(w,"extractPatternCdnConfig");function M(t){return u(t,"environment",e=>{const n=Object.fromEntries(Object.entries(e).filter(r=>typeof r[1]=="string"));return Object.keys(n).length>0?n:void 0})}s(M,"extractPatternEnvironmentConfig");function Z(t,e){const n=B(t);return{name:e,source:a(t.source),build:u(t,"build",r=>({command:a(r.command),outputDir:a(r.outputDir)})),routing:g(t.routing,_),security:u(t,"security",r=>({headers:y(r.headers),contentSecurityPolicy:a(r.contentSecurityPolicy)})),domain:a(t.domain),zoneName:a(t.zoneName),hostedZoneId:a(t.hostedZoneId),forms:u(t,"forms",r=>({to:a(r.to),from:a(r.from),corsOrigin:a(r.corsOrigin),maxConcurrency:c(r.maxConcurrency)})),cdn:u(t,"cdn",r=>({behaviours:Array.isArray(r.behaviours)?r.behaviours:void 0,priceClass:g(r.priceClass,P),invalidateOnDeploy:y(r.invalidateOnDeploy)})),accessGate:u(t,"accessGate",r=>({type:g(r.type,["basic-auth"]),username:a(r.username),password:a(r.password)})),...n.length>0&&{unreadableFields:n}}}s(Z,"extractStaticSiteConfig");function I(t){return F(t)&&("__identifier"in t||"__expression"in t||"__call"in t||"__unknown"in t)}s(I,"isUnreadableRef");function B(t){const e=[],n=s((i,o)=>{I(i)&&e.push(o)},"check");n(t.source,"source"),n(t.routing,"routing"),n(t.domain,"domain"),n(t.zoneName,"zoneName"),n(t.hostedZoneId,"hostedZoneId");const r=[[t.build,"build",["command","outputDir"]],[t.security,"security",["headers","contentSecurityPolicy"]],[t.forms,"forms",["to","from","corsOrigin","maxConcurrency"]],[t.cdn,"cdn",["behaviours","priceClass","invalidateOnDeploy"]],[t.accessGate,"accessGate",["type","username","password"]]];for(const[i,o,d]of r)if(I(i))e.push(o);else if(A(i))for(const l of d)n(i[l],`${o}.${l}`);return e}s(B,"collectUnreadableStaticSiteFields");function p(t){return t!==void 0&&t!==""}s(p,"isReadable");function S(t,e){return new Error(`Static-site pattern '${t}' in infrastructure.ts: Fjall could not read ${e.join(", ")} as inline literal(s). Fjall reads these fields out of the file and writes them back, so they must be written inline (source: "./site"), not as a variable or an expression.`)}s(S,"unreadableStaticSiteFields");function Q(t,e){const n=e.to;if(!p(n))throw S(t,["forms.to"]);return{to:n,...e.from!==void 0&&{from:e.from},...e.corsOrigin!==void 0&&{corsOrigin:e.corsOrigin},...e.maxConcurrency!==void 0&&{maxConcurrency:e.maxConcurrency}}}s(Q,"readStaticSiteForms");function $(t,e){const n=[];if(e.type!=="basic-auth"&&n.push("accessGate.type"),p(e.username)||n.push("accessGate.username"),p(e.password)||n.push("accessGate.password"),n.length>0||e.username===void 0||e.password===void 0)throw S(t,n);return{type:"basic-auth",username:e.username,password:e.password}}s($,"readStaticSiteAccessGate");function W(t,e){if(t.arguments.length<2)return null;const n=t.arguments[0],r=t.arguments[1];if(!x.isStringLiteral(n)||!x.isObjectLiteralExpression(r))return null;const i=n.text,o=G(r),d=o.type,l=D(e),f=a(o.name);return f?d==="payload"||d==="nextjs"?{variableName:l,constructId:i,type:d,config:{name:f,domain:a(o.domain),database:U(o),compute:k(o),storage:V(o),messaging:j(o),cdn:w(o),environment:M(o)},node:t}:d==="staticsite"?{variableName:l,constructId:i,type:"staticsite",config:Z(o,f),node:t}:null:null}s(W,"extractPatternResource");function X(t){return z(t,e=>{if(!x.isCallExpression(e)||!E(e,"addPattern"))return null;const n=e.arguments[0];return L(n,"PatternFactory")?W(n,e):null})}s(X,"findPatternResources");function q(t,e){if(!e||e.length===0)return;const n=e[0];if(t.pattern=n.type,n.type==="staticsite"){const{config:i}=n,o=i.source,d=i.build?.command,l=i.build?.outputDir;if(i.unreadableFields!==void 0)throw S(i.name,i.unreadableFields);if(!p(o)||!p(d)||!p(l)){const f=[];throw p(o)||f.push("source"),p(d)||f.push("build.command"),p(l)||f.push("build.outputDir"),S(i.name,f)}t.patternConfig={type:"staticsite",name:i.name,source:o,build:{command:d,outputDir:l},routing:i.routing,security:i.security,domain:i.domain,zoneName:i.zoneName,hostedZoneId:i.hostedZoneId,...i.forms!==void 0&&{forms:Q(i.name,i.forms)},cdn:i.cdn,...i.accessGate!==void 0&&{accessGate:$(i.name,i.accessGate)}};return}const{config:r}=n;t.patternConfig={type:n.type,name:r.name,domain:r.domain,database:r.database,compute:r.compute,storage:r.storage,messaging:r.messaging,cdn:r.cdn,environment:r.environment}}s(q,"applyPatternConfig");export{q as applyPatternConfig,X as findPatternResources};
1
+ var v=Object.defineProperty;var o=(t,e)=>v(t,"name",{value:e,configurable:!0});import*as b from"typescript";import{CLOUDFRONT_PRICE_CLASS_VALUES as P,STATIC_SITE_ROUTING_VALUES as _}from"@fjall/util";import{asBoolean as p,asNumber as u,asString as a,asStringArray as D,asStringUnion as g,asObjectOrFalse as h,collectFromAst as N,extractSubConfig as m,extractVariableName as z,isFactoryBuildCall as L,isFactoryMethodCall as E,isParsedObject as S,isPlainObject as F,parseBooleanOrConfig as G,parseObjectLiteral as C,parseOptionalConfig as l,typed as O}from"../common/astCommonParser.js";import{parseDeadLetterQueueConfig as R}from"./astMessagingParser.js";const T=["Instance","Aurora"],k=["postgresql","mysql"];function A(t){if(!S(t))return;const e={...t.memorySize!==void 0&&{memorySize:u(t.memorySize)},...t.timeout!==void 0&&{timeout:u(t.timeout)},...t.ephemeralStorageSize!==void 0&&{ephemeralStorageSize:u(t.ephemeralStorageSize)}};return Object.keys(e).length>0?e:void 0}o(A,"parseLambdaConfig");function U(t){return m(t,"database",e=>({type:g(e.type,T),databaseName:a(e.databaseName),databaseEngine:g(e.databaseEngine,k),deletionProtection:p(e.deletionProtection),backupRetention:u(e.backupRetention),port:u(e.port),publiclyAccessible:p(e.publiclyAccessible),allowedIpCidr:a(e.allowedIpCidr),instanceType:a(e.instanceType),allocatedStorage:u(e.allocatedStorage),multiAz:p(e.multiAz),allowVpcAccess:p(e.allowVpcAccess),monitoringInterval:u(e.monitoringInterval),preferredMaintenanceWindow:a(e.preferredMaintenanceWindow),snapshotIdentifier:a(e.snapshotIdentifier),snapshotUsername:a(e.snapshotUsername),readReplica:h(e.readReplica),writer:l(e.writer,O()),readers:h(e.readers),databaseInsights:h(e.databaseInsights),proxy:h(e.proxy),credentials:l(e.credentials,O()),encryption:l(e.encryption,O())}))}o(U,"extractPatternDatabaseConfig");function V(t){return m(t,"compute",e=>({server:l(e.server,A),imageOptimisation:l(e.imageOptimisation,A),revalidation:l(e.revalidation,A)}))}o(V,"extractPatternComputeConfig");function j(t){const e=o(n=>({versioned:p(n.versioned)}),"parseVersionedConfig");return m(t,"storage",n=>({assets:l(n.assets,e),cache:l(n.cache,e),media:l(n.media,e)}))}o(j,"extractPatternStorageConfig");function B(t){return m(t,"messaging",e=>({revalidationQueue:l(e.revalidationQueue,n=>({visibilityTimeout:u(n.visibilityTimeout),messageRetentionPeriod:u(n.messageRetentionPeriod),maxMessageSize:u(n.maxMessageSize),deadLetterQueue:R(n.deadLetterQueue)}))}))}o(B,"extractPatternMessagingConfig");function M(t){return m(t,"cdn",e=>({domainNames:D(e.domainNames),certificateArn:a(e.certificateArn)}))}o(M,"extractPatternCdnConfig");function Z(t){return m(t,"environment",e=>{const n=Object.fromEntries(Object.entries(e).filter(i=>typeof i[1]=="string"));return Object.keys(n).length>0?n:void 0})}o(Z,"extractPatternEnvironmentConfig");function w(t,e){const n=Q(t);return{name:e,source:a(t.source),build:m(t,"build",i=>({command:a(i.command),outputDir:a(i.outputDir)})),routing:g(t.routing,_),security:m(t,"security",i=>({headers:p(i.headers),contentSecurityPolicy:a(i.contentSecurityPolicy),hsts:G(i.hsts,r=>({maxAgeDays:u(r.maxAgeDays),includeSubdomains:p(r.includeSubdomains),preload:p(r.preload)}))})),domain:a(t.domain),zoneName:a(t.zoneName),hostedZoneId:a(t.hostedZoneId),forms:m(t,"forms",i=>({to:a(i.to),from:a(i.from),corsOrigin:a(i.corsOrigin),maxConcurrency:u(i.maxConcurrency)})),cdn:m(t,"cdn",i=>({behaviours:Array.isArray(i.behaviours)?i.behaviours:void 0,priceClass:g(i.priceClass,P),invalidateOnDeploy:p(i.invalidateOnDeploy)})),accessGate:m(t,"accessGate",i=>({type:g(i.type,["basic-auth"]),username:a(i.username),password:a(i.password)})),...n.length>0&&{unreadableFields:n}}}o(w,"extractStaticSiteConfig");function I(t){return F(t)&&("__identifier"in t||"__expression"in t||"__call"in t||"__unknown"in t)}o(I,"isUnreadableRef");function Q(t){const e=[],n=o((s,c)=>{I(s)&&e.push(c)},"check");n(t.source,"source"),n(t.routing,"routing"),n(t.domain,"domain"),n(t.zoneName,"zoneName"),n(t.hostedZoneId,"hostedZoneId");const i=[[t.build,"build",["command","outputDir"]],[t.security,"security",["headers","contentSecurityPolicy","hsts"]],[t.forms,"forms",["to","from","corsOrigin","maxConcurrency"]],[t.cdn,"cdn",["behaviours","priceClass","invalidateOnDeploy"]],[t.accessGate,"accessGate",["type","username","password"]]];for(const[s,c,y]of i)if(I(s))e.push(c);else if(S(s))for(const d of y)n(s[d],`${c}.${d}`);const r=t.security;if(S(r)&&S(r.hsts)){const s=r.hsts;for(const c of["maxAgeDays","includeSubdomains","preload"])n(s[c],`security.hsts.${c}`)}return e}o(Q,"collectUnreadableStaticSiteFields");function f(t){return t!==void 0&&t!==""}o(f,"isReadable");function x(t,e){return new Error(`Static-site pattern '${t}' in infrastructure.ts: Fjall could not read ${e.join(", ")} as inline literal(s). Fjall reads these fields out of the file and writes them back, so they must be written inline (source: "./site"), not as a variable or an expression.`)}o(x,"unreadableStaticSiteFields");function $(t,e){const n=e.to;if(!f(n))throw x(t,["forms.to"]);return{to:n,...e.from!==void 0&&{from:e.from},...e.corsOrigin!==void 0&&{corsOrigin:e.corsOrigin},...e.maxConcurrency!==void 0&&{maxConcurrency:e.maxConcurrency}}}o($,"readStaticSiteForms");function W(t,e){const n=[];if(e.type!=="basic-auth"&&n.push("accessGate.type"),f(e.username)||n.push("accessGate.username"),f(e.password)||n.push("accessGate.password"),n.length>0||e.username===void 0||e.password===void 0)throw x(t,n);return{type:"basic-auth",username:e.username,password:e.password}}o(W,"readStaticSiteAccessGate");function K(t,e){if(t.arguments.length<2)return null;const n=t.arguments[0],i=t.arguments[1];if(!b.isStringLiteral(n)||!b.isObjectLiteralExpression(i))return null;const r=n.text,s=C(i),c=s.type,y=z(e),d=a(s.name);return d?c==="payload"||c==="nextjs"?{variableName:y,constructId:r,type:c,config:{name:d,domain:a(s.domain),database:U(s),compute:V(s),storage:j(s),messaging:B(s),cdn:M(s),environment:Z(s)},node:t}:c==="staticsite"?{variableName:y,constructId:r,type:"staticsite",config:w(s,d),node:t}:null:null}o(K,"extractPatternResource");function q(t){return N(t,e=>{if(!b.isCallExpression(e)||!E(e,"addPattern"))return null;const n=e.arguments[0];return L(n,"PatternFactory")?K(n,e):null})}o(q,"findPatternResources");function ee(t,e){if(!e||e.length===0)return;const n=e[0];if(t.pattern=n.type,n.type==="staticsite"){const{config:r}=n,s=r.source,c=r.build?.command,y=r.build?.outputDir;if(r.unreadableFields!==void 0)throw x(r.name,r.unreadableFields);if(!f(s)||!f(c)||!f(y)){const d=[];throw f(s)||d.push("source"),f(c)||d.push("build.command"),f(y)||d.push("build.outputDir"),x(r.name,d)}t.patternConfig={type:"staticsite",name:r.name,source:s,build:{command:c,outputDir:y},routing:r.routing,security:r.security,domain:r.domain,zoneName:r.zoneName,hostedZoneId:r.hostedZoneId,...r.forms!==void 0&&{forms:$(r.name,r.forms)},cdn:r.cdn,...r.accessGate!==void 0&&{accessGate:W(r.name,r.accessGate)}};return}const{config:i}=n;t.patternConfig={type:n.type,name:i.name,domain:i.domain,database:i.database,compute:i.compute,storage:i.storage,messaging:i.messaging,cdn:i.cdn,environment:i.environment}}o(ee,"applyPatternConfig");export{ee as applyPatternConfig,q as findPatternResources};
@@ -6,6 +6,7 @@ export declare const TypedFjallTargetSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
6
6
  }, z.core.$strict>, z.ZodObject<{
7
7
  kind: z.ZodLiteral<"cdn">;
8
8
  appName: z.ZodString;
9
+ cdnName: z.ZodOptional<z.ZodString>;
9
10
  }, z.core.$strict>, z.ZodObject<{
10
11
  kind: z.ZodLiteral<"bucket">;
11
12
  appName: z.ZodString;
@@ -80,6 +81,7 @@ export declare const ParsedAliasRecordSchema: z.ZodObject<{
80
81
  }, z.core.$strict>, z.ZodObject<{
81
82
  kind: z.ZodLiteral<"cdn">;
82
83
  appName: z.ZodString;
84
+ cdnName: z.ZodOptional<z.ZodString>;
83
85
  }, z.core.$strict>, z.ZodObject<{
84
86
  kind: z.ZodLiteral<"bucket">;
85
87
  appName: z.ZodString;
@@ -121,6 +123,7 @@ export declare const ParsedDnsRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject
121
123
  }, z.core.$strict>, z.ZodObject<{
122
124
  kind: z.ZodLiteral<"cdn">;
123
125
  appName: z.ZodString;
126
+ cdnName: z.ZodOptional<z.ZodString>;
124
127
  }, z.core.$strict>, z.ZodObject<{
125
128
  kind: z.ZodLiteral<"bucket">;
126
129
  appName: z.ZodString;
@@ -199,6 +202,7 @@ export declare const ParsedDomainRecordsSchema: z.ZodObject<{
199
202
  }, z.core.$strict>, z.ZodObject<{
200
203
  kind: z.ZodLiteral<"cdn">;
201
204
  appName: z.ZodString;
205
+ cdnName: z.ZodOptional<z.ZodString>;
202
206
  }, z.core.$strict>, z.ZodObject<{
203
207
  kind: z.ZodLiteral<"bucket">;
204
208
  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(),computeName:e.string().min(1).optional()}).strict(),e.object({kind:e.literal("cdn"),appName:e.string()}).strict(),e.object({kind:e.literal("bucket"),appName:e.string(),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
+ 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(),cdnName:e.string().min(1).optional()}).strict(),e.object({kind:e.literal("bucket"),appName:e.string(),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,6 +1,6 @@
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(`
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 C(e,n){return e==="@"&&n!=="@"?-1:e!=="@"&&n==="@"?1:e.localeCompare(n)}o(C,"compareName");function b(e,n){const t=Array.isArray(e)?e.join(`
2
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.appName)}, ${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(`
3
+ `):n;return t.localeCompare(i)}o(b,"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=C(f,m);return u!==0?u:n.kind==="standard"&&t.kind==="standard"?b(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 e.cdnName===void 0?`fjallCdn(${JSON.stringify(e.appName)})`:`fjallCdn(${JSON.stringify(e.appName)}, ${JSON.stringify(e.cdnName)})`;case"bucket":return`fjallBucket(${JSON.stringify(e.appName)}, ${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
6
  ${n.map(i=>` ${i},`).join(`
@@ -8,7 +8,7 @@ ${n.map(i=>` ${i},`).join(`
8
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
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"?`
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)),N=[...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 h=y("certificates",u,z),S=y("records",m,w),$=e.registrar==="external-records"?"":B(e.zoneName,N),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"
@@ -40,7 +40,7 @@ new Domain(stack, ${JSON.stringify(i)}, {
40
40
  zoneName: ${JSON.stringify(e.zoneName)},
41
41
  ${r.length>0?r.join(`
42
42
  `)+`
43
- `:""}${N}
43
+ `:""}${h}
44
44
  ${S}
45
45
  });
46
46
  ${$}`}o(K,"emitDomainTs");export{K as emitDomainTs,T as emitRecordObjectText};
@@ -277,6 +277,11 @@ export declare const ApplicationResourcePlanSchema: z.ZodObject<{
277
277
  security: z.ZodOptional<z.ZodObject<{
278
278
  headers: z.ZodOptional<z.ZodBoolean>;
279
279
  contentSecurityPolicy: z.ZodOptional<z.ZodString>;
280
+ hsts: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
281
+ maxAgeDays: z.ZodOptional<z.ZodNumber>;
282
+ includeSubdomains: z.ZodOptional<z.ZodBoolean>;
283
+ preload: z.ZodOptional<z.ZodBoolean>;
284
+ }, z.core.$strict>]>>;
280
285
  }, z.core.$strict>>;
281
286
  domain: z.ZodOptional<z.ZodString>;
282
287
  zoneName: z.ZodOptional<z.ZodString>;
@@ -434,12 +434,28 @@ export declare const StaticSiteBuildConfigSchema: z.ZodObject<{
434
434
  outputDir: z.ZodString;
435
435
  }, z.core.$strict>;
436
436
  export type StaticSiteBuildConfig = z.infer<typeof StaticSiteBuildConfigSchema>;
437
+ /**
438
+ * HSTS directives a static site may set. Not exported as a schema — only the
439
+ * inferred type leaves this module, so the union below stays the single place
440
+ * the shape is spelled out.
441
+ */
442
+ declare const StaticSiteHstsConfigSchema: z.ZodObject<{
443
+ maxAgeDays: z.ZodOptional<z.ZodNumber>;
444
+ includeSubdomains: z.ZodOptional<z.ZodBoolean>;
445
+ preload: z.ZodOptional<z.ZodBoolean>;
446
+ }, z.core.$strict>;
447
+ export type StaticSiteHstsConfig = z.infer<typeof StaticSiteHstsConfigSchema>;
437
448
  /**
438
449
  * Security-header configuration for a static site.
439
450
  */
440
451
  export declare const StaticSiteSecurityConfigSchema: z.ZodObject<{
441
452
  headers: z.ZodOptional<z.ZodBoolean>;
442
453
  contentSecurityPolicy: z.ZodOptional<z.ZodString>;
454
+ hsts: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
455
+ maxAgeDays: z.ZodOptional<z.ZodNumber>;
456
+ includeSubdomains: z.ZodOptional<z.ZodBoolean>;
457
+ preload: z.ZodOptional<z.ZodBoolean>;
458
+ }, z.core.$strict>]>>;
443
459
  }, z.core.$strict>;
444
460
  export type StaticSiteSecurityConfig = z.infer<typeof StaticSiteSecurityConfigSchema>;
445
461
  /**
@@ -509,6 +525,11 @@ export declare const StaticSitePatternConfigSchema: z.ZodObject<{
509
525
  security: z.ZodOptional<z.ZodObject<{
510
526
  headers: z.ZodOptional<z.ZodBoolean>;
511
527
  contentSecurityPolicy: z.ZodOptional<z.ZodString>;
528
+ hsts: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
529
+ maxAgeDays: z.ZodOptional<z.ZodNumber>;
530
+ includeSubdomains: z.ZodOptional<z.ZodBoolean>;
531
+ preload: z.ZodOptional<z.ZodBoolean>;
532
+ }, z.core.$strict>]>>;
512
533
  }, z.core.$strict>>;
513
534
  domain: z.ZodOptional<z.ZodString>;
514
535
  zoneName: z.ZodOptional<z.ZodString>;
@@ -797,6 +818,11 @@ export declare const PatternConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
797
818
  security: z.ZodOptional<z.ZodObject<{
798
819
  headers: z.ZodOptional<z.ZodBoolean>;
799
820
  contentSecurityPolicy: z.ZodOptional<z.ZodString>;
821
+ hsts: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
822
+ maxAgeDays: z.ZodOptional<z.ZodNumber>;
823
+ includeSubdomains: z.ZodOptional<z.ZodBoolean>;
824
+ preload: z.ZodOptional<z.ZodBoolean>;
825
+ }, z.core.$strict>]>>;
800
826
  }, z.core.$strict>>;
801
827
  domain: z.ZodOptional<z.ZodString>;
802
828
  zoneName: z.ZodOptional<z.ZodString>;
@@ -870,3 +896,4 @@ export type PayloadCdnConfig = z.infer<typeof PayloadCdnConfigSchema>;
870
896
  export type PayloadPatternConfig = z.infer<typeof PayloadPatternConfigSchema>;
871
897
  export type NextJSPatternConfig = z.infer<typeof NextJSPatternConfigSchema>;
872
898
  export type PatternConfig = z.infer<typeof PatternConfigSchema>;
899
+ export {};
@@ -1 +1 @@
1
- import{z as t}from"zod";import{VALIDATION_MESSAGES as o,VALIDATION_PATTERNS as n}from"../validation/patterns.js";import{BackupRetentionSchema as c,MonitoringIntervalSchema as u,DatabasePortSchema as T,ProxyConfigOrFalseSchema as R,ReadReplicaConfigOrFalseSchema as b,AuroraWriterConfigSchema as M,AuroraReadersConfigOrFalseSchema as f,DatabaseInsightsConfigOrFalseSchema as h,CredentialsConfigSchema as C,EncryptionConfigSchema as N}from"./databaseSchemas.js";import{LambdaMemorySchema as p}from"./computeSchemas.js";import{PATTERN_DATABASE_TYPES as l,DATABASE_ENGINES as O}from"./constants.js";import{CLOUDFRONT_PRICE_CLASS_VALUES as _,STATIC_SITE_ROUTING_VALUES as x,isAddressAtDomain as y}from"@fjall/util";const a=t.object({memorySize:p.optional(),timeout:t.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(1,o.LAMBDA.TIMEOUT.MIN).max(900,o.LAMBDA.TIMEOUT.MAX).optional(),ephemeralStorageSize:t.number().int(o.EPHEMERAL_STORAGE.INTEGER).min(512,o.EPHEMERAL_STORAGE.MIN).max(10240,o.EPHEMERAL_STORAGE.MAX).optional()}).strict(),E=t.object({type:t.enum(l).optional(),databaseName:t.string().optional(),databaseEngine:t.enum(O).optional(),deletionProtection:t.boolean().optional(),backupRetention:c.optional(),port:T.optional(),publiclyAccessible:t.boolean().optional(),allowedIpCidr:t.string().optional(),instanceType:t.string().optional(),allocatedStorage:t.number().int(o.ALLOCATED_STORAGE.INTEGER).min(20,o.ALLOCATED_STORAGE.MIN).max(65536,o.ALLOCATED_STORAGE.MAX).optional(),multiAz:t.boolean().optional(),readReplica:b.optional(),writer:M.optional(),readers:f.optional(),allowVpcAccess:t.boolean().optional(),monitoringInterval:u.optional(),preferredMaintenanceWindow:t.string().optional(),databaseInsights:h.optional(),proxy:R.optional(),credentials:C.optional(),encryption:N.optional(),snapshotIdentifier:t.string().optional(),snapshotUsername:t.string().optional()}).strict(),S=t.object({server:a.optional(),imageOptimisation:a.optional(),revalidation:a.optional()}).strict(),r=t.object({versioned:t.boolean().optional()}).strict(),d=t.object({assets:r.optional(),cache:r.optional(),media:r.optional()}).strict(),P=t.object({visibilityTimeout:t.number().int(o.SQS.VISIBILITY_TIMEOUT.INTEGER).min(0,o.SQS.VISIBILITY_TIMEOUT.MIN).max(43200,o.SQS.VISIBILITY_TIMEOUT.MAX).optional(),messageRetentionPeriod:t.number().int(o.SQS.RETENTION_PERIOD.INTEGER).min(60,o.SQS.RETENTION_PERIOD.MIN).max(1209600,o.SQS.RETENTION_PERIOD.MAX).optional(),maxMessageSize:t.number().int(o.MAX_MESSAGE_SIZE.INTEGER).min(1024,o.MAX_MESSAGE_SIZE.MIN).max(262144,o.MAX_MESSAGE_SIZE.MAX).optional(),deadLetterQueue:t.union([t.literal(!1),t.object({enabled:t.boolean().optional(),maxReceiveCount:t.number().int(o.DLQ.MAX_RECEIVE_COUNT.INTEGER).min(1,o.DLQ.MAX_RECEIVE_COUNT.MIN).max(1e3,o.DLQ.MAX_RECEIVE_COUNT.MAX).optional()}).strict()]).optional()}).strict(),A=t.object({revalidationQueue:P.optional()}).strict(),g=t.object({domainNames:t.array(t.string()).optional(),certificateArn:t.string().optional()}).strict(),I=t.record(t.string().regex(n.ENV_VAR_NAME,o.ENV_VAR_NAME),t.string()).optional(),D=t.object({type:t.literal("payload"),name:t.string().min(1,o.REQUIRED.PATTERN_NAME),domain:t.string().optional(),database:E.optional(),compute:S.optional(),storage:d.optional(),messaging:A.optional(),cdn:g.optional(),environment:I}).strict(),L=t.object({type:t.literal("nextjs"),name:t.string().min(1,o.REQUIRED.PATTERN_NAME),domain:t.string().optional(),database:E.optional(),compute:S.optional(),storage:d.optional(),messaging:A.optional(),cdn:g.optional(),environment:I}).strict(),U=t.enum(x),G=t.object({command:t.string().min(1,o.REQUIRED.BUILD_COMMAND),outputDir:t.string().min(1,o.REQUIRED.OUTPUT_DIR)}).strict(),j=t.object({headers:t.boolean().optional(),contentSecurityPolicy:t.string().optional()}).strict(),Q=t.object({to:t.string().min(1,o.REQUIRED.FORMS_TO).regex(n.EMAIL,o.EMAIL),from:t.string().regex(n.EMAIL,o.EMAIL).optional(),corsOrigin:t.string().regex(n.HTTP_ORIGIN,"corsOrigin must be an exact origin such as https://example.com (no path, no trailing slash)").optional(),maxConcurrency:t.number().int().min(1).max(100).optional()}).strict(),v=t.object({behaviours:t.array(t.unknown()).optional(),priceClass:t.enum(_).optional(),invalidateOnDeploy:t.boolean().optional()}).strict(),B=t.object({type:t.literal("basic-auth"),username:t.string().min(1,"accessGate.username must not be empty"),password:t.string().min(1,"accessGate.password must not be empty")}).strict(),V=t.object({type:t.literal("staticsite"),name:t.string().min(1,o.REQUIRED.PATTERN_NAME),source:t.string().min(1,o.REQUIRED.SOURCE),build:G,routing:U.optional(),security:j.optional(),domain:t.string().optional(),zoneName:t.string().optional(),hostedZoneId:t.string().optional(),forms:Q.optional(),cdn:v.optional(),accessGate:B.optional()}).strict().superRefine((i,s)=>{if(i.forms===void 0)return;const e=i.domain;if(e===void 0||e===""){s.addIssue({code:"custom",path:["domain"],message:"A domain is required when forms are enabled: SES sends only from a verified identity, and the site's domain is the identity the pattern verifies"});return}const m=i.forms.from;m!==void 0&&!y(m,e)&&s.addIssue({code:"custom",path:["forms","from"],message:`forms.from must be an address at ${e} (the verified SES identity) \u2014 for example noreply@${e}. Use forms.to for the recipient.`})}),Y=t.discriminatedUnion("type",[D,L,V]),Z=t.enum(["lightweight","standard","resilient","custom"]),W=t.object({type:t.enum(l),instanceType:t.string().optional(),backupRetention:c.optional(),deletionProtection:t.boolean().optional(),encryption:t.union([t.object({useCMK:t.literal(!0)}).strict(),t.literal(!1)]).optional()}).strict(),$=t.object({memorySize:p.optional(),timeout:t.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(1,o.LAMBDA.TIMEOUT.MIN).max(900,o.LAMBDA.TIMEOUT.MAX).optional()}).strict();export{$ as CustomPatternComputeSchema,W as CustomPatternDatabaseSchema,L as NextJSPatternConfigSchema,Y as PatternConfigSchema,a as PatternLambdaConfigSchema,P as PatternQueueConfigSchema,r as PatternStorageBucketConfigSchema,Z as PatternTierSchema,g as PayloadCdnConfigSchema,S as PayloadComputeConfigSchema,E as PayloadDatabaseConfigSchema,A as PayloadMessagingConfigSchema,D as PayloadPatternConfigSchema,d as PayloadStorageConfigSchema,B as StaticSiteAccessGateConfigSchema,G as StaticSiteBuildConfigSchema,v as StaticSiteCdnConfigSchema,Q as StaticSiteFormsConfigSchema,V as StaticSitePatternConfigSchema,U as StaticSiteRoutingSchema,j as StaticSiteSecurityConfigSchema};
1
+ import{z as t}from"zod";import{VALIDATION_MESSAGES as o,VALIDATION_PATTERNS as n}from"../validation/patterns.js";import{BackupRetentionSchema as m,MonitoringIntervalSchema as u,DatabasePortSchema as T,ProxyConfigOrFalseSchema as b,ReadReplicaConfigOrFalseSchema as R,AuroraWriterConfigSchema as M,AuroraReadersConfigOrFalseSchema as f,DatabaseInsightsConfigOrFalseSchema as h,CredentialsConfigSchema as C,EncryptionConfigSchema as N}from"./databaseSchemas.js";import{LambdaMemorySchema as l}from"./computeSchemas.js";import{PATTERN_DATABASE_TYPES as p,DATABASE_ENGINES as O}from"./constants.js";import{CLOUDFRONT_PRICE_CLASS_VALUES as _,STATIC_SITE_ROUTING_VALUES as x,isAddressAtDomain as y}from"@fjall/util";const a=t.object({memorySize:l.optional(),timeout:t.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(1,o.LAMBDA.TIMEOUT.MIN).max(900,o.LAMBDA.TIMEOUT.MAX).optional(),ephemeralStorageSize:t.number().int(o.EPHEMERAL_STORAGE.INTEGER).min(512,o.EPHEMERAL_STORAGE.MIN).max(10240,o.EPHEMERAL_STORAGE.MAX).optional()}).strict(),E=t.object({type:t.enum(p).optional(),databaseName:t.string().optional(),databaseEngine:t.enum(O).optional(),deletionProtection:t.boolean().optional(),backupRetention:m.optional(),port:T.optional(),publiclyAccessible:t.boolean().optional(),allowedIpCidr:t.string().optional(),instanceType:t.string().optional(),allocatedStorage:t.number().int(o.ALLOCATED_STORAGE.INTEGER).min(20,o.ALLOCATED_STORAGE.MIN).max(65536,o.ALLOCATED_STORAGE.MAX).optional(),multiAz:t.boolean().optional(),readReplica:R.optional(),writer:M.optional(),readers:f.optional(),allowVpcAccess:t.boolean().optional(),monitoringInterval:u.optional(),preferredMaintenanceWindow:t.string().optional(),databaseInsights:h.optional(),proxy:b.optional(),credentials:C.optional(),encryption:N.optional(),snapshotIdentifier:t.string().optional(),snapshotUsername:t.string().optional()}).strict(),S=t.object({server:a.optional(),imageOptimisation:a.optional(),revalidation:a.optional()}).strict(),r=t.object({versioned:t.boolean().optional()}).strict(),d=t.object({assets:r.optional(),cache:r.optional(),media:r.optional()}).strict(),D=t.object({visibilityTimeout:t.number().int(o.SQS.VISIBILITY_TIMEOUT.INTEGER).min(0,o.SQS.VISIBILITY_TIMEOUT.MIN).max(43200,o.SQS.VISIBILITY_TIMEOUT.MAX).optional(),messageRetentionPeriod:t.number().int(o.SQS.RETENTION_PERIOD.INTEGER).min(60,o.SQS.RETENTION_PERIOD.MIN).max(1209600,o.SQS.RETENTION_PERIOD.MAX).optional(),maxMessageSize:t.number().int(o.MAX_MESSAGE_SIZE.INTEGER).min(1024,o.MAX_MESSAGE_SIZE.MIN).max(262144,o.MAX_MESSAGE_SIZE.MAX).optional(),deadLetterQueue:t.union([t.literal(!1),t.object({enabled:t.boolean().optional(),maxReceiveCount:t.number().int(o.DLQ.MAX_RECEIVE_COUNT.INTEGER).min(1,o.DLQ.MAX_RECEIVE_COUNT.MIN).max(1e3,o.DLQ.MAX_RECEIVE_COUNT.MAX).optional()}).strict()]).optional()}).strict(),A=t.object({revalidationQueue:D.optional()}).strict(),g=t.object({domainNames:t.array(t.string()).optional(),certificateArn:t.string().optional()}).strict(),I=t.record(t.string().regex(n.ENV_VAR_NAME,o.ENV_VAR_NAME),t.string()).optional(),P=t.object({type:t.literal("payload"),name:t.string().min(1,o.REQUIRED.PATTERN_NAME),domain:t.string().optional(),database:E.optional(),compute:S.optional(),storage:d.optional(),messaging:A.optional(),cdn:g.optional(),environment:I}).strict(),L=t.object({type:t.literal("nextjs"),name:t.string().min(1,o.REQUIRED.PATTERN_NAME),domain:t.string().optional(),database:E.optional(),compute:S.optional(),storage:d.optional(),messaging:A.optional(),cdn:g.optional(),environment:I}).strict(),U=t.enum(x),G=t.object({command:t.string().min(1,o.REQUIRED.BUILD_COMMAND),outputDir:t.string().min(1,o.REQUIRED.OUTPUT_DIR)}).strict(),j=t.object({maxAgeDays:t.number().optional(),includeSubdomains:t.boolean().optional(),preload:t.boolean().optional()}).strict(),Q=t.object({headers:t.boolean().optional(),contentSecurityPolicy:t.string().optional(),hsts:t.union([t.literal(!1),j]).optional()}).strict(),v=t.object({to:t.string().min(1,o.REQUIRED.FORMS_TO).regex(n.EMAIL,o.EMAIL),from:t.string().regex(n.EMAIL,o.EMAIL).optional(),corsOrigin:t.string().regex(n.HTTP_ORIGIN,"corsOrigin must be an exact origin such as https://example.com (no path, no trailing slash)").optional(),maxConcurrency:t.number().int().min(1).max(100).optional()}).strict(),B=t.object({behaviours:t.array(t.unknown()).optional(),priceClass:t.enum(_).optional(),invalidateOnDeploy:t.boolean().optional()}).strict(),V=t.object({type:t.literal("basic-auth"),username:t.string().min(1,"accessGate.username must not be empty"),password:t.string().min(1,"accessGate.password must not be empty")}).strict(),X=t.object({type:t.literal("staticsite"),name:t.string().min(1,o.REQUIRED.PATTERN_NAME),source:t.string().min(1,o.REQUIRED.SOURCE),build:G,routing:U.optional(),security:Q.optional(),domain:t.string().optional(),zoneName:t.string().optional(),hostedZoneId:t.string().optional(),forms:v.optional(),cdn:B.optional(),accessGate:V.optional()}).strict().superRefine((i,s)=>{if(i.forms===void 0)return;const e=i.domain;if(e===void 0||e===""){s.addIssue({code:"custom",path:["domain"],message:"A domain is required when forms are enabled: SES sends only from a verified identity, and the site's domain is the identity the pattern verifies"});return}const c=i.forms.from;c!==void 0&&!y(c,e)&&s.addIssue({code:"custom",path:["forms","from"],message:`forms.from must be an address at ${e} (the verified SES identity) \u2014 for example noreply@${e}. Use forms.to for the recipient.`})}),Z=t.discriminatedUnion("type",[P,L,X]),W=t.enum(["lightweight","standard","resilient","custom"]),$=t.object({type:t.enum(p),instanceType:t.string().optional(),backupRetention:m.optional(),deletionProtection:t.boolean().optional(),encryption:t.union([t.object({useCMK:t.literal(!0)}).strict(),t.literal(!1)]).optional()}).strict(),q=t.object({memorySize:l.optional(),timeout:t.number().int(o.LAMBDA.TIMEOUT.INTEGER).min(1,o.LAMBDA.TIMEOUT.MIN).max(900,o.LAMBDA.TIMEOUT.MAX).optional()}).strict();export{q as CustomPatternComputeSchema,$ as CustomPatternDatabaseSchema,L as NextJSPatternConfigSchema,Z as PatternConfigSchema,a as PatternLambdaConfigSchema,D as PatternQueueConfigSchema,r as PatternStorageBucketConfigSchema,W as PatternTierSchema,g as PayloadCdnConfigSchema,S as PayloadComputeConfigSchema,E as PayloadDatabaseConfigSchema,A as PayloadMessagingConfigSchema,P as PayloadPatternConfigSchema,d as PayloadStorageConfigSchema,V as StaticSiteAccessGateConfigSchema,G as StaticSiteBuildConfigSchema,B as StaticSiteCdnConfigSchema,v as StaticSiteFormsConfigSchema,X as StaticSitePatternConfigSchema,U as StaticSiteRoutingSchema,Q as StaticSiteSecurityConfigSchema};
@@ -1 +1 @@
1
- export declare const GENERATOR_VERSION = "25.0.0";
1
+ export declare const GENERATOR_VERSION = "27.0.0";
@@ -1 +1 @@
1
- const E="25.0.0";export{E as GENERATOR_VERSION};
1
+ const E="27.0.0";export{E as GENERATOR_VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/generator",
3
- "version": "25.0.0",
3
+ "version": "27.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fjall-tech/fjall.git",
@@ -58,7 +58,7 @@
58
58
  "license": "SEE LICENSE IN LICENSE",
59
59
  "dependencies": {
60
60
  "@babel/parser": "^7.29.8",
61
- "@fjall/util": "^25.0.0",
61
+ "@fjall/util": "^27.0.0",
62
62
  "ast-types": "^0.16.1",
63
63
  "recast": "^0.23.12",
64
64
  "ts-morph": "^28.0.0",
@@ -66,13 +66,11 @@
66
66
  "zod": "^4.4.3"
67
67
  },
68
68
  "devDependencies": {
69
- "@eslint/js": "^10.0.1",
70
69
  "@types/node": "^26.1.2",
71
70
  "@typescript-eslint/parser": "^8.65.0",
72
71
  "@vitest/coverage-v8": "^4.1.10",
73
72
  "eslint": "^10.8.0",
74
73
  "fast-check": "^4.9.0",
75
- "typescript-eslint": "^8.65.0",
76
74
  "vitest": "^4.1.10"
77
75
  }
78
76
  }