@fjall/generator 12.1.1 → 12.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.
@@ -9,7 +9,7 @@
9
9
  "package.json",
10
10
  "tsconfig.json"
11
11
  ],
12
- "hash": "53203d5b524831113b90b9a87aff8b37bc1aecf83f13bf90974afec0d9d4819f",
12
+ "hash": "70d7052bae6f8d76638dc53a083ec0ad54264f9c933a32bf28b85e86c2b58eb6",
13
13
  "files": {
14
14
  "src/ast/astTestHelpers.ts": "026cac849eb88bdb",
15
15
  "src/ast/domain/astDomainParser.ts": "940ce5742507477d",
@@ -110,9 +110,10 @@
110
110
  "src/detection/index.ts": "b4ad9a935564cb3e",
111
111
  "src/dns/bindParser.ts": "376d274bf9e4bf9f",
112
112
  "src/dns/bindWriter.ts": "c296911ce5aef77c",
113
- "src/dns/domainFileGenerator.ts": "29ece83900ecc829",
113
+ "src/dns/domainFileGenerator.ts": "179258ce9d15d990",
114
114
  "src/dns/domainRecords.ts": "ab917006b92ae916",
115
- "src/dns/index.ts": "b476ef3d7b381dc8",
115
+ "src/dns/index.ts": "c6d17b06c04a0903",
116
+ "src/dns/tsEmitter.ts": "d5814cd65ba1a05e",
116
117
  "src/dns/types.ts": "82d6db9d7d26dbc2",
117
118
  "src/generation/common.ts": "ab66eac580bc227f",
118
119
  "src/generation/compute.ts": "4029a0d8e3197686",
@@ -170,11 +171,11 @@
170
171
  "src/validation/patterns.ts": "f9629eafdad7ac3e",
171
172
  "src/validation/validationMessages.ts": "c727ade4690274f4",
172
173
  "src/validation/validationPatterns.ts": "865f3d688975b7c8",
173
- "src/version.ts": "342a42667dafc82e",
174
+ "src/version.ts": "3a2b6b85d28d1013",
174
175
  "../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
175
- "package.json": "64759ec8031b63be",
176
+ "package.json": "c615cc7b37876c27",
176
177
  "tsconfig.json": "1929cf3f99fe9b1e"
177
178
  },
178
- "outputHash": "0fe5c0bd63e8fef719fa9e80e5358c25c250ebdcec6c17bd04f0b4df18b65355",
179
- "outputFileCount": 321
179
+ "outputHash": "f4bdba589f6bd59b4d0751e5b2443cc69c006510f8e06b4f23d6e66650d54ab6",
180
+ "outputFileCount": 323
180
181
  }
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 160 files minified at 2026-08-15T09:46:48.150Z
1
+ 161 files minified at 2026-08-16T01:19:39.773Z
@@ -1,6 +1,6 @@
1
1
  import type { DnsRecord } from "./types.js";
