@fjall/generator 14.1.0 → 14.2.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.
Files changed (72) hide show
  1. package/dist/.build-source-hash +42 -37
  2. package/dist/.minified +1 -1
  3. package/dist/src/ast/astTestHelpers.d.ts +2 -0
  4. package/dist/src/ast/domain/astDomainParser.d.ts +12 -0
  5. package/dist/src/ast/domain/astDomainParser.js +1 -1
  6. package/dist/src/ast/index.d.ts +1 -1
  7. package/dist/src/ast/index.js +1 -1
  8. package/dist/src/ast/parsers/resources/astCdnParser.js +1 -1
  9. package/dist/src/ast/parsers/resources/astComputeParser.js +1 -1
  10. package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +8 -0
  11. package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -1
  12. package/dist/src/codemod/edits/addResource/siblingEmission.d.ts +61 -0
  13. package/dist/src/codemod/edits/addResource/siblingEmission.js +1 -0
  14. package/dist/src/codemod/edits/addResource.js +1 -1
  15. package/dist/src/codemod/edits/connectResourceToCompute.js +1 -1
  16. package/dist/src/codemod/edits/ensureImports.d.ts +18 -0
  17. package/dist/src/codemod/edits/ensureImports.js +1 -1
  18. package/dist/src/codemod/edits/modifyResource.js +1 -1
  19. package/dist/src/codemod/edits/resourceStatementLocator.d.ts +3 -0
  20. package/dist/src/codemod/edits/resourceStatementLocator.js +1 -1
  21. package/dist/src/codemod/edits/siblingBindingResolution.d.ts +54 -1
  22. package/dist/src/codemod/edits/siblingBindingResolution.js +1 -1
  23. package/dist/src/codemod/emitGuard.d.ts +2 -30
  24. package/dist/src/codemod/emitGuard.js +1 -1
  25. package/dist/src/codemod/emitProjection.d.ts +31 -2
  26. package/dist/src/codemod/emitProjection.js +1 -1
  27. package/dist/src/codemod/fileRewriter/builders.d.ts +18 -0
  28. package/dist/src/codemod/fileRewriter/builders.js +1 -1
  29. package/dist/src/codemod/fileRewriter/index.d.ts +1 -1
  30. package/dist/src/codemod/fileRewriter/index.js +1 -1
  31. package/dist/src/codemod/index.d.ts +1 -0
  32. package/dist/src/codemod/index.js +1 -1
  33. package/dist/src/codemod/registry.d.ts +26 -27
  34. package/dist/src/codemod/registry.js +1 -1
  35. package/dist/src/codemod/validationGate/gates/projection.js +1 -1
  36. package/dist/src/generation/common.js +8 -8
  37. package/dist/src/generation/connectionWiring.d.ts +83 -0
  38. package/dist/src/generation/connectionWiring.js +1 -0
  39. package/dist/src/generation/database.d.ts +3 -34
  40. package/dist/src/generation/database.js +20 -20
  41. package/dist/src/generation/index.d.ts +1 -0
  42. package/dist/src/generation/index.js +1 -1
  43. package/dist/src/generation/infrastructure.d.ts +11 -0
  44. package/dist/src/generation/infrastructure.js +38 -28
  45. package/dist/src/generation/messagingConnections.d.ts +1 -4
  46. package/dist/src/generation/messagingConnections.js +1 -1
  47. package/dist/src/generation/storageConnections.d.ts +1 -12
  48. package/dist/src/generation/storageConnections.js +1 -1
  49. package/dist/src/planning/resourceAddition.d.ts +3 -0
  50. package/dist/src/planning/resourceAddition.js +1 -1
  51. package/dist/src/projection/compute.d.ts +31 -0
  52. package/dist/src/projection/compute.js +1 -0
  53. package/dist/src/projection/index.d.ts +3 -2
  54. package/dist/src/projection/index.js +1 -1
  55. package/dist/src/projection/project.d.ts +16 -1
  56. package/dist/src/projection/project.js +1 -1
  57. package/dist/src/projection/roundTripKeys.d.ts +12 -0
  58. package/dist/src/projection/roundTripKeys.js +1 -0
  59. package/dist/src/projection/tables.d.ts +13 -9
  60. package/dist/src/projection/tables.js +1 -1
  61. package/dist/src/projection/types.d.ts +204 -4
  62. package/dist/src/projection/unresolved.d.ts +17 -0
  63. package/dist/src/projection/unresolved.js +1 -0
  64. package/dist/src/schemas/applicationSchemas.d.ts +2 -0
  65. package/dist/src/schemas/cdnSchemas.d.ts +4 -0
  66. package/dist/src/schemas/cdnSchemas.js +1 -1
  67. package/dist/src/schemas/computeSchemas.js +1 -1
  68. package/dist/src/validation/validationMessages.d.ts +1 -0
  69. package/dist/src/validation/validationMessages.js +1 -1
  70. package/dist/src/version.d.ts +1 -1
  71. package/dist/src/version.js +1 -1
  72. package/package.json +2 -2
@@ -1,8 +1,8 @@
1
- var m=Object.defineProperty;var n=(e,r)=>m(e,"name",{value:r,configurable:!0});import{toPascalCase as T,toKebab as V,toValidDatabaseName as C}from"@fjall/util";function c(e){return JSON.stringify(e)}n(c,"escapeStringLiteral");function _(e){return e.map(c).join(", ")}n(_,"formatStringArray");const l="import:SharedAlarmTopicArn";function $(e=" "){return`
2
- ${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(l)} } : {}),`}n($,"emitProductionAlertsTopicSpread");function y(e){return e===0?"":`_${String(e+1)}`}n(y,"connectionEnvSuffix");function x(e,r){if(e===r)return 1;if(!e.startsWith(`${r}_`))return;const t=e.slice(r.length+1);return/^\d+$/.test(t)?parseInt(t,10):void 0}n(x,"connectionKeyOrdinal");function b(e){if(typeof e!="object"||e===null)return!1;const r=e;return typeof r.__identifier=="string"||typeof r.__expression=="string"||typeof r.__call=="string"}n(b,"isSpecialValue");function u(e){return e.replace(/[^a-zA-Z0-9]/g," ").split(" ").map((r,t)=>t===0?r.charAt(0).toLowerCase()+r.slice(1):r.charAt(0).toUpperCase()+r.slice(1)).join("")}n(u,"toVariableName");function j(e){return e.variableName??u(e.name)}n(j,"getVariableName");function S(e,r){for(const t of e.database)if(t.name===r&&t.variableName)return t.variableName;for(const t of e.s3)if(t.name===r&&t.variableName)return t.variableName;for(const t of e.compute)if(t.name===r&&t.variableName)return t.variableName;for(const t of e.dynamodb??[])if(t.name===r&&t.variableName)return t.variableName;for(const t of e.sqs??[])if(t.name===r&&t.variableName)return t.variableName;return u(r)}n(S,"resolveResourceVariable");function d(e){const r=Object.entries(e);return r.length===0?!0:r.length>1?!1:r.every(([,t])=>typeof t=="string"||typeof t=="number"||typeof t=="boolean"||t===null)}n(d,"isSimpleObject");function a(e,r=" "){if(e==null)return"undefined";if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(b(e)){if("__identifier"in e)return e.__identifier;if("__expression"in e)return e.__expression;if("__call"in e)return e.__call}if(Array.isArray(e))return`[${e.map(t=>a(t,r)).join(", ")}]`;if(typeof e=="object"){const t=Object.entries(e).filter(([,f])=>f!==void 0);if(d(e)){const f=t.map(([s,p])=>`${s}: ${a(p,r)}`).join(", ");return f?`{ ${f} }`:"{}"}const o=r+" ",i=t.map(([f,s])=>`${o}${f}: ${a(s,o)}`).join(`,
3
- `);return i?`{
4
- ${i}
5
- ${r}}`:"{}"}return JSON.stringify(e)}n(a,"formatValue");function N(e,r=" "){return e.map(t=>{const o=t.value.kind==="expression"?t.value.source:a(t.value.value,r);return`
6
- ${r}${t.key}: ${o}`}).join(",")}n(N,"emitProjectedProps");function O(e,r,t,o="raw"){if(!e)return"";let i;switch(o){case"string":i=c(String(t));break;case"object":i=a(t);break;case"boolean-or-object":i=t===!1?"false":a(t);break;default:i=String(t)}return`
7
- ${r}: ${i},`}n(O,"buildProperty");function A(e,r=" "){return e?.length?e.map(t=>`
8
- ${r}${t.key}: ${t.sourceText},`).join(""):""}n(A,"emitExtraProperties");export{l as PRODUCTION_ALERTS_TOPIC_IMPORT,O as buildProperty,y as connectionEnvSuffix,x as connectionKeyOrdinal,A as emitExtraProperties,$ as emitProductionAlertsTopicSpread,N as emitProjectedProps,c as escapeStringLiteral,_ as formatStringArray,a as formatValue,j as getVariableName,b as isSpecialValue,S as resolveResourceVariable,V as toKebab,T as toPascalCase,C as toValidDatabaseName,u as toVariableName};
1
+ var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,configurable:!0});import{toPascalCase as T,toKebab as V,toValidDatabaseName as C}from"@fjall/util";function c(e){return JSON.stringify(e)}n(c,"escapeStringLiteral");function g(e){return e.map(c).join(", ")}n(g,"formatStringArray");const d="import:SharedAlarmTopicArn";function _(e=" "){return`
2
+ ${e}...(getConfig().environment === "production" ? { alertsTopic: ${c(d)} } : {}),`}n(_,"emitProductionAlertsTopicSpread");function $(e){return e===0?"":`_${String(e+1)}`}n($,"connectionEnvSuffix");function x(e,t){if(e===t)return 1;if(!e.startsWith(`${t}_`))return;const r=e.slice(t.length+1);return/^\d+$/.test(r)?parseInt(r,10):void 0}n(x,"connectionKeyOrdinal");function l(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.__identifier=="string"||typeof t.__expression=="string"||typeof t.__call=="string"}n(l,"isSpecialValue");function u(e){return e.replace(/[^a-zA-Z0-9]/g," ").split(" ").map((t,r)=>r===0?t.charAt(0).toLowerCase()+t.slice(1):t.charAt(0).toUpperCase()+t.slice(1)).join("")}n(u,"toVariableName");function j(e){return e.variableName??u(e.name)}n(j,"getVariableName");function S(e,t){for(const r of e.database)if(r.name===t&&r.variableName)return r.variableName;for(const r of e.s3)if(r.name===t&&r.variableName)return r.variableName;for(const r of e.compute)if(r.name===t&&r.variableName)return r.variableName;for(const r of e.dynamodb??[])if(r.name===t&&r.variableName)return r.variableName;for(const r of e.sqs??[])if(r.name===t&&r.variableName)return r.variableName;return u(t)}n(S,"resolveResourceVariable");function b(e){const t=Object.entries(e);return t.length===0?!0:t.length>1?!1:t.every(([,r])=>typeof r=="string"||typeof r=="number"||typeof r=="boolean"||r===null)}n(b,"isSimpleObject");function f(e,t=" "){if(e==null)return"undefined";if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(l(e)){if("__identifier"in e)return e.__identifier;if("__expression"in e)return e.__expression;if("__call"in e)return e.__call}if(Array.isArray(e))return`[${e.map(r=>f(r,t)).join(", ")}]`;if(typeof e=="object"){const r=Object.entries(e).filter(([,a])=>a!==void 0);if(b(e)){const a=r.map(([s,m])=>`${s}: ${f(m,t)}`).join(", ");return a?`{ ${a} }`:"{}"}const i=t+" ",o=r.map(([a,s])=>`${i}${a}: ${f(s,i)}`).join(`,
3
+ `);return o?`{
4
+ ${o}
5
+ ${t}}`:"{}"}return JSON.stringify(e)}n(f,"formatValue");function h(e,t=" "){return e.map(i=>{const o=r(i);return`
6
+ ${t}${i.key}: ${o}`}).join(",");function r(i){switch(i.value.kind){case"expression":return i.value.source;case"structured":throw new Error(`emitProjectedProps cannot render the structured value for "${i.key}" \u2014 structured expressions are emitted by the codemod's AST serialiser only.`);case"literal":return f(i.value.value,t)}}}n(h,"emitProjectedProps");function N(e,t,r,i="raw"){if(!e)return"";let o;switch(i){case"string":o=c(String(r));break;case"object":o=f(r);break;case"boolean-or-object":o=r===!1?"false":f(r);break;default:o=String(r)}return`
7
+ ${t}: ${o},`}n(N,"buildProperty");function A(e,t=" "){return e?.length?e.map(r=>`
8
+ ${t}${r.key}: ${r.sourceText},`).join(""):""}n(A,"emitExtraProperties");export{d as PRODUCTION_ALERTS_TOPIC_IMPORT,N as buildProperty,$ as connectionEnvSuffix,x as connectionKeyOrdinal,A as emitExtraProperties,_ as emitProductionAlertsTopicSpread,h as emitProjectedProps,c as escapeStringLiteral,g as formatStringArray,f as formatValue,j as getVariableName,l as isSpecialValue,S as resolveResourceVariable,V as toKebab,T as toPascalCase,C as toValidDatabaseName,u as toVariableName};
@@ -0,0 +1,83 @@
1
+ export declare const DATABASE_ENV_VARS: Readonly<{
2
+ readonly HOST: "DATABASE_HOST";
3
+ readonly PORT: "DATABASE_PORT";
4
+ readonly NAME: "DATABASE_NAME";
5
+ readonly SSL: "DATABASE_SSL";
6
+ readonly USERNAME: "DATABASE_USERNAME";
7
+ readonly PASSWORD: "DATABASE_PASSWORD";
8
+ }>;
9
+ export declare const CREDENTIAL_KEYS: Readonly<{
10
+ readonly USERNAME: "username";
11
+ readonly PASSWORD: "password";
12
+ }>;
13
+ /** The literal value emitted for `DATABASE_SSL`. */
14
+ export declare const DATABASE_SSL_VALUE = "true";
15
+ /**
16
+ * Construct accessor methods the emitted connection wiring calls on a bound
17
+ * database variable.
18
+ */
19
+ export declare const DATABASE_ACCESSORS: Readonly<{
20
+ readonly HOST: "getHostEndpoint";
21
+ readonly PORT: "getHostPort";
22
+ readonly NAME: "getDatabaseName";
23
+ readonly CREDENTIALS: "getCredentials";
24
+ readonly IMPORT: "getImport";
25
+ }>;
26
+ export declare const STORAGE_ENV_VARS: Readonly<{
27
+ readonly NAME: "BUCKET_NAME";
28
+ }>;
29
+ /**
30
+ * Construct accessor methods the emitted connection wiring calls on a bound
31
+ * bucket variable.
32
+ */
33
+ export declare const STORAGE_ACCESSORS: Readonly<{
34
+ readonly BUCKET_NAME: "getBucketName";
35
+ }>;
36
+ export declare const MESSAGING_ENV_VARS: Readonly<{
37
+ readonly URL: "QUEUE_URL";
38
+ readonly ARN: "QUEUE_ARN";
39
+ }>;
40
+ /**
41
+ * Construct accessor methods the emitted connection wiring calls on a bound
42
+ * queue variable.
43
+ */
44
+ export declare const MESSAGING_ACCESSORS: Readonly<{
45
+ readonly URL: "getQueueUrl";
46
+ readonly ARN: "getQueueArn";
47
+ }>;
48
+ /**
49
+ * Emission order for `connections: [...]` — databases, then storage, then
50
+ * messaging. `formatAllConnectionsCode` and the connect edit's insertion
51
+ * ranks both derive from this tuple so a surgical insert never reorders what
52
+ * a later full regeneration would emit.
53
+ */
54
+ export declare const CONNECTION_TYPE_ORDER: readonly ["database", "storage", "messaging"];
55
+ export type ConnectionResourceType = (typeof CONNECTION_TYPE_ORDER)[number];
56
+ /** How a wiring entry's value is produced from the bound resource variable. */
57
+ export type ConnectionWiringValue = {
58
+ kind: "accessor";
59
+ method: string;
60
+ } | {
61
+ kind: "credential";
62
+ credentialKey: string;
63
+ } | {
64
+ kind: "literal";
65
+ value: string;
66
+ };
67
+ export interface ConnectionWiringEntry {
68
+ key: string;
69
+ target: "environment" | "secretsImport";
70
+ value: ConnectionWiringValue;
71
+ }
72
+ /**
73
+ * The wiring entries a single connection of `resourceType` contributes, in
74
+ * canonical emission order. `suffix` is the `_N` scheme value for this
75
+ * connection's ordinal (`connectionEnvSuffix`).
76
+ */
77
+ export declare function buildConnectionWiringEntries(resourceType: ConnectionResourceType, suffix: string): ConnectionWiringEntry[];
78
+ /**
79
+ * Render a wiring value as generated source for the scaffold lane. The
80
+ * connect edit builds the equivalent AST nodes from the same
81
+ * {@link ConnectionWiringValue} shapes.
82
+ */
83
+ export declare function renderWiringValueSource(value: ConnectionWiringValue, variableName: string): string;
@@ -0,0 +1 @@
1
+ var N=Object.defineProperty;var r=(t,e)=>N(t,"name",{value:e,configurable:!0});import{escapeStringLiteral as o}from"./common.js";const E=Object.freeze({HOST:"DATABASE_HOST",PORT:"DATABASE_PORT",NAME:"DATABASE_NAME",SSL:"DATABASE_SSL",USERNAME:"DATABASE_USERNAME",PASSWORD:"DATABASE_PASSWORD"}),c=Object.freeze({USERNAME:"username",PASSWORD:"password"}),O="true",n=Object.freeze({HOST:"getHostEndpoint",PORT:"getHostPort",NAME:"getDatabaseName",CREDENTIALS:"getCredentials",IMPORT:"getImport"}),T=Object.freeze({NAME:"BUCKET_NAME"}),_=Object.freeze({BUCKET_NAME:"getBucketName"}),R=Object.freeze({URL:"QUEUE_URL",ARN:"QUEUE_ARN"}),s=Object.freeze({URL:"getQueueUrl",ARN:"getQueueArn"}),g=["database","storage","messaging"],A=r((t,e)=>({key:t,target:"environment",value:e}),"environmentEntry"),a=r((t,e)=>({key:t,target:"secretsImport",value:{kind:"credential",credentialKey:e}}),"secretEntry"),S=r(t=>({kind:"accessor",method:t}),"accessor");function D(t,e){switch(t){case"database":return[A(`${E.HOST}${e}`,S(n.HOST)),A(`${E.PORT}${e}`,S(n.PORT)),A(`${E.NAME}${e}`,S(n.NAME)),A(`${E.SSL}${e}`,{kind:"literal",value:O}),a(`${E.USERNAME}${e}`,c.USERNAME),a(`${E.PASSWORD}${e}`,c.PASSWORD)];case"storage":return[A(`${T.NAME}${e}`,S(_.BUCKET_NAME))];case"messaging":return[A(`${R.URL}${e}`,S(s.URL)),A(`${R.ARN}${e}`,S(s.ARN))]}}r(D,"buildConnectionWiringEntries");function M(t,e){switch(t.kind){case"accessor":return`${e}.${t.method}()`;case"credential":return`${e}.${n.CREDENTIALS}().${n.IMPORT}(${o(t.credentialKey)})`;case"literal":return o(t.value)}}r(M,"renderWiringValueSource");export{g as CONNECTION_TYPE_ORDER,c as CREDENTIAL_KEYS,n as DATABASE_ACCESSORS,E as DATABASE_ENV_VARS,O as DATABASE_SSL_VALUE,s as MESSAGING_ACCESSORS,R as MESSAGING_ENV_VARS,_ as STORAGE_ACCESSORS,T as STORAGE_ENV_VARS,D as buildConnectionWiringEntries,M as renderWiringValueSource};
@@ -5,38 +5,7 @@
5
5
  * RDS Instance, Aurora, and GlobalAurora configurations.