2
2
  export interface GeneratedFile {
3
- /** Path relative to the repo root (e.g. "fjall/domains/example.com/zone.bind") */
3
+ /** Path relative to the repo root (e.g. "fjall/domains/example.com/infrastructure.ts") */
4
4
  readonly path: string;
5
5
  /** File content as a string */
6
6
  readonly content: string;
@@ -12,6 +12,13 @@ export interface DomainGenerationOptions {
12
12
  readonly hostedZoneId?: string;
13
13
  /** Pre-populated DNS records (e.g. from Route53 import) */
14
14
  readonly records?: DnsRecord[];
15
+ /**
16
+ * Directory the domain component is generated into, relative to the repo
17
+ * root — `<boundaryDir>/domains/<domainName>` when the fjall boundary
18
+ * lives inside a container directory. Defaults to the bare-boundary
19
+ * spelling `fjall/domains/<domainName>`.
20
+ */
21
+ readonly basePath?: string;
15
22
  }
16
23
  /**
17
24
  * Generates all files for a domain component as pure strings.
@@ -1,7 +1,7 @@
1
- var p=Object.defineProperty;var r=(t,e)=>p(t,"name",{value:e,configurable:!0});import{getDomainStackName as w}from"@fjall/util";import{toPascalCase as f}from"../generation/common.js";import{GENERATOR_VERSION as u}from"../version.js";function j(t){const{domainName:e,hostedZoneId:o,records:n=[]}=t,a=`fjall/domains/${e}`;return[{path:`${a}/infrastructure.ts`,content:k({domainName:e,records:n,hostedZoneId:o})},{path:`${a}/package.json`,content:g(e)},{path:`${a}/tsconfig.json`,content:S},{path:`${a}/cdk.json`,content:N},{path:`${a}/.gitignore`,content:y}]}r(j,"generateDomainFiles");function k(t){const{domainName:e,records:o,hostedZoneId:n}=t,a=f(e.split(".").join("")),c=w(e),i=o.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} },`}),d=i.length>0?`[
2
- ${i.join(`
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 w}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:h({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 h(t){const{domainName:e,records:r,hostedZoneId:n}=t,a=w(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
+ ${c.join(`
3
3
  `)}
4
- ]`:"[]",l=n?` hostedZoneId: ${JSON.stringify(n)},
4
+ ]`:"[]",u=n?` hostedZoneId: ${JSON.stringify(n)},
5
5
  `:"";return`import {
6
6
  App,
7
7
  Domain,
@@ -10,29 +10,164 @@ ${i.join(`
10
10
  // Fjall-managed domain \u2014 edit this file to add or change records.
11
11
  // See https://docs.fjall.io/resources/networking/domain for the Domain construct API.
12
12
 
13
- const app = App.getApp(${JSON.stringify(c)});
14
-
15
- // Stack name must equal getDomainStackName(${JSON.stringify(e)}) \u2014 the CLI's
16
- // deploy record and ManagedDomainBinding resolution both DescribeStacks by it.
17
- const stack = app.getStack(${JSON.stringify(c)}).getStack();
13
+ const app = App.getApp(${JSON.stringify(i)});
14
+ // The stack name is Fjall's domain deploy contract (getDomainStackName) \u2014
15
+ // the CLI records and resolves the deployed domain by this exact
16
+ // CloudFormation stack name. Do not rename it.
17
+ const stack = app.getStack(${JSON.stringify(i)}).getStack();
18
18
 
19
19
  new Domain(stack, ${JSON.stringify(a)}, {
20
20
  registrar: "route53",
21
21
  zoneName: ${JSON.stringify(e)},
22
- ${l} certificates: [
22
+ ${u} certificates: [
23
23
  { domainName: ${JSON.stringify(e)} },
24
+ // Serving this zone through CloudFront (staticsite/cdn)? Add a viewer
25
+ // certificate with cloudFront: true \u2014 it is minted in us-east-1 (the
26
+ // only region CloudFront accepts) and publishes the zone-level
27
+ // us-east-1 certificate export the deploy binding carries, e.g.:
28
+ // { domainName: "www.${e}", cloudFront: true },
24
29
  ],
25
- records: ${d},
30
+ records: ${l},
26
31
  });
27
- `}r(k,"generateDefaultInfrastructureTs");function g(t){return JSON.stringify({name:`domain-${t}`,version:u,scripts:{},devDependencies:{"@types/node":"20.4.9","ts-node":"^10.9.1",typescript:"~5.1.6"},dependencies:{"@fjall/components-infrastructure":`^${u}`,"aws-cdk-lib":"^2.265.0",constructs:"^10.7.2"}},null,2)+`
28
- `}r(g,"generateDomainPackageJson");const y=`node_modules/
29
- cdk.out/
32
+
33
+ // Delegating a subdomain to another account? (D8 \u2014 child writes NS.)
34
+ // Declare the child as its own Domain with registrar: "external-delegated"
35
+ // and delegatedSubdomain set; the Fjall CLI injects parentDelegationRoleArn
36
+ // (ManagedDomainBinding.delegationRoleArn) so the child UPSERTs its NS
37
+ // records into this zone. This apex declares no delegations[].
38
+ // Adopting an EXISTING child zone instead of creating one? Set hostedZoneId
39
+ // and adoptedNameServers (both together) on the child Domain \u2014 the literals
40
+ // feed the parent NS UPSERT because an imported zone exposes no name-server
41
+ // attribute at synth.
42
+ `}o(h,"generateDefaultInfrastructureTs");function f(t){return`{
43
+ "name": ${JSON.stringify(`domain-${t}`)},
44
+ "version": "${d}",
45
+ "type": "module",
46
+ "scripts": {},
47
+ "devDependencies": {
48
+ "@types/node": "25.6.0",
49
+ "tsx": "^4.21.0",
50
+ "typescript": "~6.0.3"
51
+ },
52
+ "dependencies": {
53
+ "@fjall/components-infrastructure": "^${d}",
54
+ "aws-cdk-lib": "^2.265.0",
55
+ "constructs": "^10.7.2"
56
+ }
57
+ }
58
+ `}o(f,"generateDomainPackageJson");const k=`*.js
30
59
  *.d.ts
31
- *.js
60
+ node_modules
61
+ .cdk.staging
62
+ **/**/cdk.out
63
+
64
+ .DS_Store
65
+
66
+ # Fjall config (contains organisation-specific settings)
67
+ fjall-config.json
68
+
69
+ # Fjall-managed state directories. Keep explicit so drift baselines
70
+ # (Phase 6) and codemod history (Phase 2) stay out of version control.
71
+ /.fjall/history/
72
+ /.fjall/baseline/
73
+ /.fjall/logs/
74
+
75
+ # Fjall per-target deploy state \u2014 a per-machine cache of last-deployed template
76
+ # hashes (cascade deploys write one file per account/region). Safe when absent:
77
+ # a missing file marks every stack changed, so the next deploy is a full deploy.
78
+ # Stays out of version control to avoid churn and merge conflicts between
79
+ # deployers. The *.tmp pair covers atomic-write temp files; the
80
+ # .deploy-state.json pair is the legacy name, kept while migration unlinks it.
32
81
  .fjall-state*.json
33
82
  .fjall-state*.json.tmp
34
83
  .deploy-state.json
35
84
  .deploy-state.json.tmp
36
- `,S=JSON.stringify({compilerOptions:{target:"ES2020",module:"commonjs",lib:["es2020","dom"],declaration:!0,strict:!0,noImplicitAny:!0,strictNullChecks:!0,noImplicitThis:!0,alwaysStrict:!0,noUnusedLocals:!1,noUnusedParameters:!1,noImplicitReturns:!0,noFallthroughCasesInSwitch:!1,inlineSourceMap:!0,inlineSources:!0,experimentalDecorators:!0,strictPropertyInitialization:!1,typeRoots:["./node_modules/@types"]},exclude:["node_modules","cdk.out"]},null,2)+`
37
- `,N=JSON.stringify({app:"npx ts-node --prefer-ts-exts --transpile-only infrastructure.ts",assetMetadata:!1,pathMetadata:!1,versionReporting:!1,watch:{include:["**"],exclude:["README.md","cdk*.json","**/*.d.ts","**/*.js","tsconfig.json","package*.json","yarn.lock","node_modules","test"]},context:{"@aws-cdk/aws-lambda:recognizeLayerVersion":!0,"@aws-cdk/core:checkSecretUsage":!0,"@aws-cdk/core:target-partitions":["aws","aws-cn"],"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver":!0,"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName":!0,"@aws-cdk/aws-ecs:arnFormatIncludesClusterName":!0,"@aws-cdk/aws-iam:minimizePolicies":!0,"@aws-cdk/core:validateSnapshotRemovalPolicy":!0,"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName":!0,"@aws-cdk/aws-s3:createDefaultLoggingPolicy":!0,"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption":!0,"@aws-cdk/aws-apigateway:disableCloudWatchRole":!0,"@aws-cdk/core:enablePartitionLiterals":!0,"@aws-cdk/aws-events:eventsTargetQueueSameAccount":!0,"@aws-cdk/aws-iam:standardizedServicePrincipals":!0,"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker":!0,"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName":!0,"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy":!0,"@aws-cdk/aws-route53-patters:useCertificate":!0,"@aws-cdk/customresources:installLatestAwsSdkDefault":!1,"@aws-cdk/aws-rds:databaseProxyUniqueResourceName":!0,"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup":!0,"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId":!0,"@aws-cdk/aws-ec2:launchTemplateDefaultUserData":!0,"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments":!0,"@aws-cdk/aws-redshift:columnId":!0,"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2":!0,"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup":!0,"@aws-cdk/aws-apigateway:requestValidatorUniqueId":!0,"@aws-cdk/aws-kms:aliasNameRef":!0,"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig":!0,"@aws-cdk/core:includePrefixInUniqueNameGeneration":!0,"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby":!0}},null,2)+`
38
- `;export{j as generateDomainFiles};
85
+
86
+ # Fjall backup files (sibling \`.bak\` from codemod mutations + domain eject)
87
+ **/backup/
88
+ *.bak
89
+ `,y=`{
90
+ "compilerOptions": {
91
+ "target": "ES2022",
92
+ "module": "NodeNext",
93
+ "moduleResolution": "NodeNext",
94
+ "lib": ["es2022"],
95
+ "declaration": true,
96
+ "strict": true,
97
+ "noImplicitAny": true,
98
+ "strictNullChecks": true,
99
+ "noImplicitThis": true,
100
+ "alwaysStrict": true,
101
+ "noUnusedLocals": false,
102
+ "noUnusedParameters": false,
103
+ "noImplicitReturns": true,
104
+ "noFallthroughCasesInSwitch": false,
105
+ "inlineSourceMap": true,
106
+ "inlineSources": true,
107
+ "experimentalDecorators": true,
108
+ "strictPropertyInitialization": false,
109
+ "skipLibCheck": true,
110
+ "types": ["node"]
111
+ },
112
+ "exclude": ["node_modules", "cdk.out"]
113
+ }
114
+ `,S=`{
115
+ "acknowledged-issue-numbers": [32775, 34892, 34635]
116
+ }
117
+ `,N=`{
118
+ "app": "npx tsx infrastructure.ts",
119
+ "assetMetadata": false,
120
+ "pathMetadata": false,
121
+ "versionReporting": false,
122
+ "watch": {
123
+ "include": ["**"],
124
+ "exclude": [
125
+ "README.md",
126
+ "cdk*.json",
127
+ "**/*.d.ts",
128
+ "**/*.js",
129
+ "tsconfig.json",
130
+ "package*.json",
131
+ "yarn.lock",
132
+ "node_modules",
133
+ "test"
134
+ ]
135
+ },
136
+ "context": {
137
+ "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
138
+ "@aws-cdk/core:checkSecretUsage": true,
139
+ "@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
140
+ "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
141
+ "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
142
+ "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
143
+ "@aws-cdk/aws-iam:minimizePolicies": true,
144
+ "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
145
+ "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
146
+ "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
147
+ "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
148
+ "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
149
+ "@aws-cdk/core:enablePartitionLiterals": true,
150
+ "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
151
+ "@aws-cdk/aws-iam:standardizedServicePrincipals": true,
152
+ "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
153
+ "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
154
+ "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
155
+ "@aws-cdk/aws-route53-patters:useCertificate": true,
156
+ "@aws-cdk/customresources:installLatestAwsSdkDefault": false,
157
+ "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
158
+ "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
159
+ "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
160
+ "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
161
+ "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
162
+ "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
163
+ "@aws-cdk/aws-redshift:columnId": true,
164
+ "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
165
+ "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
166
+ "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
167
+ "@aws-cdk/aws-kms:aliasNameRef": true,
168
+ "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
169
+ "@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
170
+ "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true
171
+ }
172
+ }
173
+ `;export{I as generateDomainFiles};
@@ -3,3 +3,4 @@ export * from "./domainRecords.js";
3
3
  export { parseZoneFile, resolveAlias } from "./bindParser.js";
4
4
  export { generateZoneFile } from "./bindWriter.js";
5
5
  export { type GeneratedFile, type DomainGenerationOptions, generateDomainFiles, } from "./domainFileGenerator.js";
6
+ export { type EmitDomainTsOptions, emitDomainTs } from "./tsEmitter.js";
@@ -1 +1 @@
1
- export*from"./types.js";export*from"./domainRecords.js";import{parseZoneFile as m,resolveAlias as p}from"./bindParser.js";import{generateZoneFile as f}from"./bindWriter.js";import{generateDomainFiles as l}from"./domainFileGenerator.js";export{l as generateDomainFiles,f as generateZoneFile,m as parseZoneFile,p as resolveAlias};
1
+ export*from"./types.js";export*from"./domainRecords.js";import{parseZoneFile as t,resolveAlias as i}from"./bindParser.js";import{generateZoneFile as a}from"./bindWriter.js";import{generateDomainFiles as n}from"./domainFileGenerator.js";import{emitDomainTs as l}from"./tsEmitter.js";export{l as emitDomainTs,n as generateDomainFiles,a as generateZoneFile,t as parseZoneFile,i as resolveAlias};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Typed-construct emitter for domain `infrastructure.ts` files — the SSOT
3
+ * both the CLI import/create flows and the webapp record engine render
4
+ * through (domains completion programme, train B0). Pure string-in/string-out:
5
+ * no I/O, no CLI coupling.
6
+ */
7
+ import type { ParsedDomainRecords } from "./domainRecords.js";
8
+ export interface EmitDomainTsOptions {
9
+ /**
10
+ * Domain component name the emitted file is ADDRESSED by (D2 contract:
11
+ * the App/getStack literals must equal `getDomainStackName(componentName)`
12
+ * because deploy state and binding resolution derive the stack name from
13
+ * the component directory name). The delegated scaffold needs this: its
14
+ * component is named by the CHILD fqdn while `parsed.zoneName` is the
15
+ * PARENT zone. Default preserves the import flow's identity
16
+ * (componentName === parsed.zoneName).
17
+ */
18
+ readonly componentName?: string;
19
+ }
20
+ export declare function emitDomainTs(parsed: ParsedDomainRecords, emitOptions?: EmitDomainTsOptions): string;
@@ -0,0 +1,46 @@
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"],C=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 J(e,n){const t=Array.isArray(e)?e.join(`
2
+ `):e,a=Array.isArray(n)?n.join(`
3
+ `):n;return t.localeCompare(a)}o(J,"compareValue");function p(e){const n=e.kind==="standard"?0:1,t=C.get(e.type)??99;return[n,t,e.name]}o(p,"recordSortKey");function R(e){return[...e].sort((n,t)=>{const[a,c,m]=p(n),[s,d,f]=p(t);if(a!==s)return a-s;if(c!==d)return c-d;const u=b(m,f);return u!==0?u:n.kind==="standard"&&t.kind==="standard"?J(n.value,t.value):0})}o(R,"sortRecords");function P(e){return Array.isArray(e)?`[${e.map(t=>JSON.stringify(t)).join(", ")}]`:JSON.stringify(e)}o(P,"formatValue");function v(e){const n=[`type: ${JSON.stringify(e.type)}`,`name: ${JSON.stringify(e.name)}`,`value: ${P(e.value)}`];return e.ttl!==void 0&&n.push(`ttl: ${e.ttl}`),` { ${n.join(", ")} },`}o(v,"emitStandardRecord");function I(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(I,"emitAliasTarget");function T(e){return` { ${[`type: ${JSON.stringify(e.type)}`,`name: ${JSON.stringify(e.name)}`,`target: ${I(e.target)}`].join(", ")} },`}o(T,"emitAliasRecord");function w(e){return e.kind==="standard"?v(e):T(e)}o(w,"emitRecord");function x(e){const n=[`domainName: ${JSON.stringify(e.domainName)}`];if(e.subjectAlternativeNames&&e.subjectAlternativeNames.length>0){const t=e.subjectAlternativeNames.map(a=>JSON.stringify(a)).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(x,"emitCertificate");function z(e,n){if(n.length===0)return"";const t=["","// Delegations (D8 \u2014 child writes NS; no parent-side records here):"];for(const a of n)t.push(`// ${a.subdomain}.${e} \u2192 deploy a Domain { registrar: "external-delegated",`,`// zoneName: ${JSON.stringify(e)}, delegatedSubdomain: ${JSON.stringify(a.subdomain)} }`,`// in account ${JSON.stringify(a.toAccount)}; the CLI injects parentDelegationRoleArn`,"// (ManagedDomainBinding.delegationRoleArn) and the child UPSERTs its NS into this zone.");return t.join(`
4
+ `)+`
5
+ `}o(z,"emitDelegationGuidance");function B(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(B,"computeUsedHelpers");function F(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(a=>` ${a},`).join(`
7
+ `)}
8
+ } from "@fjall/components-infrastructure";`}o(F,"emitImports");function L(e){return D(e.split(".").join(""))}o(L,"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 E(e){return e.registrar==="external-delegated"&&e.delegatedSubdomain?`${e.delegatedSubdomain}.${e.zoneName}`:e.zoneName}o(E,"effectiveZoneName");function y(e,n,t){if(n.length===0)return` ${e}: [],`;const a=n.map(t).join(`
9
+ `);return` ${e}: [
10
+ ${a}
11
+ ],`}o(y,"emitBlock");function M(e,n={}){const t=k(n.componentName??e.zoneName),a=L(e.zoneName),c=B(e.records),m=F(c),s=E(e),d=e.records.map(i=>i.kind==="standard"?{...i,name:g(i.name,s)}:{...i,name:g(i.name,s)}),f=R(d),u=[...e.certificates].sort((i,l)=>i.domainName.localeCompare(l.domainName)),h=[...e.delegations].sort((i,l)=>i.subdomain.localeCompare(l.subdomain)),r=[];if(e.hostedZoneId&&r.push(` hostedZoneId: ${JSON.stringify(e.hostedZoneId)},`),e.adoptedNameServers&&e.adoptedNameServers.length>0){const i=e.adoptedNameServers.map(l=>JSON.stringify(l)).join(", ");r.push(` adoptedNameServers: [${i}],`)}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,x),S=y("records",f,w),$=e.registrar==="external-records"?"":z(e.zoneName,h),j=e.registrar==="external-delegated"?`
12
+ // Injected by the Fjall CLI at deploy time (D8) \u2014 do not set these by hand.
13
+ const domainDeployPhase: unknown = app.node.tryGetContext(
14
+ "fjall:domainDeployPhase"
15
+ );
16
+ if (
17
+ domainDeployPhase !== undefined &&
18
+ domainDeployPhase !== "zone" &&
19
+ domainDeployPhase !== "full"
20
+ ) {
21
+ throw new Error(
22
+ \`Domain deploy: CDK context 'fjall:domainDeployPhase' must be "zone" or "full" (got \${JSON.stringify(domainDeployPhase)}) \u2014 re-run the deploy through the Fjall CLI, or correct the hand-set context entry.\`
23
+ );
24
+ }
25
+ const parentDelegationRoleArn: unknown = app.node.tryGetContext(
26
+ "fjall:parentDelegationRoleArn"
27
+ );
28
+ `:"";return`${m}
29
+
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
+
32
+ const app = App.getApp(${JSON.stringify(t)});
33
+ // The stack name is Fjall's domain deploy contract (getDomainStackName) \u2014
34
+ // the CLI records and resolves the deployed domain by this exact
35
+ // CloudFormation stack name. Do not rename it.
36
+ const stack = app.getStack(${JSON.stringify(t)}).getStack();
37
+ ${j}
38
+ new Domain(stack, ${JSON.stringify(a)}, {
39
+ registrar: ${JSON.stringify(e.registrar)},
40
+ zoneName: ${JSON.stringify(e.zoneName)},
41
+ ${r.length>0?r.join(`
42
+ `)+`
43
+ `:""}${N}
44
+ ${S}
45
+ });
46
+ ${$}`}o(M,"emitDomainTs");export{M as emitDomainTs};
@@ -1 +1 @@
1
- export declare const GENERATOR_VERSION = "12.1.1";
1
+ export declare const GENERATOR_VERSION = "12.3.0";
@@ -1 +1 @@
1
- const E="12.1.1";export{E as GENERATOR_VERSION};
1
+ const E="12.3.0";export{E as GENERATOR_VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/generator",
3
- "version": "12.1.1",
3
+ "version": "12.3.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fjall-tech/fjall.git",
@@ -23,6 +23,10 @@
23
23
  "types": "./dist/src/detection/index.d.ts",
24
24
  "default": "./dist/src/detection/index.js"
25
25
  },
26
+ "./dns": {
27
+ "types": "./dist/src/dns/index.d.ts",
28
+ "default": "./dist/src/dns/index.js"
29
+ },
26
30
  "./schemas": {
27
31
  "types": "./dist/src/schemas/index.d.ts",
28
32
  "default": "./dist/src/schemas/index.js"
@@ -53,7 +57,7 @@
53
57
  },
54
58
  "license": "SEE LICENSE IN LICENSE",
55
59
  "dependencies": {
56
- "@fjall/util": "^12.1.1",
60
+ "@fjall/util": "^12.3.0",
57
61
  "ast-types": "^0.16.1",
58
62
  "recast": "^0.23.12",
59
63
  "ts-morph": "^28.0.0",