6
6
  */
7
7
  import type { DatabaseResourcePlan, ApplicationResourcePlan, ComputeResourcePlan } from "../schemas/resourceSchemas.js";
8
- export declare const DATABASE_ENV_VARS: Readonly<{
9
- readonly HOST: "DATABASE_HOST";
10
- readonly PORT: "DATABASE_PORT";
11
- readonly NAME: "DATABASE_NAME";
12
- readonly SSL: "DATABASE_SSL";
13
- readonly USERNAME: "DATABASE_USERNAME";
14
- readonly PASSWORD: "DATABASE_PASSWORD";
15
- }>;
16
- export declare const CREDENTIAL_KEYS: Readonly<{
17
- readonly USERNAME: "username";
18
- readonly PASSWORD: "password";
19
- }>;
20
- /**
21
- * The literal value emitted for `DATABASE_SSL`. Shared with the codemod
22
- * connection edit (`codemod/edits/connectResourceToCompute.ts`) — the two
23
- * emitters must write the same byte or surgically-wired apps diverge from
24
- * regenerated ones.
25
- */
26
- export declare const DATABASE_SSL_VALUE = "true";
27
- /**
28
- * Construct accessor methods the emitted connection wiring calls on a bound
29
- * database variable. Shared with the codemod connection edit
30
- * (`codemod/edits/connectResourceToCompute.ts`) — the two emitters must call
31
- * identical methods or surgically-wired apps fail at synth.
32
- */
33
- export declare const DATABASE_ACCESSORS: Readonly<{
34
- readonly HOST: "getHostEndpoint";
35
- readonly PORT: "getHostPort";
36
- readonly NAME: "getDatabaseName";
37
- readonly CREDENTIALS: "getCredentials";
38
- readonly IMPORT: "getImport";
39
- }>;
8
+ export { CREDENTIAL_KEYS, DATABASE_ACCESSORS, DATABASE_ENV_VARS, DATABASE_SSL_VALUE, } from "./connectionWiring.js";
40
9
  export type DatabaseEnvVarEntry = {
41
10
  key: string;
42
11
  expression: string;
@@ -51,8 +20,8 @@ export interface DatabaseEnvVars {
51
20
  */
52
21
  export declare function getConnectedDatabases(plan: ApplicationResourcePlan, compute: ComputeResourcePlan): DatabaseResourcePlan[];
53
22
  /**
54
- * Generate database environment variable entries for a list of connected databases.
55
- * Both ECS and Lambda use containerSecretsImport with getImport() for credentials.
23
+ * Generate database environment variable entries for a list of connected
24
+ * databases from the shared wiring vocabulary (`connectionWiring.ts`).
56
25
  * Credential entries are always marked as secrets (isSecret: true).
57
26
  */
58
27
  export declare function generateDatabaseEnvVarEntries(connectedDatabases: DatabaseResourcePlan[]): DatabaseEnvVarEntry[];
@@ -1,26 +1,26 @@
1
- var $=Object.defineProperty;var c=(e,n)=>$(e,"name",{value:n,configurable:!0});import{buildProperty as o,connectionEnvSuffix as y,formatValue as S,getVariableName as p,emitExtraProperties as b,escapeStringLiteral as a,formatStringArray as R,emitProductionAlertsTopicSpread as m}from"./common.js";const l=Object.freeze({HOST:"DATABASE_HOST",PORT:"DATABASE_PORT",NAME:"DATABASE_NAME",SSL:"DATABASE_SSL",USERNAME:"DATABASE_USERNAME",PASSWORD:"DATABASE_PASSWORD"}),A=Object.freeze({USERNAME:"username",PASSWORD:"password"}),g="true",u=Object.freeze({HOST:"getHostEndpoint",PORT:"getHostPort",NAME:"getDatabaseName",CREDENTIALS:"getCredentials",IMPORT:"getImport"});function D(e,n){const r=n.connectedDatabase;return r?.length?e.database.filter(t=>r.includes(t.name)):[]}c(D,"getConnectedDatabases");function E(e,n){return`${e}.${u.CREDENTIALS}().${u.IMPORT}(${a(n)})`}c(E,"getCredentialExpression");function T(e){const n=[],r=c((t,d,s)=>{n.push({key:t,expression:d,isSecret:s})},"addEntry");if(e.length===1){const t=p(e[0]);r(l.HOST,`${t}.${u.HOST}()`,!1),r(l.PORT,`${t}.${u.PORT}()`,!1),r(l.NAME,`${t}.${u.NAME}()`,!1),r(l.SSL,a(g),!1),r(l.USERNAME,E(t,A.USERNAME),!0),r(l.PASSWORD,E(t,A.PASSWORD),!0)}else for(const[t,d]of e.entries()){const s=p(d),i=y(t);r(`${l.HOST}${i}`,`${s}.${u.HOST}()`,!1),r(`${l.PORT}${i}`,`${s}.${u.PORT}()`,!1),r(`${l.NAME}${i}`,`${s}.${u.NAME}()`,!1),r(`${l.SSL}${i}`,a(g),!1),r(`${l.USERNAME}${i}`,E(s,A.USERNAME),!0),r(`${l.PASSWORD}${i}`,E(s,A.PASSWORD),!0)}return n}c(T,"generateDatabaseEnvVarEntries");function j(e){return`connections: [${e.map(r=>p(r)).join(", ")}],`}c(j,"formatConnectionsCode");function h(e){return e.expression===a(g)?g:{__expression:e.expression}}c(h,"toDatabaseEnvVarValue");function _(e,n){const r={},t={};if(!n.needsConnection||!n.connectedDatabase?.length)return{env:r,secrets:t};const d=D(e,n),s=T(d);for(const i of s){const f=h(i);i.isSecret?t[i.key]={__expression:i.expression}:r[i.key]=f}return{env:r,secrets:t}}c(_,"buildDatabaseEnvVars");function x(e){let n="";return n+=o(e.port!==void 0,"port",e.port),n+=o(e.deletionProtection!==void 0,"deletionProtection",e.deletionProtection),n+=o(e.snapshotIdentifier!==void 0,"snapshotIdentifier",e.snapshotIdentifier,"string"),n+=o(e.snapshotUsername!==void 0,"snapshotUsername",e.snapshotUsername,"string"),n+=o(e.monitoringInterval!==void 0,"monitoringInterval",e.monitoringInterval),n}c(x,"generateDatabaseSharedProps");function N(e){if(e.type!=="Instance")return"";let n="";return n+=o(e.instanceType!==void 0,"instanceType",e.instanceType,"string"),n+=o(e.allocatedStorage!==void 0,"allocatedStorage",e.allocatedStorage),n+=o(e.multiAz!==void 0,"multiAz",e.multiAz),n+=o(e.publiclyAccessible!==void 0,"publiclyAccessible",e.publiclyAccessible),n+=o(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=o(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=o(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=o(e.readReplica!==void 0,"readReplica",e.readReplica,"boolean-or-object"),n+=o(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=o(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n}c(N,"generateDatabaseInstanceProps");function P(e){if(e.type!=="Aurora"&&e.type!=="GlobalAurora")return"";let n="";return n+=o(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=o(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=o(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=o(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=o(e.writer!==void 0,"writer",e.writer,"object"),n+=o(e.readers!==void 0,"readers",e.readers,"boolean-or-object"),n+=o(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n+=o(e.preferredMaintenanceWindow!==void 0,"preferredMaintenanceWindow",e.preferredMaintenanceWindow,"string"),n}c(P,"generateDatabaseAuroraProps");function O(e){if(e.type!=="GlobalAurora")return"";let n="";return n+=o(e.primaryRegion!==void 0,"primaryRegion",e.primaryRegion,"string"),e.secondaryRegions!==void 0&&e.secondaryRegions.length>0&&(n+=`
2
- secondaryRegions: [${R(e.secondaryRegions)}],`),n+=o(e.globalClusterIdentifier!==void 0,"globalClusterIdentifier",e.globalClusterIdentifier,"string"),n+=o(e.enableGlobalWriteForwarding!==void 0,"enableGlobalWriteForwarding",e.enableGlobalWriteForwarding),n}c(O,"generateDatabaseGlobalAuroraProps");function I(e,n){return n.compute.some(r=>r.needsConnection&&r.connectedDatabase?.includes(e.name))}c(I,"databaseNeedsVariable");function w(e){if(e.database.length===0)return"";let n="";for(let r=0;r<e.database.length;r++){const t=e.database[r],d=p(t),s=I(t,e),i=r>0,f=s?`const ${d} = `:"";n+=`${i?`
3
- `:""}${f}app.addDatabase(
4
- DatabaseFactory.build(${a(t.name)}, {
1
+ var y=Object.defineProperty;var o=(e,n)=>y(e,"name",{value:n,configurable:!0});import{buildProperty as r,connectionEnvSuffix as b,formatValue as u,getVariableName as p,emitExtraProperties as f,escapeStringLiteral as s,formatStringArray as m,emitProductionAlertsTopicSpread as h}from"./common.js";import{DATABASE_SSL_VALUE as g,buildConnectionWiringEntries as x,renderWiringValueSource as A}from"./connectionWiring.js";import{CREDENTIAL_KEYS as F,DATABASE_ACCESSORS as U,DATABASE_ENV_VARS as B,DATABASE_SSL_VALUE as z}from"./connectionWiring.js";function S(e,n){const t=n.connectedDatabase;return t?.length?e.database.filter(i=>t.includes(i.name)):[]}o(S,"getConnectedDatabases");function D(e){const n=[];for(const[t,i]of e.entries()){const l=p(i),a=b(t);for(const c of x("database",a))n.push({key:c.key,expression:A(c.value,l),isSecret:c.target==="secretsImport"})}return n}o(D,"generateDatabaseEnvVarEntries");function v(e){return`connections: [${e.map(t=>p(t)).join(", ")}],`}o(v,"formatConnectionsCode");function k(e){return e.expression===s(g)?g:{__expression:e.expression}}o(k,"toDatabaseEnvVarValue");function P(e,n){const t={},i={};if(!n.needsConnection||!n.connectedDatabase?.length)return{env:t,secrets:i};const l=S(e,n),a=D(l);for(const c of a){const d=k(c);c.isSecret?i[c.key]={__expression:c.expression}:t[c.key]=d}return{env:t,secrets:i}}o(P,"buildDatabaseEnvVars");function E(e){let n="";return n+=r(e.port!==void 0,"port",e.port),n+=r(e.deletionProtection!==void 0,"deletionProtection",e.deletionProtection),n+=r(e.snapshotIdentifier!==void 0,"snapshotIdentifier",e.snapshotIdentifier,"string"),n+=r(e.snapshotUsername!==void 0,"snapshotUsername",e.snapshotUsername,"string"),n+=r(e.monitoringInterval!==void 0,"monitoringInterval",e.monitoringInterval),n}o(E,"generateDatabaseSharedProps");function R(e){if(e.type!=="Instance")return"";let n="";return n+=r(e.instanceType!==void 0,"instanceType",e.instanceType,"string"),n+=r(e.allocatedStorage!==void 0,"allocatedStorage",e.allocatedStorage),n+=r(e.multiAz!==void 0,"multiAz",e.multiAz),n+=r(e.publiclyAccessible!==void 0,"publiclyAccessible",e.publiclyAccessible),n+=r(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=r(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=r(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=r(e.readReplica!==void 0,"readReplica",e.readReplica,"boolean-or-object"),n+=r(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=r(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n}o(R,"generateDatabaseInstanceProps");function I(e){if(e.type!=="Aurora"&&e.type!=="GlobalAurora")return"";let n="";return n+=r(e.encryption!==void 0,"encryption",e.encryption,"object"),n+=r(e.databaseInsights!==void 0,"databaseInsights",e.databaseInsights,"boolean-or-object"),n+=r(e.proxy!==void 0,"proxy",e.proxy,"boolean-or-object"),n+=r(e.credentials!==void 0,"credentials",e.credentials,"object"),n+=r(e.writer!==void 0,"writer",e.writer,"object"),n+=r(e.readers!==void 0,"readers",e.readers,"boolean-or-object"),n+=r(e.backupRetention!==void 0,"backupRetention",e.backupRetention),n+=r(e.preferredMaintenanceWindow!==void 0,"preferredMaintenanceWindow",e.preferredMaintenanceWindow,"string"),n}o(I,"generateDatabaseAuroraProps");function $(e){if(e.type!=="GlobalAurora")return"";let n="";return n+=r(e.primaryRegion!==void 0,"primaryRegion",e.primaryRegion,"string"),e.secondaryRegions!==void 0&&e.secondaryRegions.length>0&&(n+=`
2
+ secondaryRegions: [${m(e.secondaryRegions)}],`),n+=r(e.globalClusterIdentifier!==void 0,"globalClusterIdentifier",e.globalClusterIdentifier,"string"),n+=r(e.enableGlobalWriteForwarding!==void 0,"enableGlobalWriteForwarding",e.enableGlobalWriteForwarding),n}o($,"generateDatabaseGlobalAuroraProps");function C(e,n){return n.compute.some(t=>t.needsConnection&&t.connectedDatabase?.includes(e.name))}o(C,"databaseNeedsVariable");function _(e){if(e.database.length===0)return"";let n="";for(let t=0;t<e.database.length;t++){const i=e.database[t],l=p(i),a=C(i,e),c=t>0,d=a?`const ${l} = `:"";n+=`${c?`
3
+ `:""}${d}app.addDatabase(
4
+ DatabaseFactory.build(${s(i.name)}, {
5
5
  vpc: app.getVpc(),
6
- type: ${a(t.type)},
7
- databaseName: ${a(t.databaseName)},`,t.engineExpression?n+=`
8
- engine: ${t.engineExpression},`:t.databaseEngine&&(n+=`
9
- databaseEngine: ${a(t.databaseEngine)},`),n+=x(t),n+=N(t),n+=P(t),n+=O(t),n+=b(t.extraProperties),t.alarms===!1?n+=`
10
- alarms: false,`:typeof t.alarms=="object"&&(n+=`
11
- alarms: ${S(t.alarms," ")},`),t.type!=="GlobalAurora"&&(n+=m()),n+=`
6
+ type: ${s(i.type)},
7
+ databaseName: ${s(i.databaseName)},`,i.engineExpression?n+=`
8
+ engine: ${i.engineExpression},`:i.databaseEngine&&(n+=`
9
+ databaseEngine: ${s(i.databaseEngine)},`),n+=E(i),n+=R(i),n+=I(i),n+=$(i),n+=f(i.extraProperties),i.alarms===!1?n+=`
10
+ alarms: false,`:typeof i.alarms=="object"&&(n+=`
11
+ alarms: ${u(i.alarms," ")},`),i.type!=="GlobalAurora"&&(n+=h()),n+=`
12
12
  })
13
13
  );
14
- `}return n}c(w,"generateDatabaseCode");function W(e){if(!e.clickhouse||e.clickhouse.length===0)return"";let n="";for(let r=0;r<e.clickhouse.length;r++){const t=e.clickhouse[r],d=p(t),s=k(t,e),i=r>0?`
15
- `:"",f=s?`const ${d} = `:"";n+=`${i}${f}app.addDatabase(
16
- DatabaseFactory.build(${a(t.name)}, {
14
+ `}return n}o(_,"generateDatabaseCode");function W(e){if(!e.clickhouse||e.clickhouse.length===0)return"";let n="";for(let t=0;t<e.clickhouse.length;t++){const i=e.clickhouse[t],l=p(i),a=V(i,e),c=t>0?`
15
+ `:"",d=a?`const ${l} = `:"";n+=`${c}${d}app.addDatabase(
16
+ DatabaseFactory.build(${s(i.name)}, {
17
17
  type: "ClickHouse",
18
- databaseName: ${a(t.databaseName)},`,t.instanceType!==void 0&&(n+=`
19
- instanceType: ${a(t.instanceType)},`),t.coldTier!==void 0&&(n+=`
20
- coldTier: ${S(t.coldTier," ")},`),t.optimiseSchedule!==void 0&&(n+=`
21
- optimiseSchedule: ${S(t.optimiseSchedule," ")},`),t.backupSchedule!==void 0&&(n+=`
22
- backupSchedule: ${S(t.backupSchedule," ")},`),t.backupRetentionDays!==void 0&&(n+=`
23
- backupRetentionDays: ${t.backupRetentionDays},`),n+=b(t.extraProperties),n+=`
18
+ databaseName: ${s(i.databaseName)},`,i.instanceType!==void 0&&(n+=`
19
+ instanceType: ${s(i.instanceType)},`),i.coldTier!==void 0&&(n+=`
20
+ coldTier: ${u(i.coldTier," ")},`),i.optimiseSchedule!==void 0&&(n+=`
21
+ optimiseSchedule: ${u(i.optimiseSchedule," ")},`),i.backupSchedule!==void 0&&(n+=`
22
+ backupSchedule: ${u(i.backupSchedule," ")},`),i.backupRetentionDays!==void 0&&(n+=`
23
+ backupRetentionDays: ${i.backupRetentionDays},`),n+=f(i.extraProperties),n+=`
24
24
  })
25
25
  );
26
- `}return n}c(W,"generateClickHouseCode");function k(e,n){return n.compute.some(r=>r.connectedDatabase?.includes(e.name))}c(k,"clickhouseNeedsVariable");export{A as CREDENTIAL_KEYS,u as DATABASE_ACCESSORS,l as DATABASE_ENV_VARS,g as DATABASE_SSL_VALUE,_ as buildDatabaseEnvVars,I as databaseNeedsVariable,j as formatConnectionsCode,W as generateClickHouseCode,w as generateDatabaseCode,T as generateDatabaseEnvVarEntries,D as getConnectedDatabases,h as toDatabaseEnvVarValue};
26
+ `}return n}o(W,"generateClickHouseCode");function V(e,n){return n.compute.some(t=>t.connectedDatabase?.includes(e.name))}o(V,"clickhouseNeedsVariable");export{F as CREDENTIAL_KEYS,U as DATABASE_ACCESSORS,B as DATABASE_ENV_VARS,z as DATABASE_SSL_VALUE,P as buildDatabaseEnvVars,C as databaseNeedsVariable,v as formatConnectionsCode,W as generateClickHouseCode,_ as generateDatabaseCode,D as generateDatabaseEnvVarEntries,S as getConnectedDatabases,k as toDatabaseEnvVarValue};
@@ -5,6 +5,7 @@
5
5
  * infrastructure code from resource plans.
6
6
  */
7
7
  export { type IdentifierValue, type ExpressionValue, type CallValue, type SpecialValue, isSpecialValue, toPascalCase, toKebab, toValidDatabaseName, toVariableName, formatValue, buildProperty, getVariableName, resolveResourceVariable, emitExtraProperties, } from "./common.js";
8
+ export { CONNECTION_TYPE_ORDER, DATABASE_ACCESSORS, DATABASE_SSL_VALUE, MESSAGING_ACCESSORS, STORAGE_ACCESSORS, type ConnectionResourceType, type ConnectionWiringEntry, type ConnectionWiringValue, buildConnectionWiringEntries, renderWiringValueSource, } from "./connectionWiring.js";
8
9
  export { DATABASE_ENV_VARS, CREDENTIAL_KEYS, type DatabaseEnvVarEntry, type DatabaseEnvVars, getConnectedDatabases, generateDatabaseEnvVarEntries, formatConnectionsCode, buildDatabaseEnvVars, databaseNeedsVariable, generateDatabaseCode, generateClickHouseCode, } from "./database.js";
9
10
  export { STORAGE_ENV_VARS, type StorageEnvVarEntry, type StorageEnvVars, getConnectedStorage, generateStorageEnvVarEntries, buildStorageEnvVars, formatAllConnectionsCode, } from "./storageConnections.js";
10
11
  export { MESSAGING_ENV_VARS, type MessagingEnvVarEntry, type MessagingEnvVars, getConnectedMessaging, generateMessagingEnvVarEntries, buildMessagingEnvVars, } from "./messagingConnections.js";
@@ -1 +1 @@
1
- import{isSpecialValue as t,toPascalCase as r,toKebab as o,toValidDatabaseName as n,toVariableName as s,formatValue as g,buildProperty as d,getVariableName as C,resolveResourceVariable as i,emitExtraProperties as l}from"./common.js";import{DATABASE_ENV_VARS as E,CREDENTIAL_KEYS as V,getConnectedDatabases as b,generateDatabaseEnvVarEntries as c,formatConnectionsCode as p,buildDatabaseEnvVars as S,databaseNeedsVariable as N,generateDatabaseCode as A,generateClickHouseCode as f}from"./database.js";import{STORAGE_ENV_VARS as D,getConnectedStorage as x,generateStorageEnvVarEntries as R,buildStorageEnvVars as v,formatAllConnectionsCode as _}from"./storageConnections.js";import{MESSAGING_ENV_VARS as I,getConnectedMessaging as M,generateMessagingEnvVarEntries as T,buildMessagingEnvVars as G}from"./messagingConnections.js";import{generateLambdaCode as h,generateLambdaConnectionsCode as k,generateEc2Code as y,generateEcsCode as B,generateComputeCode as K}from"./compute.js";import{generateS3Code as w,generateDynamoDBCode as H,generateSQSCode as O,s3NeedsVariable as Q,sqsNeedsVariable as W}from"./storage.js";import{generateNetworkCode as j,generateTags as z,generateAppInit as F,generateImports as J,generateCDNCode as U,collectCdnReferencedResources as X,usesPatternApproach as Z,generatePatternCodeWithComments as $}from"./infrastructure.js";export{V as CREDENTIAL_KEYS,E as DATABASE_ENV_VARS,I as MESSAGING_ENV_VARS,D as STORAGE_ENV_VARS,S as buildDatabaseEnvVars,G as buildMessagingEnvVars,d as buildProperty,v as buildStorageEnvVars,X as collectCdnReferencedResources,N as databaseNeedsVariable,l as emitExtraProperties,_ as formatAllConnectionsCode,p as formatConnectionsCode,g as formatValue,F as generateAppInit,U as generateCDNCode,f as generateClickHouseCode,K as generateComputeCode,A as generateDatabaseCode,c as generateDatabaseEnvVarEntries,H as generateDynamoDBCode,y as generateEc2Code,B as generateEcsCode,J as generateImports,h as generateLambdaCode,k as generateLambdaConnectionsCode,T as generateMessagingEnvVarEntries,j as generateNetworkCode,$ as generatePatternCodeWithComments,w as generateS3Code,O as generateSQSCode,R as generateStorageEnvVarEntries,z as generateTags,b as getConnectedDatabases,M as getConnectedMessaging,x as getConnectedStorage,C as getVariableName,t as isSpecialValue,i as resolveResourceVariable,Q as s3NeedsVariable,W as sqsNeedsVariable,o as toKebab,r as toPascalCase,n as toValidDatabaseName,s as toVariableName,Z as usesPatternApproach};
1
+ import{isSpecialValue as r,toPascalCase as t,toKebab as o,toValidDatabaseName as n,toVariableName as s,formatValue as C,buildProperty as g,getVariableName as i,resolveResourceVariable as d,emitExtraProperties as E}from"./common.js";import{CONNECTION_TYPE_ORDER as A,DATABASE_ACCESSORS as l,DATABASE_SSL_VALUE as V,MESSAGING_ACCESSORS as m,STORAGE_ACCESSORS as b,buildConnectionWiringEntries as c,renderWiringValueSource as p}from"./connectionWiring.js";import{DATABASE_ENV_VARS as u,CREDENTIAL_KEYS as R,getConnectedDatabases as _,generateDatabaseEnvVarEntries as D,formatConnectionsCode as f,buildDatabaseEnvVars as x,databaseNeedsVariable as T,generateDatabaseCode as O,generateClickHouseCode as v}from"./database.js";import{STORAGE_ENV_VARS as I,getConnectedStorage as P,generateStorageEnvVarEntries as L,buildStorageEnvVars as M,formatAllConnectionsCode as B}from"./storageConnections.js";import{MESSAGING_ENV_VARS as h,getConnectedMessaging as k,generateMessagingEnvVarEntries as y,buildMessagingEnvVars as K}from"./messagingConnections.js";import{generateLambdaCode as q,generateLambdaConnectionsCode as w,generateEc2Code as H,generateEcsCode as Q,generateComputeCode as U}from"./compute.js";import{generateS3Code as z,generateDynamoDBCode as F,generateSQSCode as J,s3NeedsVariable as X,sqsNeedsVariable as Z}from"./storage.js";import{generateNetworkCode as ee,generateTags as ae,generateAppInit as re,generateImports as te,generateCDNCode as oe,collectCdnReferencedResources as ne,usesPatternApproach as se,generatePatternCodeWithComments as Ce}from"./infrastructure.js";export{A as CONNECTION_TYPE_ORDER,R as CREDENTIAL_KEYS,l as DATABASE_ACCESSORS,u as DATABASE_ENV_VARS,V as DATABASE_SSL_VALUE,m as MESSAGING_ACCESSORS,h as MESSAGING_ENV_VARS,b as STORAGE_ACCESSORS,I as STORAGE_ENV_VARS,c as buildConnectionWiringEntries,x as buildDatabaseEnvVars,K as buildMessagingEnvVars,g as buildProperty,M as buildStorageEnvVars,ne as collectCdnReferencedResources,T as databaseNeedsVariable,E as emitExtraProperties,B as formatAllConnectionsCode,f as formatConnectionsCode,C as formatValue,re as generateAppInit,oe as generateCDNCode,v as generateClickHouseCode,U as generateComputeCode,O as generateDatabaseCode,D as generateDatabaseEnvVarEntries,F as generateDynamoDBCode,H as generateEc2Code,Q as generateEcsCode,te as generateImports,q as generateLambdaCode,w as generateLambdaConnectionsCode,y as generateMessagingEnvVarEntries,ee as generateNetworkCode,Ce as generatePatternCodeWithComments,z as generateS3Code,J as generateSQSCode,L as generateStorageEnvVarEntries,ae as generateTags,_ as getConnectedDatabases,k as getConnectedMessaging,P as getConnectedStorage,i as getVariableName,r as isSpecialValue,p as renderWiringValueSource,d as resolveResourceVariable,X as s3NeedsVariable,Z as sqsNeedsVariable,o as toKebab,t as toPascalCase,n as toValidDatabaseName,s as toVariableName,se as usesPatternApproach};
@@ -24,6 +24,17 @@ export declare function generateAppInit(plan: ApplicationResourcePlan): string;
24
24
  * Generate import statements for the infrastructure file
25
25
  */
26
26
  export declare function generateImports(plan: ApplicationResourcePlan): string;
27
+ /**
28
+ * The origin lane is DERIVED from the referenced compute's domain state,
29
+ * never stored in the plan: an ECS compute origin without a cluster domain
30
+ * has no TLS-valid hostname, so the auto lane refuses it at synth (E4) and
31
+ * the honest topology is the validated D4 shape — `originType: "alb"` with
32
+ * `protocolPolicy: "HTTP_ONLY"` (plain-HTTP origin fetch, exactly what the
33
+ * pre-14.2 string lane did implicitly). Deriving at emission keeps one
34
+ * source of truth: give the cluster a domain later and regeneration
35
+ * upgrades the CDN to the auto lane by itself.
36
+ */
37
+ export declare function cdnDefaultOriginNeedsAlbLane(plan: ApplicationResourcePlan): boolean;
27
38
  /**
28
39
  * Generate CDN infrastructure code
29
40
  */
@@ -1,47 +1,57 @@
1
- var g=Object.defineProperty;var c=(e,t)=>g(e,"name",{value:t,configurable:!0});import{toVariableName as h,formatValue as d,resolveResourceVariable as u,emitExtraProperties as l}from"./common.js";import{COMPUTE_TYPE as f}from"../schemas/constants.js";import{OPENNEXT_DEFAULTS as F,generatePatternCodeWithComments as E}from"./generatePatternCode.js";const m="fjall:costAllocation:owner",b="engineering";function y(e){return typeof e=="object"&&e!==null&&Object.keys(e).length===0}c(y,"isEmptyObject");function p(e){const t={...e};return y(t.flowLogs)&&delete t.flowLogs,t}c(p,"cleanNetworkConfig");function w(e){if(!e.additionalNetworks||e.additionalNetworks.length===0)return"";let t="";for(const n of e.additionalNetworks){const i=h(n.name),o={};n.maxAzs!==void 0&&(o.maxAzs=n.maxAzs),n.natGateways!==void 0&&(o.natGateways=n.natGateways),n.flowLogs!==void 0&&(o.flowLogs=n.flowLogs),n.vpcEndpoints!==void 0&&(o.vpcEndpoints=n.vpcEndpoints);const s=p(o);t+=`const ${i} = app.addNetwork(
2
- NetworkFactory.build("${n.name}", ${d(s," ")})
1
+ var p=Object.defineProperty;var s=(e,t)=>p(e,"name",{value:t,configurable:!0});import{toVariableName as h,formatValue as d,resolveResourceVariable as u,emitExtraProperties as l}from"./common.js";import{COMPUTE_TYPE as f}from"../schemas/constants.js";import{OPENNEXT_DEFAULTS as v,generatePatternCodeWithComments as E}from"./generatePatternCode.js";const m="fjall:costAllocation:owner",b="engineering";function y(e){return typeof e=="object"&&e!==null&&Object.keys(e).length===0}s(y,"isEmptyObject");function g(e){const t={...e};return y(t.flowLogs)&&delete t.flowLogs,t}s(g,"cleanNetworkConfig");function k(e){if(!e.additionalNetworks||e.additionalNetworks.length===0)return"";let t="";for(const o of e.additionalNetworks){const i=h(o.name),n={};o.maxAzs!==void 0&&(n.maxAzs=o.maxAzs),o.natGateways!==void 0&&(n.natGateways=o.natGateways),o.flowLogs!==void 0&&(n.flowLogs=o.flowLogs),o.vpcEndpoints!==void 0&&(n.vpcEndpoints=o.vpcEndpoints);const c=g(n);t+=`const ${i} = app.addNetwork(
2
+ NetworkFactory.build("${o.name}", ${d(c," ")})
3
3
  );
4
4
 
5
- `}return t}c(w,"generateNetworkCode");function C(e){const t={};return e.tags&&Object.keys(e.tags).length>0&&Object.assign(t,e.tags),t[m]||(t[m]=e.owner||b),`app.addTags({
6
- ${Object.entries(t).map(([i,o])=>` "${i}": "${o}"`).join(`,
5
+ `}return t}s(k,"generateNetworkCode");function N(e){const t={};return e.tags&&Object.keys(e.tags).length>0&&Object.assign(t,e.tags),t[m]||(t[m]=e.owner||b),`app.addTags({
6
+ ${Object.entries(t).map(([i,n])=>` "${i}": "${n}"`).join(`,
7
7
  `)}
8
8
  });
9
9
 
10
- `}c(C,"generateTags");function N(e){let t=`
10
+ `}s(N,"generateTags");function T(e){let t=`
11
11
  const appName = "${e.appName}";
12
- `;const n=e.backup&&typeof e.backup=="object"?e.backup:void 0,i=e.tunnel&&typeof e.tunnel=="object"?e.tunnel:void 0,o=i?i.instanceType?`tunnel: { instanceType: "${i.instanceType}" }`:"tunnel: true":void 0;if(e.vpcId)t+=`const app = App.getApp(appName, {
13
- network: { useExisting: "${e.vpcId}" }`,n&&(t+=`,
14
- backup: { tier: "${n.tier}" }`),o&&(t+=`,
15
- ${o}`),t+=`
12
+ `;const o=e.backup&&typeof e.backup=="object"?e.backup:void 0,i=e.tunnel&&typeof e.tunnel=="object"?e.tunnel:void 0,n=i?i.instanceType?`tunnel: { instanceType: "${i.instanceType}" }`:"tunnel: true":void 0;if(e.vpcId)t+=`const app = App.getApp(appName, {
13
+ network: { useExisting: "${e.vpcId}" }`,o&&(t+=`,
14
+ backup: { tier: "${o.tier}" }`),n&&(t+=`,
15
+ ${n}`),t+=`
16
16
  });
17
- `;else if(e.network){const s=p(e.network);t+=`const app = App.getApp(appName, {
18
- network: ${d(s," ")}`,n&&(t+=`,
19
- backup: { tier: "${n.tier}" }`),o&&(t+=`,
20
- ${o}`),t+=`
17
+ `;else if(e.network){const c=g(e.network);t+=`const app = App.getApp(appName, {
18
+ network: ${d(c," ")}`,o&&(t+=`,
19
+ backup: { tier: "${o.tier}" }`),n&&(t+=`,
20
+ ${n}`),t+=`
21
21
  });
22
- `}else t+="const app = App.getApp(appName, { network: false",n&&(t+=`, backup: { tier: "${n.tier}" }`),o&&(t+=`, ${o}`),t+=` });
22
+ `}else t+="const app = App.getApp(appName, { network: false",o&&(t+=`, backup: { tier: "${o.tier}" }`),n&&(t+=`, ${n}`),t+=` });
23
23
  `;return t+=`
24
- `,t}c(N,"generateAppInit");function j(e){const t=[];if(e.patternConfig?t.push("PatternFactory"):(e.database.length>0&&t.push("DatabaseFactory"),e.s3.length>0&&t.push("StorageFactory"),e.compute.length>0&&t.push("ComputeFactory"),(e.compute.length>0||e.database.length>0||e.sqs!==void 0&&e.sqs.length>0)&&t.push("getConfig"),e.dynamodb&&e.dynamodb.length>0&&e.database.length===0&&t.push("DatabaseFactory"),e.clickhouse&&e.clickhouse.length>0&&e.database.length===0&&!(e.dynamodb&&e.dynamodb.length>0)&&t.push("DatabaseFactory"),e.sqs&&e.sqs.length>0&&t.push("MessagingFactory"),e.cdn&&t.push("CdnFactory"),e.compute.some(r=>r.type===f.LAMBDA&&r.deployment==="code")&&(t.push("Code"),t.push("Runtime")),e.compute.some(r=>r.type===f.LAMBDA&&r.functionUrl)&&t.push("FunctionUrlAuthType"),e.compute.some(r=>r.type===f.LAMBDA&&(r.architecture||r.deployment==="container"))&&t.push("Architecture")),e.additionalNetworks&&e.additionalNetworks.length>0&&t.push("NetworkFactory"),e.additionalManagedImports){for(const o of e.additionalManagedImports)if(o.moduleSpecifier==="@fjall/components-infrastructure"||o.moduleSpecifier==="@fjall/infrastructure")for(const s of o.namedImports)t.includes(s)||t.push(s)}let i=`#!/usr/bin/env node
24
+ `,t}s(T,"generateAppInit");function P(e){const t=[];if(e.patternConfig?t.push("PatternFactory"):(e.database.length>0&&t.push("DatabaseFactory"),e.s3.length>0&&t.push("StorageFactory"),e.compute.length>0&&t.push("ComputeFactory"),(e.compute.length>0||e.database.length>0||e.sqs!==void 0&&e.sqs.length>0)&&t.push("getConfig"),e.dynamodb&&e.dynamodb.length>0&&e.database.length===0&&t.push("DatabaseFactory"),e.clickhouse&&e.clickhouse.length>0&&e.database.length===0&&!(e.dynamodb&&e.dynamodb.length>0)&&t.push("DatabaseFactory"),e.sqs&&e.sqs.length>0&&t.push("MessagingFactory"),e.cdn&&t.push("CdnFactory"),e.compute.some(r=>r.type===f.LAMBDA&&r.deployment==="code")&&(t.push("Code"),t.push("Runtime")),e.compute.some(r=>r.type===f.LAMBDA&&r.functionUrl)&&t.push("FunctionUrlAuthType"),e.compute.some(r=>r.type===f.LAMBDA&&(r.architecture||r.deployment==="container"))&&t.push("Architecture")),e.additionalNetworks&&e.additionalNetworks.length>0&&t.push("NetworkFactory"),e.additionalManagedImports){for(const n of e.additionalManagedImports)if(n.moduleSpecifier==="@fjall/components-infrastructure"||n.moduleSpecifier==="@fjall/infrastructure")for(const c of n.namedImports)t.includes(c)||t.push(c)}let i=`#!/usr/bin/env node
25
25
 
26
26
  import { App${t.length>0?`, ${t.join(", ")}`:""} } from "@fjall/components-infrastructure";
27
- `;if(e.additionalManagedImports)for(const o of e.additionalManagedImports){if(o.moduleSpecifier==="@fjall/components-infrastructure"||o.moduleSpecifier==="@fjall/infrastructure")continue;const s=o.namedImports.length>0?`{ ${o.namedImports.join(", ")} }`:"",r=[o.defaultImport??"",s].filter(Boolean).join(", ");r&&(i+=`import ${r} from "${o.moduleSpecifier}";
28
- `)}return i}c(j,"generateImports");function x(e){if(!e.cdn)return"";const t=u(e,e.cdn.defaultOriginRef);let n=`
27
+ `;if(e.additionalManagedImports)for(const n of e.additionalManagedImports){if(n.moduleSpecifier==="@fjall/components-infrastructure"||n.moduleSpecifier==="@fjall/infrastructure")continue;const c=n.namedImports.length>0?`{ ${n.namedImports.join(", ")} }`:"",r=[n.defaultImport??"",c].filter(Boolean).join(", ");r&&(i+=`import ${r} from "${n.moduleSpecifier}";
28
+ `)}return i}s(P,"generateImports");function A(e){if(!e.cdn)return!1;const t=e.compute.find(n=>n.name===e.cdn?.defaultOriginRef);if(t===void 0||t.type!=="ecs")return!1;const o=t.cluster;return o?.domain!==void 0?!1:!(o?.extraProperties??[]).some(n=>n.key==="domainConfig")}s(A,"cdnDefaultOriginNeedsAlbLane");function x(e){if(!e.cdn)return"";const t=u(e,e.cdn.defaultOriginRef);let o=A(e)?`
29
+ app.addCdn(
30
+ CdnFactory.build("${e.cdn.name}", {
31
+ // Plain-HTTP origin fetch: the compute has no domain, so no TLS-valid
32
+ // origin hostname exists. Give the cluster a domain and switch to
33
+ // originType "auto" for HTTPS between CloudFront and the origin.
34
+ originType: "alb",
35
+ loadBalancer: ${t},
36
+ protocolPolicy: "HTTP_ONLY"`:`
29
37
  app.addCdn(
30
38
  CdnFactory.build("${e.cdn.name}", {
31
39
  originType: "auto",
32
- origin: ${t}`;if(e.cdn.behaviours&&e.cdn.behaviours.length>0){const i=e.cdn.behaviours.map(o=>{const s=u(e,o.originRef);let a=`{
33
- pathPattern: "${o.pathPattern}",
34
- origin: ${s},`;return o.cachePolicy&&(a+=`
35
- cachePolicy: "${o.cachePolicy}",`),a+=`
40
+ origin: ${t}`;if(e.cdn.behaviours&&e.cdn.behaviours.length>0){const i=e.cdn.behaviours.map(n=>{const c=u(e,n.originRef);let a=`{
41
+ pathPattern: "${n.pathPattern}",
42
+ origin: ${c},`;return n.cachePolicy&&(a+=`
43
+ cachePolicy: "${n.cachePolicy}",`),a+=`
36
44
  }`,a}).join(`,
37
- `);n+=`,
45
+ `);o+=`,
38
46
  behaviours: [
39
47
  ${i}
40
- ]`}return e.cdn.customDomain&&(n+=`,
41
- domainNames: ["${e.cdn.customDomain}"]`),e.cdn.certificateArn&&(n+=`,
42
- certificateArn: "${e.cdn.certificateArn}"`),e.cdn.accessGate!==void 0&&(e.cdn.accessGate===!1?n+=`,
43
- accessGate: false`:n+=`,
44
- accessGate: ${d(e.cdn.accessGate," ")}`),n+=l(e.cdn.extraProperties),n+=`
48
+ ]`}return e.cdn.customDomain&&(o+=`,
49
+ domainNames: ["${e.cdn.customDomain}"]`),e.cdn.domain&&(o+=`,
50
+ domainConfig: { domainName: "${e.cdn.domain}" }`),e.cdn.certificateArn&&(o+=`,
51
+ certificateArn: "${e.cdn.certificateArn}"`),e.cdn.originHostname&&(o+=`,
52
+ originHostname: "${e.cdn.originHostname}"`),e.cdn.accessGate!==void 0&&(e.cdn.accessGate===!1?o+=`,
53
+ accessGate: false`:o+=`,
54
+ accessGate: ${d(e.cdn.accessGate," ")}`),o+=l(e.cdn.extraProperties),o+=`
45
55
  })
46
56
  );
47
- `,n}c(x,"generateCDNCode");function L(e){const t=new Set;if(e.cdn&&(e.cdn.defaultOriginRef&&t.add(e.cdn.defaultOriginRef),e.cdn.behaviours))for(const n of e.cdn.behaviours)t.add(n.originRef);return t}c(L,"collectCdnReferencedResources");function O(e){return e.patternConfig!==void 0}c(O,"usesPatternApproach");export{m as COST_ALLOCATION_TAG,b as DEFAULT_COST_ALLOCATION_OWNER,F as OPENNEXT_DEFAULTS,L as collectCdnReferencedResources,N as generateAppInit,x as generateCDNCode,j as generateImports,w as generateNetworkCode,E as generatePatternCodeWithComments,C as generateTags,O as usesPatternApproach};
57
+ `,o}s(x,"generateCDNCode");function L(e){const t=new Set;if(e.cdn&&(e.cdn.defaultOriginRef&&t.add(e.cdn.defaultOriginRef),e.cdn.behaviours))for(const o of e.cdn.behaviours)t.add(o.originRef);return t}s(L,"collectCdnReferencedResources");function O(e){return e.patternConfig!==void 0}s(O,"usesPatternApproach");export{m as COST_ALLOCATION_TAG,b as DEFAULT_COST_ALLOCATION_OWNER,v as OPENNEXT_DEFAULTS,A as cdnDefaultOriginNeedsAlbLane,L as collectCdnReferencedResources,T as generateAppInit,x as generateCDNCode,P as generateImports,k as generateNetworkCode,E as generatePatternCodeWithComments,N as generateTags,O as usesPatternApproach};
@@ -5,10 +5,7 @@
5
5
  * following the same pattern as database and storage connections.
6
6
  */
7
7
  import type { SQSResourcePlan, ApplicationResourcePlan, ComputeResourcePlan } from "../schemas/resourceSchemas.js";
8
- export declare const MESSAGING_ENV_VARS: Readonly<{
9
- readonly URL: "QUEUE_URL";
10
- readonly ARN: "QUEUE_ARN";
11
- }>;
8
+ export { MESSAGING_ACCESSORS, MESSAGING_ENV_VARS } from "./connectionWiring.js";
12
9
  export type MessagingEnvVarEntry = {
13
10
  key: string;
14
11
  expression: string;
@@ -1 +1 @@
1
- var g=Object.defineProperty;var u=(s,e)=>g(s,"name",{value:e,configurable:!0});import{connectionEnvSuffix as p,getVariableName as f}from"./common.js";const i=Object.freeze({URL:"QUEUE_URL",ARN:"QUEUE_ARN"});function a(s,e){const{connectedMessaging:n}=e;return n?.length?(s.sqs??[]).filter(t=>n.includes(t.name)):[]}u(a,"getConnectedMessaging");function x(s){const e=[];if(s.length===1){const n=s[0];if(!n)return e;const t=f(n);e.push({key:i.URL,expression:`${t}.getQueueUrl()`}),e.push({key:i.ARN,expression:`${t}.getQueueArn()`})}else for(const[n,t]of s.entries()){const r=f(t),o=p(n);e.push({key:`${i.URL}${o}`,expression:`${r}.getQueueUrl()`}),e.push({key:`${i.ARN}${o}`,expression:`${r}.getQueueArn()`})}return e}u(x,"generateMessagingEnvVarEntries");function U(s,e){const n={},t={};if(!e.connectedMessaging?.length)return{env:n,secrets:t};const r=a(s,e),o=x(r);for(const c of o)n[c.key]={__expression:c.expression};return{env:n,secrets:t}}u(U,"buildMessagingEnvVars");export{i as MESSAGING_ENV_VARS,U as buildMessagingEnvVars,x as generateMessagingEnvVarEntries,a as getConnectedMessaging};
1
+ var g=Object.defineProperty;var o=(r,e)=>g(r,"name",{value:e,configurable:!0});import{connectionEnvSuffix as u,getVariableName as f}from"./common.js";import{buildConnectionWiringEntries as a,renderWiringValueSource as x}from"./connectionWiring.js";import{MESSAGING_ACCESSORS as v,MESSAGING_ENV_VARS as y}from"./connectionWiring.js";function S(r,e){const{connectedMessaging:n}=e;return n?.length?(r.sqs??[]).filter(s=>n.includes(s.name)):[]}o(S,"getConnectedMessaging");function d(r){const e=[];for(const[n,s]of r.entries()){const i=f(s),c=u(n);for(const t of a("messaging",c))e.push({key:t.key,expression:x(t.value,i)})}return e}o(d,"generateMessagingEnvVarEntries");function M(r,e){const n={},s={};if(!e.connectedMessaging?.length)return{env:n,secrets:s};const i=S(r,e),c=d(i);for(const t of c)n[t.key]={__expression:t.expression};return{env:n,secrets:s}}o(M,"buildMessagingEnvVars");export{v as MESSAGING_ACCESSORS,y as MESSAGING_ENV_VARS,M as buildMessagingEnvVars,d as generateMessagingEnvVarEntries,S as getConnectedMessaging};
@@ -5,18 +5,7 @@
5
5
  * following the same pattern as database connections.
6
6
  */
7
7
  import type { S3ResourcePlan, SQSResourcePlan, ApplicationResourcePlan, ComputeResourcePlan, DatabaseResourcePlan } from "../schemas/resourceSchemas.js";
8
- export declare const STORAGE_ENV_VARS: Readonly<{
9
- readonly NAME: "BUCKET_NAME";
10
- }>;
11
- /**
12
- * Construct accessor methods the emitted connection wiring calls on a bound
13
- * bucket variable. Shared with the codemod connection edit
14
- * (`codemod/edits/connectResourceToCompute.ts`) — the two emitters must call
15
- * identical methods or surgically-wired apps fail at synth.
16
- */
17
- export declare const STORAGE_ACCESSORS: Readonly<{
18
- readonly BUCKET_NAME: "getBucketName";
19
- }>;
8
+ export { STORAGE_ACCESSORS, STORAGE_ENV_VARS } from "./connectionWiring.js";
20
9
  export type StorageEnvVarEntry = {
21
10
  key: string;
22
11
  expression: string;
@@ -1 +1 @@
1
- var p=Object.defineProperty;var i=(t,e)=>p(t,"name",{value:e,configurable:!0});import{connectionEnvSuffix as g,getVariableName as a}from"./common.js";const u=Object.freeze({NAME:"BUCKET_NAME"}),E=Object.freeze({BUCKET_NAME:"getBucketName"});function l(t,e){const{connectedStorage:n}=e;return n?.length?t.s3.filter(r=>n.includes(r.name)):[]}i(l,"getConnectedStorage");function x(t){const e=[];if(t.length===1){const n=t[0];if(!n)return e;const r=a(n);e.push({key:u.NAME,expression:`${r}.${E.BUCKET_NAME}()`})}else for(const[n,r]of t.entries()){const o=a(r),s=g(n);e.push({key:`${u.NAME}${s}`,expression:`${o}.${E.BUCKET_NAME}()`})}return e}i(x,"generateStorageEnvVarEntries");function S(t,e){const n={},r={};if(!e.connectedStorage?.length)return{env:n,secrets:r};const o=l(t,e),s=x(o);for(const f of s)n[f.key]={__expression:f.expression};return{env:n,secrets:r}}i(S,"buildStorageEnvVars");function N(t,e,n=[]){const r=t.map(c=>a(c)),o=e.map(c=>a(c)),s=n.map(c=>a(c));return`connections: [${[...r,...o,...s].join(", ")}],`}i(N,"formatAllConnectionsCode");export{E as STORAGE_ACCESSORS,u as STORAGE_ENV_VARS,S as buildStorageEnvVars,N as formatAllConnectionsCode,x as generateStorageEnvVarEntries,l as getConnectedStorage};
1
+ var f=Object.defineProperty;var c=(o,e)=>f(o,"name",{value:e,configurable:!0});import{connectionEnvSuffix as u,getVariableName as a}from"./common.js";import{CONNECTION_TYPE_ORDER as g,buildConnectionWiringEntries as l,renderWiringValueSource as p}from"./connectionWiring.js";import{STORAGE_ACCESSORS as b,STORAGE_ENV_VARS as v}from"./connectionWiring.js";function S(o,e){const{connectedStorage:t}=e;return t?.length?o.s3.filter(r=>t.includes(r.name)):[]}c(S,"getConnectedStorage");function E(o){const e=[];for(const[t,r]of o.entries()){const i=a(r),n=u(t);for(const s of l("storage",n))e.push({key:s.key,expression:p(s.value,i)})}return e}c(E,"generateStorageEnvVarEntries");function V(o,e){const t={},r={};if(!e.connectedStorage?.length)return{env:t,secrets:r};const i=S(o,e),n=E(i);for(const s of n)t[s.key]={__expression:s.expression};return{env:t,secrets:r}}c(V,"buildStorageEnvVars");function C(o,e,t=[]){const r={database:o.map(n=>a(n)),storage:e.map(n=>a(n)),messaging:t.map(n=>a(n))};return`connections: [${g.flatMap(n=>r[n]).join(", ")}],`}c(C,"formatAllConnectionsCode");export{b as STORAGE_ACCESSORS,v as STORAGE_ENV_VARS,V as buildStorageEnvVars,C as formatAllConnectionsCode,E as generateStorageEnvVarEntries,S as getConnectedStorage};
@@ -121,6 +121,9 @@ export interface CdnAddOptions {
121
121
  readonly defaultOriginRef: string;
122
122
  readonly customDomain?: string;
123
123
  readonly certificateArn?: string;
124
+ /** Managed-domain lane — exclusive with customDomain/certificateArn. */
125
+ readonly domain?: string;
126
+ readonly originHostname?: string;
124
127
  readonly behaviours?: ReadonlyArray<{
125
128
  pathPattern: string;
126
129
  originRef: string;
@@ -1 +1 @@
1
- var b=Object.defineProperty;var d=(a,e)=>b(a,"name",{value:e,configurable:!0});import{success as c,failure as u}from"../types/Result.js";import{toPascalCase as l}from"../generation/common.js";import{applyComputeConnections as y,applyServiceConnections as w}from"./resourceConnections.js";function z(a){const e=a.database.length>0,n=a.cdn!==void 0;return[{type:"database",label:"Database (RDS)",available:!0},{type:"database:proxy",label:"RDS Proxy",available:e,reason:e?void 0:"Requires at least one database"},{type:"storage:s3",label:"S3 Bucket",available:!0},{type:"network",label:"Network (VPC)",available:!0},{type:"compute:ecs",label:"Compute (ECS)",available:!0},{type:"compute:lambda",label:"Compute (Lambda)",available:!0},{type:"cdn",label:"CDN (CloudFront)",available:!n,reason:n?"A CDN is already configured. Remove existing CDN first.":void 0},{type:"tunnel",label:"Database Tunnel",available:e&&!a.tunnel,reason:e?a.tunnel?"Tunnel is already enabled":void 0:"Requires at least one database"}]}d(z,"listAvailableResources");function g(a,e){if(S(a,e.resourceName))return u(new Error($(e.resourceName)));switch(e.type){case"database":return v(a,e);case"database:proxy":return h(a,e);case"storage:s3":return c(void 0);case"network":return c(void 0);case"compute:ecs":return!e.services||e.services.length===0?u(new Error("ECS compute requires at least one service.")):c(void 0);case"compute:lambda":return c(void 0);case"cdn":return C(a,e);case"tunnel":return R(a);default:{const n=e;return u(new Error(`Unknown resource type: ${String(n)}`))}}}d(g,"validateResourceAddition");function v(a,e){const n=e.databaseName??e.resourceName.toLowerCase();return a.database.some(t=>t.databaseName===n)?u(new Error(`Database name '${n}' already exists. Choose a different database name.`)):e.databaseType==="GlobalAurora"&&!e.primaryRegion?u(new Error("GlobalAurora databases require a primaryRegion.")):c(void 0)}d(v,"validateDatabaseAddition");function h(a,e){const n=a.database.find(r=>r.name===e.targetDatabase||r.databaseName===e.targetDatabase);if(!n){const r=a.database.map(t=>t.name).join(", ")||"none";return u(new Error(`Database '${e.targetDatabase}' not found. Available databases: ${r}`))}return n.proxy!==void 0&&n.proxy!==!1?u(new Error(`Database '${n.name}' already has RDS Proxy enabled.`)):c(void 0)}d(h,"validateProxyAddition");function C(a,e){if(a.cdn)return u(new Error("A CDN is already configured for this application. Remove the existing CDN first."));if(!f(a,e.defaultOriginRef))return u(new Error(`Origin '${e.defaultOriginRef}' not found in plan. CDN origin must reference an existing resource.`));if(e.behaviours){for(const n of e.behaviours)if(!f(a,n.originRef))return u(new Error(`Behaviour origin '${n.originRef}' not found in plan.`))}return c(void 0)}d(C,"validateCdnAddition");function R(a){return a.tunnel&&typeof a.tunnel=="object"?u(new Error("Tunnel is already enabled for this application.")):a.database.length===0?u(new Error("No databases found \u2014 tunnel requires at least one relational database.")):c(void 0)}d(R,"validateTunnelAddition");function O(a,e){const n=g(a,e);if(!n.success)return n;switch(e.type){case"database":return k(a,e);case"database:proxy":return x(a,e);case"storage:s3":return N(a,e);case"network":return D(a,e);case"compute:ecs":return A(a,e);case"compute:lambda":return T(a,e);case"cdn":return E(a,e);case"tunnel":return P(a,e);default:{const r=e;return u(new Error(`Unknown resource type: ${String(r)}`))}}}d(O,"addResourceToPlan");function k(a,e){const n=e.databaseName??e.resourceName.toLowerCase(),r={name:e.resourceName,type:e.databaseType,databaseName:n};let t;switch(e.databaseType){case"Instance":t={...r,...e.instanceType!==void 0?{instanceType:e.instanceType}:{},...e.multiAz!==void 0?{multiAz:e.multiAz}:{},...e.readReplica!==void 0?{readReplica:e.readReplica}:{},...e.publiclyAccessible!==void 0?{publiclyAccessible:e.publiclyAccessible}:{},...e.backupRetention!==void 0?{backupRetention:e.backupRetention}:{}};break;case"Aurora":t={...r,...e.writer!==void 0?{writer:e.writer}:{},...e.readers!==void 0?{readers:e.readers}:{},...e.backupRetention!==void 0?{backupRetention:e.backupRetention}:{},...e.preferredMaintenanceWindow!==void 0?{preferredMaintenanceWindow:e.preferredMaintenanceWindow}:{}};break;case"GlobalAurora":t={...r,primaryRegion:e.primaryRegion,...e.secondaryRegions!==void 0?{secondaryRegions:e.secondaryRegions}:{}};break;default:{const s=e.databaseType;return u(new Error(`Unknown database type: ${String(s)}`))}}const i={...a,database:[...a.database,t]};return o(i,e.resourceName,"database",e),c(i)}d(k,"addDatabase");function x(a,e){const n=a.database.map(i=>({...i})),r=n.find(i=>i.name===e.targetDatabase||i.databaseName===e.targetDatabase);if(!r)return u(new Error(`Database '${e.targetDatabase}' not found.`));const t={};return e.maxConnections!==void 0&&(t.maxConnections=e.maxConnections),e.maxIdleConnections!==void 0&&(t.maxIdleConnections=e.maxIdleConnections),e.connectionBorrowTimeout!==void 0&&(t.connectionBorrowTimeout=e.connectionBorrowTimeout),e.requireTLS!==void 0&&(t.requireTLS=e.requireTLS),r.proxy=Object.keys(t).length>0?t:{},c({...a,database:n})}d(x,"addProxy");function N(a,e){const n=e.bucketName??e.resourceName.toLowerCase(),r=l(n),t=a.s3.length,i=t===0?"":`${t+1}`,s={name:r,bucketName:n,variableName:`bucket${i}`,...e.publicReadAccess!==void 0?{publicReadAccess:e.publicReadAccess}:{},...e.versioned!==void 0?{versioned:e.versioned}:{},...e.encryption!==void 0?{encryption:e.encryption}:{},...e.websiteHosting?{websiteHosting:{indexDocument:"index.html"}}:{}},m={...a,s3:[...a.s3,s]};return o(m,r,"storage",e),c(m)}d(N,"addS3");function D(a,e){const n={};if(e.maxAzs!==void 0&&(n.maxAzs=e.maxAzs),e.natGateways!==void 0&&(n.natGateways=e.natGateways),e.flowLogs!==void 0&&(n.flowLogs=e.flowLogs),e.vpcEndpoints!==void 0&&(n.vpcEndpoints=e.vpcEndpoints),e.networkName){const r={name:e.networkName,...n};return c({...a,additionalNetworks:[...a.additionalNetworks??[],r]})}return c({...a,network:{...a.network??{},...n}})}d(D,"addNetwork");function A(a,e){const n=e.connectedDatabase??[],r={name:e.resourceName,type:"ecs",needsConnection:n.length>0,connectedDatabase:n,...e.loadBalancer!==void 0?{cluster:{loadBalancer:e.loadBalancer}}:{},services:e.services.map(t=>({name:t.name,capacityProvider:t.capacityProvider??"FARGATE",...t.port!==void 0?{containers:[{port:t.port}]}:{},...t.cpu!==void 0?{cpu:t.cpu}:{},...t.memory!==void 0?{memoryLimitMiB:t.memory}:{}})),...e.docker!==void 0&&{docker:e.docker}};return c({...a,compute:[...a.compute,r]})}d(A,"addEcsCompute");function T(a,e){const n=e.connectedDatabase??[],r={name:e.resourceName,type:"lambda",needsConnection:n.length>0,connectedDatabase:n,...e.timeout!==void 0?{timeout:e.timeout}:{},...e.memory!==void 0?{memory:e.memory}:{},...e.handler!==void 0?{handler:e.handler}:{},...e.runtime!==void 0?{runtime:e.runtime}:{}};return c({...a,compute:[...a.compute,r]})}d(T,"addLambdaCompute");function E(a,e){const n={name:e.resourceName,defaultOriginRef:e.defaultOriginRef,...e.customDomain!==void 0?{customDomain:e.customDomain}:{},...e.certificateArn!==void 0?{certificateArn:e.certificateArn}:{},...e.behaviours&&e.behaviours.length>0?{behaviours:[...e.behaviours].map(r=>({pathPattern:r.pathPattern,originRef:r.originRef,...r.cachePolicy!==void 0?{cachePolicy:r.cachePolicy}:{}}))}:{}};return c({...a,cdn:n})}d(E,"addCdn");function P(a,e){const n=e.instanceType?{instanceType:e.instanceType}:{};return c({...a,tunnel:n})}d(P,"addTunnel");function S(a,e){const n=[...a.database.map(r=>r.name),...(a.clickhouse??[]).map(r=>r.name),...a.s3.map(r=>r.name),...a.compute.map(r=>r.name),...(a.dynamodb??[]).map(r=>r.name),...(a.sqs??[]).map(r=>r.name),...(a.additionalNetworks??[]).map(r=>r.name)];return a.cdn&&n.push(a.cdn.name),n.includes(e)}d(S,"isResourceNameTaken");function $(a){return`Resource name '${a}' is already used in this application.`}d($,"resourceNameTakenMessage");function f(a,e){return a.database.some(n=>n.name===e)||a.s3.some(n=>n.name===e)||a.compute.some(n=>n.name===e)||(a.dynamodb??[]).some(n=>n.name===e)||(a.sqs??[]).some(n=>n.name===e)}d(f,"resourceExistsInPlan");function o(a,e,n,r){r.connectToCompute&&r.connectToCompute.length>0&&y(a,[...r.connectToCompute],e,n),r.connectToServices&&r.connectToServices.length>0&&w(a,[...r.connectToServices],e,n)}d(o,"applyConnections");export{O as addResourceToPlan,S as isResourceNameTaken,z as listAvailableResources,$ as resourceNameTakenMessage,g as validateResourceAddition};
1
+ var b=Object.defineProperty;var d=(a,e)=>b(a,"name",{value:e,configurable:!0});import{success as u,failure as c}from"../types/Result.js";import{toPascalCase as l}from"../generation/common.js";import{applyComputeConnections as y,applyServiceConnections as g}from"./resourceConnections.js";function z(a){const e=a.database.length>0,n=a.cdn!==void 0;return[{type:"database",label:"Database (RDS)",available:!0},{type:"database:proxy",label:"RDS Proxy",available:e,reason:e?void 0:"Requires at least one database"},{type:"storage:s3",label:"S3 Bucket",available:!0},{type:"network",label:"Network (VPC)",available:!0},{type:"compute:ecs",label:"Compute (ECS)",available:!0},{type:"compute:lambda",label:"Compute (Lambda)",available:!0},{type:"cdn",label:"CDN (CloudFront)",available:!n,reason:n?"A CDN is already configured. Remove existing CDN first.":void 0},{type:"tunnel",label:"Database Tunnel",available:e&&!a.tunnel,reason:e?a.tunnel?"Tunnel is already enabled":void 0:"Requires at least one database"}]}d(z,"listAvailableResources");function w(a,e){if(S(a,e.resourceName))return c(new Error($(e.resourceName)));switch(e.type){case"database":return v(a,e);case"database:proxy":return h(a,e);case"storage:s3":return u(void 0);case"network":return u(void 0);case"compute:ecs":return!e.services||e.services.length===0?c(new Error("ECS compute requires at least one service.")):u(void 0);case"compute:lambda":return u(void 0);case"cdn":return C(a,e);case"tunnel":return R(a);default:{const n=e;return c(new Error(`Unknown resource type: ${String(n)}`))}}}d(w,"validateResourceAddition");function v(a,e){const n=e.databaseName??e.resourceName.toLowerCase();return a.database.some(t=>t.databaseName===n)?c(new Error(`Database name '${n}' already exists. Choose a different database name.`)):e.databaseType==="GlobalAurora"&&!e.primaryRegion?c(new Error("GlobalAurora databases require a primaryRegion.")):u(void 0)}d(v,"validateDatabaseAddition");function h(a,e){const n=a.database.find(r=>r.name===e.targetDatabase||r.databaseName===e.targetDatabase);if(!n){const r=a.database.map(t=>t.name).join(", ")||"none";return c(new Error(`Database '${e.targetDatabase}' not found. Available databases: ${r}`))}return n.proxy!==void 0&&n.proxy!==!1?c(new Error(`Database '${n.name}' already has RDS Proxy enabled.`)):u(void 0)}d(h,"validateProxyAddition");function C(a,e){if(a.cdn)return c(new Error("A CDN is already configured for this application. Remove the existing CDN first."));if(!f(a,e.defaultOriginRef))return c(new Error(`Origin '${e.defaultOriginRef}' not found in plan. CDN origin must reference an existing resource.`));if(e.behaviours){for(const n of e.behaviours)if(!f(a,n.originRef))return c(new Error(`Behaviour origin '${n.originRef}' not found in plan.`))}return u(void 0)}d(C,"validateCdnAddition");function R(a){return a.tunnel&&typeof a.tunnel=="object"?c(new Error("Tunnel is already enabled for this application.")):a.database.length===0?c(new Error("No databases found \u2014 tunnel requires at least one relational database.")):u(void 0)}d(R,"validateTunnelAddition");function O(a,e){const n=w(a,e);if(!n.success)return n;switch(e.type){case"database":return k(a,e);case"database:proxy":return x(a,e);case"storage:s3":return N(a,e);case"network":return D(a,e);case"compute:ecs":return A(a,e);case"compute:lambda":return T(a,e);case"cdn":return E(a,e);case"tunnel":return P(a,e);default:{const r=e;return c(new Error(`Unknown resource type: ${String(r)}`))}}}d(O,"addResourceToPlan");function k(a,e){const n=e.databaseName??e.resourceName.toLowerCase(),r={name:e.resourceName,type:e.databaseType,databaseName:n};let t;switch(e.databaseType){case"Instance":t={...r,...e.instanceType!==void 0?{instanceType:e.instanceType}:{},...e.multiAz!==void 0?{multiAz:e.multiAz}:{},...e.readReplica!==void 0?{readReplica:e.readReplica}:{},...e.publiclyAccessible!==void 0?{publiclyAccessible:e.publiclyAccessible}:{},...e.backupRetention!==void 0?{backupRetention:e.backupRetention}:{}};break;case"Aurora":t={...r,...e.writer!==void 0?{writer:e.writer}:{},...e.readers!==void 0?{readers:e.readers}:{},...e.backupRetention!==void 0?{backupRetention:e.backupRetention}:{},...e.preferredMaintenanceWindow!==void 0?{preferredMaintenanceWindow:e.preferredMaintenanceWindow}:{}};break;case"GlobalAurora":t={...r,primaryRegion:e.primaryRegion,...e.secondaryRegions!==void 0?{secondaryRegions:e.secondaryRegions}:{}};break;default:{const s=e.databaseType;return c(new Error(`Unknown database type: ${String(s)}`))}}const i={...a,database:[...a.database,t]};return o(i,e.resourceName,"database",e),u(i)}d(k,"addDatabase");function x(a,e){const n=a.database.map(i=>({...i})),r=n.find(i=>i.name===e.targetDatabase||i.databaseName===e.targetDatabase);if(!r)return c(new Error(`Database '${e.targetDatabase}' not found.`));const t={};return e.maxConnections!==void 0&&(t.maxConnections=e.maxConnections),e.maxIdleConnections!==void 0&&(t.maxIdleConnections=e.maxIdleConnections),e.connectionBorrowTimeout!==void 0&&(t.connectionBorrowTimeout=e.connectionBorrowTimeout),e.requireTLS!==void 0&&(t.requireTLS=e.requireTLS),r.proxy=Object.keys(t).length>0?t:{},u({...a,database:n})}d(x,"addProxy");function N(a,e){const n=e.bucketName??e.resourceName.toLowerCase(),r=l(n),t=a.s3.length,i=t===0?"":`${t+1}`,s={name:r,bucketName:n,variableName:`bucket${i}`,...e.publicReadAccess!==void 0?{publicReadAccess:e.publicReadAccess}:{},...e.versioned!==void 0?{versioned:e.versioned}:{},...e.encryption!==void 0?{encryption:e.encryption}:{},...e.websiteHosting?{websiteHosting:{indexDocument:"index.html"}}:{}},m={...a,s3:[...a.s3,s]};return o(m,r,"storage",e),u(m)}d(N,"addS3");function D(a,e){const n={};if(e.maxAzs!==void 0&&(n.maxAzs=e.maxAzs),e.natGateways!==void 0&&(n.natGateways=e.natGateways),e.flowLogs!==void 0&&(n.flowLogs=e.flowLogs),e.vpcEndpoints!==void 0&&(n.vpcEndpoints=e.vpcEndpoints),e.networkName){const r={name:e.networkName,...n};return u({...a,additionalNetworks:[...a.additionalNetworks??[],r]})}return u({...a,network:{...a.network??{},...n}})}d(D,"addNetwork");function A(a,e){const n=e.connectedDatabase??[],r={name:e.resourceName,type:"ecs",needsConnection:n.length>0,connectedDatabase:n,...e.loadBalancer!==void 0?{cluster:{loadBalancer:e.loadBalancer}}:{},services:e.services.map(t=>({name:t.name,capacityProvider:t.capacityProvider??"FARGATE",...t.port!==void 0?{containers:[{port:t.port}]}:{},...t.cpu!==void 0?{cpu:t.cpu}:{},...t.memory!==void 0?{memoryLimitMiB:t.memory}:{}})),...e.docker!==void 0&&{docker:e.docker}};return u({...a,compute:[...a.compute,r]})}d(A,"addEcsCompute");function T(a,e){const n=e.connectedDatabase??[],r={name:e.resourceName,type:"lambda",needsConnection:n.length>0,connectedDatabase:n,...e.timeout!==void 0?{timeout:e.timeout}:{},...e.memory!==void 0?{memory:e.memory}:{},...e.handler!==void 0?{handler:e.handler}:{},...e.runtime!==void 0?{runtime:e.runtime}:{}};return u({...a,compute:[...a.compute,r]})}d(T,"addLambdaCompute");function E(a,e){const n={name:e.resourceName,defaultOriginRef:e.defaultOriginRef,...e.customDomain!==void 0?{customDomain:e.customDomain}:{},...e.certificateArn!==void 0?{certificateArn:e.certificateArn}:{},...e.domain!==void 0?{domain:e.domain}:{},...e.originHostname!==void 0?{originHostname:e.originHostname}:{},...e.behaviours&&e.behaviours.length>0?{behaviours:[...e.behaviours].map(r=>({pathPattern:r.pathPattern,originRef:r.originRef,...r.cachePolicy!==void 0?{cachePolicy:r.cachePolicy}:{}}))}:{}};return u({...a,cdn:n})}d(E,"addCdn");function P(a,e){const n=e.instanceType?{instanceType:e.instanceType}:{};return u({...a,tunnel:n})}d(P,"addTunnel");function S(a,e){const n=[...a.database.map(r=>r.name),...(a.clickhouse??[]).map(r=>r.name),...a.s3.map(r=>r.name),...a.compute.map(r=>r.name),...(a.dynamodb??[]).map(r=>r.name),...(a.sqs??[]).map(r=>r.name),...(a.additionalNetworks??[]).map(r=>r.name)];return a.cdn&&n.push(a.cdn.name),n.includes(e)}d(S,"isResourceNameTaken");function $(a){return`Resource name '${a}' is already used in this application.`}d($,"resourceNameTakenMessage");function f(a,e){return a.database.some(n=>n.name===e)||a.s3.some(n=>n.name===e)||a.compute.some(n=>n.name===e)||(a.dynamodb??[]).some(n=>n.name===e)||(a.sqs??[]).some(n=>n.name===e)}d(f,"resourceExistsInPlan");function o(a,e,n,r){r.connectToCompute&&r.connectToCompute.length>0&&y(a,[...r.connectToCompute],e,n),r.connectToServices&&r.connectToServices.length>0&&g(a,[...r.connectToServices],e,n)}d(o,"applyConnections");export{O as addResourceToPlan,S as isResourceNameTaken,z as listAvailableResources,$ as resourceNameTakenMessage,w as validateResourceAddition};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Compute — the last scaffold-emitted type to graduate from `emitGuard`.
3
+ *
4
+ * Every entry here replaces a guard rule that REFUSED, with a translation
5
+ * that EMITS, and the disagreements are carried over from what was actually
6
+ * observed at the constructs (file:line evidence in the increment's report):
7
+ *
8
+ * - `memory`→`memorySize`, `ssmSecrets`→`secrets`: plain renames the guard
9
+ * used to refuse as silently-dropped keys.
10
+ * - `codePath`→`code: Code.fromAsset(...)`, `runtime`→`Runtime.<member>`,
11
+ * `architecture`→`Architecture.<member>`, `functionUrl.authType`→
12
+ * `FunctionUrlAuthType.<member>`: CDK values a literal cannot carry,
13
+ * expressible since structured rules exist.
14
+ * - `services[].scaling.scalingType`→`ScalingType.<member>`: a STRING
15
+ * scaling type is read by `addServiceAutoScaling` via enum comparison, so
16
+ * `"MEMORY"` written as a string silently scales on CPU — the member
17
+ * emission is the only shape the construct actually switches on.
18
+ * - `scheduleExpression` expands into a second statement
19
+ * (`app.addSchedule(...)`) through the sibling projection; the connection
20
+ * keys expand into shared `environment`/`secretsImport`/`connections`
21
+ * props through the fragment expansion, consuming the same
22
+ * `connectionWiring.ts` vocabulary both existing emission lanes use.
23
+ *
24
+ * The construct-default contract matters throughout: `handler` and `runtime`
25
+ * both default in the construct (`props.handler || COMPUTE_DEFAULTS...`,
26
+ * computeLambda.ts:428-429), so a code-deployed Lambda REQUIRES only its
27
+ * `codePath` — refusing a missing handler or runtime would refuse statements
28
+ * the construct deploys correctly.
29
+ */
30
+ import type { TypeProjection } from "./types.js";
31
+ export declare const compute: TypeProjection;
@@ -0,0 +1 @@
1
+ var S=Object.defineProperty;var t=(e,n)=>S(e,"name",{value:n,configurable:!0});import{connectionEnvSuffix as x}from"../generation/common.js";import{buildConnectionWiringEntries as C,CONNECTION_TYPE_ORDER as T,DATABASE_ACCESSORS as v}from"../generation/connectionWiring.js";import{getArchitectureForInstanceType as j}from"../schemas/instanceTypeArchitecture.js";import{roundTripKeys as R}from"./roundTripKeys.js";const b=/^[A-Za-z_$][A-Za-z0-9_$]*$/;function y(e,n){return{kind:"member",object:{kind:"identifier",name:e},property:n}}t(y,"memberOf");function h(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}t(h,"isPlainRecord");function m(e){return Array.isArray(e)?{kind:"array",elements:e.map(m)}:h(e)?{kind:"object",entries:Object.entries(e).filter(([,n])=>n!==void 0).map(([n,r])=>({key:n,value:m(r)}))}:{kind:"literal",value:e}}t(m,"toStructuredLiteral");function O(e){if(!Array.isArray(e))return{expression:m(e)};let n=!1;const r=[];for(const p of e){if(!h(p))return{expression:m(e)};const i=[];for(const[o,c]of Object.entries(p)){if(c===void 0)continue;if(o!=="scaling"||!h(c)){i.push({key:o,value:m(c)});continue}const d=[];for(const[l,a]of Object.entries(c))if(a!==void 0){if(l==="scalingType"&&typeof a=="string"&&b.test(a)){n=!0,d.push({key:l,value:y("ScalingType",a)});continue}d.push({key:l,value:m(a)})}i.push({key:o,value:{kind:"object",entries:d}})}r.push({kind:"object",entries:i})}return{expression:{kind:"array",elements:r},...n&&{imports:["ScalingType"]}}}t(O,"buildServicesBinding");function D(e){return h(e)&&Object.keys(e).length===1&&typeof e.authType=="string"&&b.test(e.authType)?{expression:{kind:"object",entries:[{key:"authType",value:y("FunctionUrlAuthType",e.authType)}]},imports:["FunctionUrlAuthType"]}:{expression:m(e)}}t(D,"buildFunctionUrlBinding");const M=[{property:"deployment",reason:"a Lambda needs a deployment mode: pass `deployment=container` (the image carries code and runtime) or `deployment=code` with a `codePath` for `Code.fromAsset(...)`.",refuseWhen:t(e=>e.type==="lambda"&&e.deployment===void 0&&e.code===void 0,"refuseWhen")},{property:"codePath",reason:"a container Lambda takes its code from the image, so `codePath` is never read \u2014 drop it, or use `deployment=code`.",refuseWhen:t(e=>e.deployment==="container"&&e.codePath!==void 0,"refuseWhen")},{property:"handler",reason:"a container Lambda takes its handler from the image (`Handler.FROM_IMAGE`), so `handler` is never read \u2014 drop it, or use `deployment=code`.",refuseWhen:t(e=>e.deployment==="container"&&e.handler!==void 0,"refuseWhen")},{property:"runtime",reason:"a container Lambda takes its runtime from the image (`Runtime.FROM_IMAGE`), so `runtime` is never read \u2014 drop it, or use `deployment=code`.",refuseWhen:t(e=>e.deployment==="container"&&e.runtime!==void 0,"refuseWhen")},{property:"codePath",reason:"`deployment=code` needs a `codePath` for `Code.fromAsset(...)`: without one the statement takes the whole app's synth down with `Cannot read properties of undefined (reading 'bind')` \u2014 naming no resource. Pass `codePath=<dir>`, or use `deployment=container`.",refuseWhen:t(e=>e.deployment==="code"&&e.code===void 0&&e.codePath===void 0,"refuseWhen")},{property:"scheduleExpression",reason:"`scheduleExpression` expands into an `app.addSchedule(...)` statement targeting this compute, and only a Lambda is a schedule target \u2014 drop it, or use `type=lambda`.",refuseWhen:t(e=>e.scheduleExpression!==void 0&&typeof e.type=="string"&&e.type!=="lambda","refuseWhen")},{property:"services",reason:'an x86 instance type mismatches the default linux/arm64 (Graviton) Docker build, so the service would pull images the instance cannot run. Use a Graviton instance type (t4g, c6g, r6g, m6g, \u2026), or set `amiHardwareType: "STANDARD"` on that service\'s `ec2Config` to acknowledge x86.',refuseWhen:t(e=>e.type==="ecs"&&Array.isArray(e.services)&&e.services.some(n=>{if(!h(n))return!1;const r=n.ec2Config;return!h(r)||typeof r.instanceType!="string"||r.instanceType===""||r.amiHardwareType!==void 0?!1:j(r.instanceType)!=="ARM"}),"refuseWhen")},{property:"architecture",reason:"`X86_64` on a container Lambda mismatches the default linux/arm64 Docker build. Use `ARM_64` (recommended), or author the statement by hand with a build pipeline that targets linux/amd64.",refuseWhen:t(e=>e.type==="lambda"&&e.deployment==="container"&&e.architecture==="X86_64","refuseWhen")}];function P(e,n){const r=e.scheduleExpression;return typeof r!="string"?{siblings:[],unprojectable:[]}:typeof e.type=="string"&&e.type!=="lambda"?{siblings:[],unprojectable:[{key:"scheduleExpression",reason:"`scheduleExpression` expands into an `app.addSchedule(...)` statement targeting this compute, and only a Lambda is a schedule target.",kind:"cross-key"}]}:n.resourceName===void 0?{siblings:[],unprojectable:[{key:"scheduleExpression",reason:"`scheduleExpression` expands into an `app.addSchedule(...)` statement whose construct id derives from the resource name, and this caller supplied none.",kind:"missing-context"}]}:{siblings:[{planKey:"scheduleExpression",constructId:`${n.resourceName}Schedule`,appMethod:"addSchedule",props:[{key:"schedule",value:{kind:"literal",value:r}},{key:"target",value:{kind:"structured",expression:{kind:"primary-binding"}}},{key:"stackPlacement",value:{kind:"literal",value:"compute"}}]}],unprojectable:[]}}t(P,"deriveScheduleSibling");const K={database:"connectedDatabase",storage:"connectedStorage",messaging:"connectedMessaging"};function N(e){const n=[],r=[];for(const p of T){const i=K[p],o=e[i];if(!Array.isArray(o)||o.length===0)continue;const c=o.filter(d=>typeof d=="string"&&d.length>0);if(c.length!==o.length){const l=typeof o.find(a=>typeof a!="string"||a.length===0)=="string"?'the empty string ""':"not a string";r.push({key:i,reason:`\`${i}\` lists sibling resources by name and one element is ${l} \u2014 nothing can be wired to a nameless resource, and dropping the element would deploy the compute with the requested wiring silently missing. Replace the element with the resource's name, or drop it.`,kind:"unresolved-binding"});continue}n.push({planKey:i,resourceType:p,names:c})}return{requests:n,unprojectable:r}}t(N,"readConnectionRequests");function _(e,n){switch(e.kind){case"accessor":return{kind:"call",callee:{kind:"member",object:{kind:"identifier",name:n},property:e.method},args:[]};case"credential":return{kind:"call",callee:{kind:"member",object:{kind:"call",callee:{kind:"member",object:{kind:"identifier",name:n},property:v.CREDENTIALS},args:[]},property:v.IMPORT},args:[{kind:"literal",value:e.credentialKey}]};case"literal":return{kind:"literal",value:e.value}}}t(_,"wiringValueToStructured");function g(e,n,r){return{props:[],unprojectable:[{key:e,reason:n,kind:r}]}}t(g,"expansionRefusal");function I(e,n){const{requests:r,unprojectable:p}=N(e);if(p.length>0)return{props:[],unprojectable:p};const i=h(e.environment)?e.environment:void 0;if(r.length===0)return{props:i!==void 0?[{key:"environment",value:{kind:"literal",value:i}}]:[],unprojectable:[]};const[o]=r;if(o===void 0)return{props:[],unprojectable:[]};if(n.editingExisting===!0)return g(o.planKey,"connection keys rebuild the statement's `environment`, `secretsImport` and `connections` props wholesale, which an edit to an existing compute cannot do safely. Wire the connection when creating the compute (`fjall add compute \u2026 connectedDatabase=<Name>`), add it from the resource's own side (`fjall add <database|storage|messaging>` connecting to this compute's services), or author the wiring in infrastructure.ts by hand.","cross-key");if(typeof e.type=="string"&&e.type!=="lambda")return g(o.planKey,"top-level connection wiring is a Lambda shape (`environment`/`secretsImport`/`connections` are Lambda construct props); an ECS cluster wires connections per SERVICE \u2014 add the resource from its own side (`fjall add <database|storage|messaging>` connecting to the services), or author the per-service wiring by hand.","cross-key");if(r.some(s=>s.resourceType==="database")&&e.needsConnection!==!0)return g("connectedDatabase","`connectedDatabase` wires only when `needsConnection` is true \u2014 database wiring is gated on it (storage and messaging wiring are not). Pass `needsConnection=true` alongside `connectedDatabase`.","cross-key");const c=[];for(const s of r){const u=n.resolveBindings?.(s.names,s.planKey);if(u===void 0)return g(s.planKey,`\`${s.planKey}\` names planned sibling resources and the wiring reads live bindings in their place; no unique ${s.resourceType} binding could be resolved for every listed name in this file.`,"unresolved-binding");c.push({request:s,variables:[...u]})}const d=new Map,l=[];for(const{request:s,variables:u}of c)u.forEach((w,E)=>{const A=x(E);for(const f of C(s.resourceType,A)){const k=_(f.value,w);f.target==="secretsImport"?l.push({key:f.key,value:k}):d.set(f.key,k)}});if(i!==void 0)for(const[s,u]of Object.entries(i))u!==void 0&&d.set(s,{kind:"literal",value:u});const a=[{key:"environment",value:{kind:"structured",expression:{kind:"object",entries:[...d].map(([s,u])=>({key:s,value:u}))}}}];return l.length>0&&a.push({key:"secretsImport",value:{kind:"structured",expression:{kind:"object",entries:l}}}),a.push({key:"connections",value:{kind:"structured",expression:{kind:"array",elements:c.flatMap(({variables:s})=>s.map(u=>({kind:"identifier",name:u})))}}}),{props:a,unprojectable:[]}}t(I,"deriveConnectionExpansion");const $={keys:{memory:{kind:"prop",as:"memorySize"},ssmSecrets:{kind:"prop",as:"secrets"},codePath:{kind:"structured",as:"code",reason:"`codePath` becomes `code: Code.fromAsset(<dir>)` and needs a non-empty directory path; nothing else can feed `Code.fromAsset`.",build:t(e=>typeof e=="string"&&e.length>0?{expression:{kind:"call",callee:y("Code","fromAsset"),args:[{kind:"literal",value:e}]},imports:["Code"]}:void 0,"build")},runtime:{kind:"structured",reason:"the construct reads a CDK `Runtime` member, so pass the MEMBER name (`NODEJS_22_X`), not a version string: `nodejs20.x` passes the plan schema but no `Runtime.<member>` expression can carry it.",build:t(e=>typeof e=="string"&&b.test(e)?{expression:y("Runtime",e),imports:["Runtime"]}:void 0,"build")},architecture:{kind:"structured",reason:"the construct reads a CDK `Architecture` member (`ARM_64`, `X86_64`); a value that is not a member name would emit an EMPTY `Architectures` list where omitting the key yields the correct default.",build:t(e=>typeof e=="string"&&b.test(e)?{expression:y("Architecture",e),imports:["Architecture"]}:void 0,"build")},functionUrl:{kind:"structured",reason:"`functionUrl.authType` is a CDK `FunctionUrlAuthType` member; the emitted prop is `{ authType: FunctionUrlAuthType.<member> }`.",build:t(e=>D(e),"build")},services:{kind:"structured",reason:"`services[].scaling.scalingType` is a CDK `ScalingType` member: written as a string it silently scales on CPU whatever was asked, so the array is re-emitted with `ScalingType.<member>` accesses.",build:t(e=>O(e),"build")},enableSSH:{kind:"transform",as:"ssh",apply:t(e=>e===!0?{}:!1,"apply")},secrets:{kind:"planOnly",reason:"the plan's `secrets` RECORD has no construct slot: the Lambda construct reads `secrets` as a string ARRAY of SSM names (the plan's `ssmSecrets`), and ECS secrets live per service \u2014 a record here lands inert and the function deploys without those secrets."},eventSources:{kind:"planOnly",reason:"zero `props.eventSources` reads exist across @fjall/components-infrastructure \u2014 the array lands inert and no event source mapping is created."},functionName:{kind:"planOnly",reason:"the Lambda construct hardcodes `functionName: id` (its construct id), so an override is never read and the function keeps the id-derived name."},keyName:{kind:"planOnly",reason:"the EC2 construct reads only the `ssh` prop's presence; `keyName` is never forwarded, so the instance launches without the named key pair."},userData:{kind:"planOnly",reason:"the EC2 construct wants a live CDK `UserData` object; a plan string is never read, so the instance boots without the requested user data."},securityGroups:{kind:"planOnly",reason:"no EC2 construct prop reads `securityGroups`; the instance deploys with the construct's own groups and the listed ones are never attached."},alarms:{kind:"planOnly",reason:"no construct reads a top-level `alarms`: ECS alarm thresholds live per service (`services[].alarms`) and the Lambda construct reads no alarm config at all, so the thresholds land inert."},...R},crossKey:M,siblings:{keys:["scheduleExpression"],derive:P},expansion:{keys:["needsConnection","connectedDatabase","connectedStorage","connectedMessaging","environment"],derive:I},constructKeyAliases:{memorySize:["memory"],description:["lambdaDescription"],secrets:["ssmSecrets"],secretsImport:["containerSecretsImport"]}};export{$ as compute};