@fjall/generator 7.3.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/.build-source-hash +28 -21
  2. package/dist/.minified +1 -1
  3. package/dist/src/ast/domain/astDomainParser.d.ts +2 -0
  4. package/dist/src/ast/domain/astDomainParser.js +1 -1
  5. package/dist/src/codemod/drift/snapshot.js +1 -1
  6. package/dist/src/codemod/edits/appendAccountToStage.js +1 -1
  7. package/dist/src/codemod/edits/computeServiceLocator.d.ts +65 -0
  8. package/dist/src/codemod/edits/computeServiceLocator.js +1 -0
  9. package/dist/src/codemod/edits/connectResourceToCompute.d.ts +65 -0
  10. package/dist/src/codemod/edits/connectResourceToCompute.js +1 -0
  11. package/dist/src/codemod/edits/modifyResource.js +1 -1
  12. package/dist/src/codemod/edits/moduleConstResolver.d.ts +25 -0
  13. package/dist/src/codemod/edits/moduleConstResolver.js +1 -0
  14. package/dist/src/codemod/edits/objectGraph.d.ts +34 -0
  15. package/dist/src/codemod/edits/objectGraph.js +1 -0
  16. package/dist/src/codemod/edits/secretsProvability.d.ts +48 -0
  17. package/dist/src/codemod/edits/secretsProvability.js +1 -0
  18. package/dist/src/codemod/edits/setContainerSecrets.d.ts +55 -0
  19. package/dist/src/codemod/edits/setContainerSecrets.js +1 -0
  20. package/dist/src/codemod/index.d.ts +2 -0
  21. package/dist/src/codemod/index.js +1 -1
  22. package/dist/src/codemod/registry.d.ts +1 -2
  23. package/dist/src/codemod/registry.js +1 -1
  24. package/dist/src/codemod/types.d.ts +9 -1
  25. package/dist/src/codemod/types.js +1 -1
  26. package/dist/src/dns/bindParser.js +2 -2
  27. package/dist/src/dns/bindWriter.js +2 -2
  28. package/dist/src/dns/domainRecords.d.ts +4 -0
  29. package/dist/src/dns/domainRecords.js +1 -1
  30. package/dist/src/generation/common.d.ts +15 -0
  31. package/dist/src/generation/common.js +6 -6
  32. package/dist/src/generation/database.d.ts +20 -0
  33. package/dist/src/generation/database.js +18 -18
  34. package/dist/src/generation/messagingConnections.js +1 -1
  35. package/dist/src/generation/storageConnections.d.ts +9 -0
  36. package/dist/src/generation/storageConnections.js +1 -1
  37. package/dist/src/planning/index.d.ts +2 -1
  38. package/dist/src/planning/index.js +1 -1
  39. package/dist/src/planning/planBuilders.d.ts +48 -0
  40. package/dist/src/planning/planBuilders.js +1 -0
  41. package/dist/src/planning/resourceAddition.d.ts +3 -0
  42. package/dist/src/planning/resourceAddition.js +1 -1
  43. package/dist/src/version.d.ts +1 -1
  44. package/dist/src/version.js +1 -1
  45. package/package.json +2 -2
@@ -9,10 +9,10 @@
9
9
  "package.json",
10
10
  "tsconfig.json"
11
11
  ],
12
- "hash": "940dd689f74de4aba85a336a7c2c2f48358a0b9740fabec971c03be2294e0714",
12
+ "hash": "ad0983e8acdd6ab00f35788c1a68734a2a72ae29e370dc810e7d1c4491996315",
13
13
  "files": {
14
14
  "src/ast/astTestHelpers.ts": "026cac849eb88bdb",
15
- "src/ast/domain/astDomainParser.ts": "bac0b16eb2e62552",
15
+ "src/ast/domain/astDomainParser.ts": "940ce5742507477d",
16
16
  "src/ast/index.ts": "502a507c3764acbf",
17
17
  "src/ast/mutation/astCodeInjection.ts": "c1ebf483fb1e2332",
18
18
  "src/ast/mutation/astExpressionEvaluator.ts": "6082789268b91212",
@@ -39,24 +39,30 @@
39
39
  "src/codemod/drift/detect.ts": "af3fb518a9d7165d",
40
40
  "src/codemod/drift/index.ts": "e87e1ced35eefa44",
41
41
  "src/codemod/drift/merge.ts": "29093929befa9abd",
42
- "src/codemod/drift/snapshot.ts": "f8ef6b4097aa3d10",
42
+ "src/codemod/drift/snapshot.ts": "d3c70df4f8537237",
43
43
  "src/codemod/drift/types.ts": "7f1d7899e420e4d7",
44
44
  "src/codemod/edits/addResource.ts": "c8fe476d5ef589fe",
45
45
  "src/codemod/edits/addResource/appBinding.ts": "3553fdb30fe06335",
46
46
  "src/codemod/edits/addResource/bodyIndex.ts": "3e179eac10d7bcf4",
47
47
  "src/codemod/edits/addResource/propertyBuilder.ts": "9102dff7e9fab376",
48
- "src/codemod/edits/appendAccountToStage.ts": "2b92f93734497303",
48
+ "src/codemod/edits/appendAccountToStage.ts": "1796d909fa3ef79d",
49
+ "src/codemod/edits/computeServiceLocator.ts": "7f86483d9a35e053",
50
+ "src/codemod/edits/connectResourceToCompute.ts": "7e90a6fbfb07c630",
49
51
  "src/codemod/edits/controlFlowPolicy.ts": "e32bbe2894f76c65",
50
52
  "src/codemod/edits/crossPlanConnection.ts": "54a4ecb7b3368160",
51
53
  "src/codemod/edits/driftPolicy.ts": "5d9b7bb3505f987d",
52
54
  "src/codemod/edits/ensureImports.ts": "3ca0b6d446c4333c",
53
55
  "src/codemod/edits/findInsertionPosition.ts": "20cd34fdcf781017",
54
56
  "src/codemod/edits/index.ts": "bea5ed7c3983342b",
55
- "src/codemod/edits/modifyResource.ts": "8f19d8c272c2613e",
57
+ "src/codemod/edits/modifyResource.ts": "c27380cf9dae5dfc",
56
58
  "src/codemod/edits/modifyResource/literalConversion.ts": "31295cccd59131b7",
59
+ "src/codemod/edits/moduleConstResolver.ts": "85a8597427849a80",
60
+ "src/codemod/edits/objectGraph.ts": "5efc4181547237f8",
57
61
  "src/codemod/edits/removeResource.ts": "2c7c8fe67bc3a866",
58
62
  "src/codemod/edits/removeResource/commentHeuristic.ts": "90b6ce7ba5aa2a48",
59
63
  "src/codemod/edits/removeResource/importPruning.ts": "f22783108b40f6cb",
64
+ "src/codemod/edits/secretsProvability.ts": "d723283918e31efd",
65
+ "src/codemod/edits/setContainerSecrets.ts": "24478c4205e79cbd",
60
66
  "src/codemod/edits/unmanagedShapeErrors.ts": "47a2644913c8e619",
61
67
  "src/codemod/edits/vpcPeer.ts": "0bcf90c2e6d16ca4",
62
68
  "src/codemod/edits/vpcPeerAccepter.ts": "c9eace933e9e2345",
@@ -68,7 +74,7 @@
68
74
  "src/codemod/fileRewriter/parse.ts": "b12026c31562a13c",
69
75
  "src/codemod/fileRewriter/print.ts": "f5ff7afb5b7786bf",
70
76
  "src/codemod/historyPaths.ts": "ef8084013146db57",
71
- "src/codemod/index.ts": "6d786ef76a61fdc6",
77
+ "src/codemod/index.ts": "db90315eab333aab",
72
78
  "src/codemod/listResources.ts": "97f206a50edbea20",
73
79
  "src/codemod/llmFallback/apply.ts": "2e656a6e55b3b4e3",
74
80
  "src/codemod/llmFallback/claudeTier.ts": "0a37fe782c85f75b",
@@ -83,7 +89,7 @@
83
89
  "src/codemod/llmFallback/telemetryEvents.ts": "33a85939739693ab",
84
90
  "src/codemod/llmFallback/tierRunner.ts": "a26094accd78cf15",
85
91
  "src/codemod/llmFallback/types.ts": "14af8d2bd9afae12",
86
- "src/codemod/registry.ts": "bb0d629f33e5bf59",
92
+ "src/codemod/registry.ts": "e4c9ae5ccc782b7f",
87
93
  "src/codemod/semanticIndex/classifyControlFlow.ts": "ed96215d91a3cae3",
88
94
  "src/codemod/semanticIndex/findReferences.ts": "96aea37418d1e91a",
89
95
  "src/codemod/semanticIndex/index.ts": "cfcd212d34ab20fb",
@@ -92,7 +98,7 @@
92
98
  "src/codemod/semanticIndex/projectCache.ts": "dfd9b265c9d233c9",
93
99
  "src/codemod/semanticIndex/resolveConstructByLiteralProperty.ts": "2d013a330af15c5c",
94
100
  "src/codemod/telemetry/errorKinds.ts": "66c736abfa8b3a67",
95
- "src/codemod/types.ts": "4097b650c1bde13a",
101
+ "src/codemod/types.ts": "0cd929df5bb46696",
96
102
  "src/codemod/validationGate/gates/classify.ts": "edb92a1f7a2d9aeb",
97
103
  "src/codemod/validationGate/gates/drift.ts": "bd603a216fbb91a9",
98
104
  "src/codemod/validationGate/gates/locate.ts": "2c186c32edbb97ce",
@@ -101,30 +107,31 @@
101
107
  "src/codemod/validationGate/index.ts": "df5754bea9070410",
102
108
  "src/codemod/validationGate/types.ts": "af466ee5f3433042",
103
109
  "src/detection/index.ts": "b4ad9a935564cb3e",
104
- "src/dns/bindParser.ts": "a5371cd1fa781ce6",
105
- "src/dns/bindWriter.ts": "634b96dd15ee94b2",
110
+ "src/dns/bindParser.ts": "376d274bf9e4bf9f",
111
+ "src/dns/bindWriter.ts": "c296911ce5aef77c",
106
112
  "src/dns/domainFileGenerator.ts": "83451c031d3ed79c",
107
- "src/dns/domainRecords.ts": "17f895ff9a7b719b",
113
+ "src/dns/domainRecords.ts": "ab917006b92ae916",
108
114
  "src/dns/index.ts": "b476ef3d7b381dc8",
109
115
  "src/dns/types.ts": "82d6db9d7d26dbc2",
110
- "src/generation/common.ts": "73fa0ad5ffeeeed4",
116
+ "src/generation/common.ts": "ab66eac580bc227f",
111
117
  "src/generation/compute.ts": "4029a0d8e3197686",
112
118
  "src/generation/compute/ec2.ts": "4d8187d293a57fb1",
113
119
  "src/generation/compute/ecs.ts": "72190132fdaa1847",
114
120
  "src/generation/compute/lambda.ts": "4f5e31080941b83a",
115
121
  "src/generation/compute/shared.ts": "3724d4bfe92cfcb7",
116
- "src/generation/database.ts": "a28f791f0f028343",
122
+ "src/generation/database.ts": "dd4a1540986ad350",
117
123
  "src/generation/generatePatternCode.ts": "de16f42105a45358",
118
124
  "src/generation/index.ts": "fd58a833e13bcf07",
119
125
  "src/generation/infrastructure.ts": "6381d502f4733926",
120
- "src/generation/messagingConnections.ts": "1f070088c39e9749",
126
+ "src/generation/messagingConnections.ts": "fef976a8261c6751",
121
127
  "src/generation/storage.ts": "2c0171aeeec3d79e",
122
- "src/generation/storageConnections.ts": "db1ab6ccdc19afab",
128
+ "src/generation/storageConnections.ts": "a4020c9d6c36dc3f",
123
129
  "src/index.ts": "fc8f27b8ffade9ef",
124
130
  "src/planning/generateResourceChange.ts": "1c6411f9a12e7acb",
125
- "src/planning/index.ts": "64c4a88a38e9956d",
131
+ "src/planning/index.ts": "8ef807b31c43310c",
126
132
  "src/planning/openNextPlanning.ts": "4af9cb9061f7d21e",
127
- "src/planning/resourceAddition.ts": "45b010d2eaf96522",
133
+ "src/planning/planBuilders.ts": "bea93d0c05caef21",
134
+ "src/planning/resourceAddition.ts": "ba27203af283d840",
128
135
  "src/planning/resourceConnections.ts": "a6b7db8f733e560f",
129
136
  "src/planning/resourcePlanning.ts": "6c966fe586fff080",
130
137
  "src/planning/staticSitePlanning.ts": "242af1e9618821ab",
@@ -162,11 +169,11 @@
162
169
  "src/validation/patterns.ts": "f9629eafdad7ac3e",
163
170
  "src/validation/validationMessages.ts": "c727ade4690274f4",
164
171
  "src/validation/validationPatterns.ts": "865f3d688975b7c8",
165
- "src/version.ts": "cb82d9efdb80e56a",
172
+ "src/version.ts": "27d242fcf04ce64a",
166
173
  "../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
167
- "package.json": "7b8ea09642d00081",
174
+ "package.json": "8ff7f2a2605bff3a",
168
175
  "tsconfig.json": "1929cf3f99fe9b1e"
169
176
  },
170
- "outputHash": "fbeb7c7236155acb29d05407d96d62c5e210f2478b90d1809a51fc9c2c96cd02",
171
- "outputFileCount": 305
177
+ "outputHash": "764ac0887b73972f66e833ef1670b1225c82080d76940e2dc6781c0a873419f0",
178
+ "outputFileCount": 319
172
179
  }
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 152 files minified at 2026-08-06T23:10:36.463Z
1
+ 159 files minified at 2026-08-09T10:17:00.891Z
@@ -27,6 +27,8 @@ export interface DomainCallMatch {
27
27
  export type ParsedFjallTarget = {
28
28
  readonly kind: "ecs";
29
29
  readonly appName: string;
30
+ /** Second `fjallApp` argument — present only for a multi-ALB app. */
31
+ readonly computeName?: string;
30
32
  } | {
31
33
  readonly kind: "cdn";
32
34
  readonly appName: string;
@@ -1 +1 @@
1
- var R=Object.defineProperty;var u=(n,e)=>R(n,"name",{value:e,configurable:!0});import*as m from"typescript";import{parseObjectLiteral as T,asString as c,asStringUnion as _,asStringArray as y,asBoolean as b,asNumber as $,isCallRef as E,isParsedObject as g}from"../parsers/common/astCommonParser.js";import{success as l,failure as a}from"../../types/Result.js";import{DnsRecordTypeSchema as L}from"../../dns/types.js";import{DomainRegistrarSchema as j,DomainDeployPhaseSchema as Z,AliasRecordTypeSchema as O,TYPED_FJALL_TARGET_KINDS as C}from"../../dns/domainRecords.js";const N=j.options,x=Z.options,P=L.options,V=O.options;function ie(n){const e=[],t=u(i=>{if(m.isNewExpression(i)&&z(i.expression)){const d=F(i);d!==void 0&&e.push(d)}m.forEachChild(i,t)},"visit");if(t(n),e.length===0)return l(void 0);if(e.length>1)return a(new Error(`Expected exactly one 'new Domain(...)' call per infrastructure file, found ${e.length}`));const r=e[0];return r?l(r):l(void 0)}u(ie,"findDomainConstructCall");function z(n){return m.isIdentifier(n)&&n.text==="Domain"}u(z,"isDomainIdentifier");function F(n){const e=n.arguments;if(!e||e.length<3)return;const t=e[0],r=e[1],i=e[2];if(!t||!r||!i||!m.isObjectLiteralExpression(i))return;const d=M(n);if(d===void 0)return;const o=q(n),s=m.isStringLiteral(r)?r.text:void 0;return{callExpression:n,containingStatement:d,propsObjectLiteral:i,domainVarId:o,scopeArgumentText:t.getText(),constructIdLiteral:s}}u(F,"buildMatch");function M(n){let e=n;for(;e!==void 0;){if(m.isExpressionStatement(e)||m.isVariableStatement(e))return e;e=e.parent}}u(M,"findContainingTopLevelStatement");function q(n){let e=n.parent;for(;e!==void 0;){if(m.isVariableDeclaration(e)&&m.isIdentifier(e.name)&&e.initializer===n)return e.name.text;e=e.parent}}u(q,"extractDomainVarId");function B(n){switch(n.kind){case"registrar_required":return"'registrar' property is required";case"registrar_unsupported":return`'registrar' must be one of ${N.join(", ")}, got ${JSON.stringify(n.value)}`;case"missing_field":return`'${n.field}' property is required`;case"invalid_literal":return`'${n.field}' ${n.reason}`;case"removed_field":return`'${n.field}' was removed from the Domain API \u2014 ${n.cure}`}}u(B,"errorMessage");const J="declare the delegated child as its own Domain with registrar: 'external-delegated' and set 'parentDelegationRoleArn' (the CLI injects it via ManagedDomainBinding.delegationRoleArn); the child UPSERTs its NS records into the parent zone";function re(n){const e=T(n),t=_(e.registrar,N);if(t===void 0){const s=e.registrar;if(s===void 0)return a({kind:"registrar_required"});const f=typeof s=="string"?s:k(s);return a({kind:"registrar_unsupported",value:f})}const r=c(e.zoneName);if(r===void 0)return a({kind:"missing_field",field:"zoneName"});const i=U(e.records);if(!i.success)return i;const d=Q(e.certificates);if(!d.success)return d;if(e.delegations!==void 0)return a({kind:"removed_field",field:"delegations",cure:J});const o={zoneName:r,description:c(e.description),costAllocationEnvironment:c(e.costAllocationEnvironment),tags:W(e.tags),records:i.data,certificates:d.data};switch(t){case"route53":return l({...o,registrar:t,hostedZoneId:c(e.hostedZoneId)});case"external-delegated":{const s=c(e.delegatedSubdomain);if(s===void 0)return a({kind:"missing_field",field:"delegatedSubdomain"});const f=c(e.hostedZoneId);if(e.hostedZoneId!==void 0&&f===void 0)return a({kind:"invalid_literal",field:"hostedZoneId",reason:"must be a literal string zone id on external-delegated \u2014 dynamic expressions cannot be round-tripped"});const h=y(e.adoptedNameServers);if(e.adoptedNameServers!==void 0&&h===void 0)return a({kind:"invalid_literal",field:"adoptedNameServers",reason:"must be an array of literal NS hostname strings \u2014 the parent NS UPSERT writes them verbatim"});if(f===void 0!=(h===void 0))return a({kind:"invalid_literal",field:f===void 0?"hostedZoneId":"adoptedNameServers",reason:"adopting an existing child zone requires hostedZoneId and adoptedNameServers together (both-or-neither) \u2014 an imported zone exposes no name-server attribute at synth"});const S=c(e.parentDelegationRoleArn);if(e.parentDelegationRoleArn!==void 0&&S===void 0)return a({kind:"invalid_literal",field:"parentDelegationRoleArn",reason:"must be a literal string ARN (VD2-a) \u2014 the CLI injects it via ManagedDomainBinding.delegationRoleArn; dynamic expressions such as Fn.importValue are not supported"});const A=_(e.phase,x);return e.phase!==void 0&&A===void 0?a({kind:"invalid_literal",field:"phase",reason:`must be one of ${x.map(I=>`'${I}'`).join(", ")}`}):l({...o,registrar:t,delegatedSubdomain:s,hostedZoneId:f,adoptedNameServers:h,parentDelegationRoleArn:S,phase:A})}case"external-records":return l({...o,registrar:t})}}u(re,"parseDomainProps");function se(n){return B(n)}u(se,"parseDomainErrorMessage");function U(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"records",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const r=n[t];if(!g(r))return a({kind:"invalid_literal",field:`records[${t}]`,reason:"must be an object literal"});const i=G(r,t);if(!i.success)return i;e.push(i.data)}return l(e)}u(U,"parseRecordsArray");function G(n,e){const t=c(n.type),r=c(n.name);if(t===void 0)return a({kind:"missing_field",field:`records[${e}].type`});if(r===void 0)return a({kind:"missing_field",field:`records[${e}].name`});if(n.target!==void 0){if(!V.some(f=>f===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`alias records must have type 'A' or 'AAAA', got '${t}'`});const s=H(n.target);return l({kind:"alias",type:t,name:r,target:s})}if(!P.some(s=>s===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`unsupported record type '${t}'`});const i=Y(n.value);if(i===void 0)return a({kind:"invalid_literal",field:`records[${e}].value`,reason:`must be a string or array of strings (got ${JSON.stringify(n.value)})`});const d=$(n.ttl),o={kind:"standard",type:t,name:r,value:i,...d!==void 0?{ttl:d}:{}};return l(o)}u(G,"parseRecord");function Y(n){if(n===void 0)return;if(typeof n=="string")return n;const e=y(n);if(e!==void 0)return e}u(Y,"parseRecordValue");function H(n){if(E(n))return K(n);if(g(n)){const e=_(n.kind,C);if(e==="ecs"||e==="cdn"){const t=c(n.appName);if(t!==void 0)return{kind:e,appName:t}}if(e==="bucket"){const t=c(n.bucketName);if(t!==void 0)return{kind:e,bucketName:t}}if(e==="custom"){const t=c(n.dnsName),r=c(n.hostedZoneId);if(t!==void 0&&r!==void 0)return{kind:e,dnsName:t,hostedZoneId:r}}}return{kind:"unresolved",sourceText:k(n)}}u(H,"parseTarget");function K(n){const e=n.__call.trim(),t=e.match(/^([A-Za-z_][\w$]*)\s*\(([\s\S]*)\)\s*$/);if(!t)return{kind:"unresolved",sourceText:e};const r=t[1],i=t[2]??"",d=v(i);switch(r){case"fjallApp":{const o=p(d,0);return o===void 0?{kind:"dynamic",sourceText:e}:{kind:"ecs",appName:o}}case"fjallCdn":{const o=p(d,0);return o===void 0?{kind:"dynamic",sourceText:e}:{kind:"cdn",appName:o}}case"fjallBucket":{const o=p(d,0);return o===void 0?{kind:"dynamic",sourceText:e}:{kind:"bucket",bucketName:o}}case"aliasTo":{if(d.length>=2){const o=p(d,0),s=p(d,1);return o!==void 0&&s!==void 0?{kind:"custom",dnsName:o,hostedZoneId:s}:{kind:"dynamic",sourceText:e}}if(d.length===1){const o=d[0]?.trim()??"",s=D(o,"dnsName"),f=D(o,"hostedZoneId");return s!==void 0&&f!==void 0?{kind:"custom",dnsName:s,hostedZoneId:f}:{kind:"dynamic",sourceText:e}}return{kind:"unresolved",sourceText:e}}default:return{kind:"unresolved",sourceText:e}}}u(K,"resolveCallRefTarget");function v(n){const e=[];let t=0,r=null,i="";for(let o=0;o<n.length;o++){const s=n[o];if(r!==null){if(i+=s,s==="\\"&&o+1<n.length){const f=n[o+1];f!==void 0&&(i+=f,o+=1);continue}s===r&&(r=null);continue}if(s==='"'||s==="'"||s==="`"){r=s,i+=s;continue}if(s==="("||s==="{"||s==="["){t+=1,i+=s;continue}if(s===")"||s==="}"||s==="]"){t-=1,i+=s;continue}if(s===","&&t===0){e.push(i.trim()),i="";continue}i+=s}const d=i.trim();return d.length>0&&e.push(d),e}u(v,"splitTopLevelArgs");function p(n,e){const t=n[e];if(t===void 0)return;const r=t.trim();if(r.length<2)return;const i=r[0],d=r[r.length-1];if(i===d&&!(i!=='"'&&i!=="'"&&i!=="`"))return r.slice(1,-1)}u(p,"extractStringLiteralArg");function D(n,e){const t=n.trim().replace(/^\{|\}$/g,""),r=v(t);for(const i of r){const d=i.indexOf(":");if(d<0||i.slice(0,d).trim().replace(/["'`]/g,"")!==e)continue;const s=i.slice(d+1).trim();return p([s],0)}}u(D,"extractObjectFieldString");function Q(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"certificates",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const r=n[t];if(typeof r=="string"){e.push({domainName:r});continue}if(!g(r))return a({kind:"invalid_literal",field:`certificates[${t}]`,reason:"must be a string or object literal"});const i=c(r.domainName);if(i===void 0)return a({kind:"missing_field",field:`certificates[${t}].domainName`});const d=y(r.subjectAlternativeNames),o=b(r.transparencyLogging),s=b(r.cloudFront);if(r.cloudFront!==void 0&&s===void 0)return a({kind:"invalid_literal",field:`certificates[${t}].cloudFront`,reason:"must be a boolean literal \u2014 the CloudFront designation drives the zone-level us-east-1 export contract and cannot be round-tripped from a dynamic expression"});e.push({domainName:i,...d!==void 0?{subjectAlternativeNames:d}:{},...o!==void 0?{transparencyLogging:o}:{},...s!==void 0?{cloudFront:s}:{}})}return l(e)}u(Q,"parseCertificatesArray");function W(n){if(n===void 0||!g(n))return;const e={};for(const[t,r]of Object.entries(n)){const i=c(r);i!==void 0&&(e[t]=i)}return Object.keys(e).length===0?void 0:e}u(W,"parseStringRecord");function k(n){if(n===void 0)return"undefined";if(n===null)return"null";if(typeof n=="string")return JSON.stringify(n);if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return`[${n.map(e=>k(e)).join(", ")}]`;if(typeof n=="object"){if("__call"in n)return String(n.__call);if("__identifier"in n)return String(n.__identifier);if("__expression"in n)return String(n.__expression);if("__unknown"in n)return String(n.__unknown)}return String(n)}u(k,"stringifyParsedValue");export{ie as findDomainConstructCall,se as parseDomainErrorMessage,re as parseDomainProps,v as splitTopLevelArgs};
1
+ var R=Object.defineProperty;var u=(n,e)=>R(n,"name",{value:e,configurable:!0});import*as m from"typescript";import{parseObjectLiteral as T,asString as c,asStringUnion as k,asStringArray as y,asBoolean as b,asNumber as $,isCallRef as E,isParsedObject as g}from"../parsers/common/astCommonParser.js";import{success as l,failure as a}from"../../types/Result.js";import{DnsRecordTypeSchema as L}from"../../dns/types.js";import{DomainRegistrarSchema as j,DomainDeployPhaseSchema as Z,AliasRecordTypeSchema as O,TYPED_FJALL_TARGET_KINDS as C}from"../../dns/domainRecords.js";const N=j.options,x=Z.options,P=L.options,V=O.options;function ie(n){const e=[],t=u(r=>{if(m.isNewExpression(r)&&z(r.expression)){const d=F(r);d!==void 0&&e.push(d)}m.forEachChild(r,t)},"visit");if(t(n),e.length===0)return l(void 0);if(e.length>1)return a(new Error(`Expected exactly one 'new Domain(...)' call per infrastructure file, found ${e.length}`));const s=e[0];return s?l(s):l(void 0)}u(ie,"findDomainConstructCall");function z(n){return m.isIdentifier(n)&&n.text==="Domain"}u(z,"isDomainIdentifier");function F(n){const e=n.arguments;if(!e||e.length<3)return;const t=e[0],s=e[1],r=e[2];if(!t||!s||!r||!m.isObjectLiteralExpression(r))return;const d=M(n);if(d===void 0)return;const o=q(n),i=m.isStringLiteral(s)?s.text:void 0;return{callExpression:n,containingStatement:d,propsObjectLiteral:r,domainVarId:o,scopeArgumentText:t.getText(),constructIdLiteral:i}}u(F,"buildMatch");function M(n){let e=n;for(;e!==void 0;){if(m.isExpressionStatement(e)||m.isVariableStatement(e))return e;e=e.parent}}u(M,"findContainingTopLevelStatement");function q(n){let e=n.parent;for(;e!==void 0;){if(m.isVariableDeclaration(e)&&m.isIdentifier(e.name)&&e.initializer===n)return e.name.text;e=e.parent}}u(q,"extractDomainVarId");function B(n){switch(n.kind){case"registrar_required":return"'registrar' property is required";case"registrar_unsupported":return`'registrar' must be one of ${N.join(", ")}, got ${JSON.stringify(n.value)}`;case"missing_field":return`'${n.field}' property is required`;case"invalid_literal":return`'${n.field}' ${n.reason}`;case"removed_field":return`'${n.field}' was removed from the Domain API \u2014 ${n.cure}`}}u(B,"errorMessage");const J="declare the delegated child as its own Domain with registrar: 'external-delegated' and set 'parentDelegationRoleArn' (the CLI injects it via ManagedDomainBinding.delegationRoleArn); the child UPSERTs its NS records into the parent zone";function re(n){const e=T(n),t=k(e.registrar,N);if(t===void 0){const i=e.registrar;if(i===void 0)return a({kind:"registrar_required"});const f=typeof i=="string"?i:_(i);return a({kind:"registrar_unsupported",value:f})}const s=c(e.zoneName);if(s===void 0)return a({kind:"missing_field",field:"zoneName"});const r=U(e.records);if(!r.success)return r;const d=Q(e.certificates);if(!d.success)return d;if(e.delegations!==void 0)return a({kind:"removed_field",field:"delegations",cure:J});const o={zoneName:s,description:c(e.description),costAllocationEnvironment:c(e.costAllocationEnvironment),tags:W(e.tags),records:r.data,certificates:d.data};switch(t){case"route53":return l({...o,registrar:t,hostedZoneId:c(e.hostedZoneId)});case"external-delegated":{const i=c(e.delegatedSubdomain);if(i===void 0)return a({kind:"missing_field",field:"delegatedSubdomain"});const f=c(e.hostedZoneId);if(e.hostedZoneId!==void 0&&f===void 0)return a({kind:"invalid_literal",field:"hostedZoneId",reason:"must be a literal string zone id on external-delegated \u2014 dynamic expressions cannot be round-tripped"});const h=y(e.adoptedNameServers);if(e.adoptedNameServers!==void 0&&h===void 0)return a({kind:"invalid_literal",field:"adoptedNameServers",reason:"must be an array of literal NS hostname strings \u2014 the parent NS UPSERT writes them verbatim"});if(f===void 0!=(h===void 0))return a({kind:"invalid_literal",field:f===void 0?"hostedZoneId":"adoptedNameServers",reason:"adopting an existing child zone requires hostedZoneId and adoptedNameServers together (both-or-neither) \u2014 an imported zone exposes no name-server attribute at synth"});const S=c(e.parentDelegationRoleArn);if(e.parentDelegationRoleArn!==void 0&&S===void 0)return a({kind:"invalid_literal",field:"parentDelegationRoleArn",reason:"must be a literal string ARN (VD2-a) \u2014 the CLI injects it via ManagedDomainBinding.delegationRoleArn; dynamic expressions such as Fn.importValue are not supported"});const A=k(e.phase,x);return e.phase!==void 0&&A===void 0?a({kind:"invalid_literal",field:"phase",reason:`must be one of ${x.map(I=>`'${I}'`).join(", ")}`}):l({...o,registrar:t,delegatedSubdomain:i,hostedZoneId:f,adoptedNameServers:h,parentDelegationRoleArn:S,phase:A})}case"external-records":return l({...o,registrar:t})}}u(re,"parseDomainProps");function se(n){return B(n)}u(se,"parseDomainErrorMessage");function U(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"records",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const s=n[t];if(!g(s))return a({kind:"invalid_literal",field:`records[${t}]`,reason:"must be an object literal"});const r=G(s,t);if(!r.success)return r;e.push(r.data)}return l(e)}u(U,"parseRecordsArray");function G(n,e){const t=c(n.type),s=c(n.name);if(t===void 0)return a({kind:"missing_field",field:`records[${e}].type`});if(s===void 0)return a({kind:"missing_field",field:`records[${e}].name`});if(n.target!==void 0){if(!V.some(f=>f===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`alias records must have type 'A' or 'AAAA', got '${t}'`});const i=H(n.target);return l({kind:"alias",type:t,name:s,target:i})}if(!P.some(i=>i===t))return a({kind:"invalid_literal",field:`records[${e}]`,reason:`unsupported record type '${t}'`});const r=Y(n.value);if(r===void 0)return a({kind:"invalid_literal",field:`records[${e}].value`,reason:`must be a string or array of strings (got ${JSON.stringify(n.value)})`});const d=$(n.ttl),o={kind:"standard",type:t,name:s,value:r,...d!==void 0?{ttl:d}:{}};return l(o)}u(G,"parseRecord");function Y(n){if(n===void 0)return;if(typeof n=="string")return n;const e=y(n);if(e!==void 0)return e}u(Y,"parseRecordValue");function H(n){if(E(n))return K(n);if(g(n)){const e=k(n.kind,C);if(e==="ecs"||e==="cdn"){const t=c(n.appName);if(t!==void 0)return{kind:e,appName:t}}if(e==="bucket"){const t=c(n.bucketName);if(t!==void 0)return{kind:e,bucketName:t}}if(e==="custom"){const t=c(n.dnsName),s=c(n.hostedZoneId);if(t!==void 0&&s!==void 0)return{kind:e,dnsName:t,hostedZoneId:s}}}return{kind:"unresolved",sourceText:_(n)}}u(H,"parseTarget");function K(n){const e=n.__call.trim(),t=e.match(/^([A-Za-z_][\w$]*)\s*\(([\s\S]*)\)\s*$/);if(!t)return{kind:"unresolved",sourceText:e};const s=t[1],r=t[2]??"",d=v(r);switch(s){case"fjallApp":{const o=p(d,0);if(o===void 0)return{kind:"dynamic",sourceText:e};if(d.length<2)return{kind:"ecs",appName:o};const i=p(d,1);return i===void 0?{kind:"dynamic",sourceText:e}:{kind:"ecs",appName:o,computeName:i}}case"fjallCdn":{const o=p(d,0);return o===void 0?{kind:"dynamic",sourceText:e}:{kind:"cdn",appName:o}}case"fjallBucket":{const o=p(d,0);return o===void 0?{kind:"dynamic",sourceText:e}:{kind:"bucket",bucketName:o}}case"aliasTo":{if(d.length>=2){const o=p(d,0),i=p(d,1);return o!==void 0&&i!==void 0?{kind:"custom",dnsName:o,hostedZoneId:i}:{kind:"dynamic",sourceText:e}}if(d.length===1){const o=d[0]?.trim()??"",i=D(o,"dnsName"),f=D(o,"hostedZoneId");return i!==void 0&&f!==void 0?{kind:"custom",dnsName:i,hostedZoneId:f}:{kind:"dynamic",sourceText:e}}return{kind:"unresolved",sourceText:e}}default:return{kind:"unresolved",sourceText:e}}}u(K,"resolveCallRefTarget");function v(n){const e=[];let t=0,s=null,r="";for(let o=0;o<n.length;o++){const i=n[o];if(s!==null){if(r+=i,i==="\\"&&o+1<n.length){const f=n[o+1];f!==void 0&&(r+=f,o+=1);continue}i===s&&(s=null);continue}if(i==='"'||i==="'"||i==="`"){s=i,r+=i;continue}if(i==="("||i==="{"||i==="["){t+=1,r+=i;continue}if(i===")"||i==="}"||i==="]"){t-=1,r+=i;continue}if(i===","&&t===0){e.push(r.trim()),r="";continue}r+=i}const d=r.trim();return d.length>0&&e.push(d),e}u(v,"splitTopLevelArgs");function p(n,e){const t=n[e];if(t===void 0)return;const s=t.trim();if(s.length<2)return;const r=s[0],d=s[s.length-1];if(r===d&&!(r!=='"'&&r!=="'"&&r!=="`"))return s.slice(1,-1)}u(p,"extractStringLiteralArg");function D(n,e){const t=n.trim().replace(/^\{|\}$/g,""),s=v(t);for(const r of s){const d=r.indexOf(":");if(d<0||r.slice(0,d).trim().replace(/["'`]/g,"")!==e)continue;const i=r.slice(d+1).trim();return p([i],0)}}u(D,"extractObjectFieldString");function Q(n){if(n===void 0)return l([]);if(!Array.isArray(n))return a({kind:"invalid_literal",field:"certificates",reason:"must be an array"});const e=[];for(let t=0;t<n.length;t++){const s=n[t];if(typeof s=="string"){e.push({domainName:s});continue}if(!g(s))return a({kind:"invalid_literal",field:`certificates[${t}]`,reason:"must be a string or object literal"});const r=c(s.domainName);if(r===void 0)return a({kind:"missing_field",field:`certificates[${t}].domainName`});const d=y(s.subjectAlternativeNames),o=b(s.transparencyLogging),i=b(s.cloudFront);if(s.cloudFront!==void 0&&i===void 0)return a({kind:"invalid_literal",field:`certificates[${t}].cloudFront`,reason:"must be a boolean literal \u2014 the CloudFront designation drives the zone-level us-east-1 export contract and cannot be round-tripped from a dynamic expression"});e.push({domainName:r,...d!==void 0?{subjectAlternativeNames:d}:{},...o!==void 0?{transparencyLogging:o}:{},...i!==void 0?{cloudFront:i}:{}})}return l(e)}u(Q,"parseCertificatesArray");function W(n){if(n===void 0||!g(n))return;const e={};for(const[t,s]of Object.entries(n)){const r=c(s);r!==void 0&&(e[t]=r)}return Object.keys(e).length===0?void 0:e}u(W,"parseStringRecord");function _(n){if(n===void 0)return"undefined";if(n===null)return"null";if(typeof n=="string")return JSON.stringify(n);if(typeof n=="number"||typeof n=="boolean")return String(n);if(Array.isArray(n))return`[${n.map(e=>_(e)).join(", ")}]`;if(typeof n=="object"){if("__call"in n)return String(n.__call);if("__identifier"in n)return String(n.__identifier);if("__expression"in n)return String(n.__expression);if("__unknown"in n)return String(n.__unknown)}return String(n)}u(_,"stringifyParsedValue");export{ie as findDomainConstructCall,se as parseDomainErrorMessage,re as parseDomainProps,v as splitTopLevelArgs};
@@ -1 +1 @@
1
- var h=Object.defineProperty;var u=(r,t)=>h(r,"name",{value:t,configurable:!0});import{failure as d,success as g}from"../../types/Result.js";import{extractProgramBody as k,isRecord as m}from"../_internal.js";import{astToLiteral as b,isNodeShape as y,NON_LITERAL as E,readKeyName as x}from"../edits/modifyResource/literalConversion.js";import{parse as N}from"../fileRewriter/index.js";import{listResources as O}from"../listResources.js";import{STATEMENT_REGISTRY as j}from"../registry.js";function I(r,t,n){const e=O(r);if(!e.success)return d(e.error);const i=e.data.resources.find(o=>o.type===t&&o.name===n);if(i===void 0)return d({kind:"ResourceNotFoundError",type:t,name:n,knownNames:e.data.resources.filter(o=>o.type===t).map(o=>o.name)});const s=N(r,i.filePath);if(!s.success)return d(s.error);const c=k(s.data);if(c===void 0)return d({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=S(c,i);if(f===void 0)return d({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const a=new Set(Object.keys(j[t].schemaFragment.shape)),l={};for(const o of f.properties){if(o.type!=="Property"&&o.type!=="ObjectProperty"||o.shorthand===!0||o.computed===!0)continue;const p=x(o.key);p===void 0||!a.has(p)||o.value!==void 0&&(l[p]=v(o.value,r))}return g({type:t,name:n,properties:l,schemaVersion:1})}u(I,"snapshotProperties");function S(r,t){const n=t.start+t.length;let e;const i=u(s=>{if(e!==void 0||s.type!=="CallExpression")return;const c=s.arguments;if(!Array.isArray(c)||c.length<2)return;const f=c[0];if(!y(f)||f.type!=="StringLiteral"||f.start!==t.start||f.end!==n)return;const a=c[1];y(a)&&a.type==="ObjectExpression"&&(e=a)},"visitor");for(const s of r)if(P(s,i),e!==void 0)break;return e}u(S,"findConfigObject");function v(r,t){const n=b(r);return n!==E?n:A(r,t)}u(v,"extractPropertyValue");function A(r,t){const n=typeof r.start=="number"?r.start:void 0,e=typeof r.end=="number"?r.end:void 0;return{kind:"expression",text:n!==void 0&&e!==void 0&&n<e?t.slice(n,e):""}}u(A,"toExpressionValue");function P(r,t){const n=[r];for(;n.length>0;){const e=n.pop();if(m(e)){typeof e.type=="string"&&t(e);for(const i of Object.keys(e)){if(i==="loc"||i==="comments"||i==="tokens")continue;const s=e[i];if(Array.isArray(s))for(const c of s)m(c)&&n.push(c);else m(s)&&n.push(s)}}}}u(P,"visit");export{I as snapshotProperties};
1
+ var y=Object.defineProperty;var u=(e,r)=>y(e,"name",{value:r,configurable:!0});import{failure as d,success as h}from"../../types/Result.js";import{extractProgramBody as b}from"../_internal.js";import{astToLiteral as g,isNodeShape as l,NON_LITERAL as E,readKeyName as k}from"../edits/modifyResource/literalConversion.js";import{visit as x}from"../edits/objectGraph.js";import{parse as N}from"../fileRewriter/index.js";import{listResources as O}from"../listResources.js";import{STATEMENT_REGISTRY as S}from"../registry.js";function I(e,r,o){const n=O(e);if(!n.success)return d(n.error);const f=n.data.resources.find(t=>t.type===r&&t.name===o);if(f===void 0)return d({kind:"ResourceNotFoundError",type:r,name:o,knownNames:n.data.resources.filter(t=>t.type===r).map(t=>t.name)});const s=N(e,f.filePath);if(!s.success)return d(s.error);const i=b(s.data);if(i===void 0)return d({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const c=j(i,f);if(c===void 0)return d({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const a=new Set(Object.keys(S[r].schemaFragment.shape)),m={};for(const t of c.properties){if(t.type!=="Property"&&t.type!=="ObjectProperty"||t.shorthand===!0||t.computed===!0)continue;const p=k(t.key);p===void 0||!a.has(p)||t.value!==void 0&&(m[p]=P(t.value,e))}return h({type:r,name:o,properties:m,schemaVersion:1})}u(I,"snapshotProperties");function j(e,r){const o=r.start+r.length;let n;const f=u(s=>{if(n!==void 0||s.type!=="CallExpression")return;const i=s.arguments;if(!Array.isArray(i)||i.length<2)return;const c=i[0];if(!l(c)||c.type!=="StringLiteral"||c.start!==r.start||c.end!==o)return;const a=i[1];l(a)&&a.type==="ObjectExpression"&&(n=a)},"visitor");for(const s of e)if(x(s,f),n!==void 0)break;return n}u(j,"findConfigObject");function P(e,r){const o=g(e);return o!==E?o:T(e,r)}u(P,"extractPropertyValue");function T(e,r){const o=typeof e.start=="number"?e.start:void 0,n=typeof e.end=="number"?e.end:void 0;return{kind:"expression",text:o!==void 0&&n!==void 0&&o<n?r.slice(o,n):""}}u(T,"toExpressionValue");export{I as snapshotProperties};
@@ -1 +1 @@
1
- var T=Object.defineProperty;var u=(e,r)=>T(e,"name",{value:r,configurable:!0});import{failure as d,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as x,computeLinesDelta as k,extractProgramBody as b}from"../_internal.js";import{buildObjectProperty as h,detectQuoteStyle as D,parse as C,printFile as F}from"../fileRewriter/index.js";import{makeStringLiteral as L,toAstValue as w}from"./addResource/propertyBuilder.js";import{astToLiteral as I,isNodeShape as f,readKeyName as g}from"./modifyResource/literalConversion.js";const K="ACCOUNTS",O="workloads";function J(e,r){const n=r.filePath??x,t=r.constName??K,a=r.nestedKey??O,{stage:i,displayName:o}=r,s=C(e,n);if(!s.success)return d(s.error);const l=b(s.data);if(l===void 0)return d({kind:"InvalidStageTargetError",stage:i,reason:"recast File is missing program.body"});const m=$(l,t);if(m===void 0)return d({kind:"ConstNotFoundError",constName:t});const p=D(s.data),c=V(m,{constName:t,stage:i,nestedKey:a,displayName:o,quoteStyle:p});if(!c.success)return d(c.error);if(c.data.created)return P(s.data,e);const v=c.data.array;return v.elements.some(N=>f(N)&&I(N)===o)?y({content:e,linesChanged:{added:0,removed:0},skipped:!0}):(v.elements.push(L(o,p)),P(s.data,e))}u(J,"appendAccountToStage");function P(e,r){const n=F(e,r);return y({content:n,linesChanged:k(r,n)})}u(P,"printSuccess");function V(e,r){const{constName:n,stage:t,nestedKey:a,displayName:i,quoteStyle:o}=r,s=E(e,t);if(s!==void 0)return A(s.value)?y({created:!1,array:s.value}):d({kind:"InvalidStageTargetError",stage:t,reason:`Top-level "${t}" is not an array literal.`});const l=E(e,a);if(l!==void 0&&S(l.value)){const m=l.value,p=E(m,t);if(p!==void 0)return A(p.value)?y({created:!1,array:p.value}):d({kind:"InvalidStageTargetError",stage:t,reason:`Nested "${a}.${t}" is not an array literal.`});const c=_(m,t,i,o);return c.success?y({created:!0}):d(c.error)}return d({kind:"StageNotFoundError",constName:n,stage:t,knownStages:B(e,a)})}u(V,"resolveStageArray");function _(e,r,n,t){const a=w([n],t);if(a===void 0)return d({kind:"InvalidStageTargetError",stage:r,reason:`Unable to build an array literal for "${r}".`});const i=h(r,a,t);return e.properties[e.properties.length-1]?.extra?.trailingComma===!0&&(i.extra={...i.extra??{},trailingComma:!0}),e.properties.push(i),y(void 0)}u(_,"appendStageProperty");function $(e,r){for(const n of e){const t=U(n);if(t===void 0)continue;const a=t.declarations;if(Array.isArray(a))for(const i of a){if(!f(i)||i.type!=="VariableDeclarator")continue;const o=i.id,s=j(i.init);if(f(o)&&o.type==="Identifier"&&o.name===r&&S(s))return s}}}u($,"findConstObjectExpression");function U(e){if(e.type==="VariableDeclaration")return e;if(e.type==="ExportNamedDeclaration"){const r=e.declaration;if(f(r)&&r.type==="VariableDeclaration")return r}}u(U,"unwrapVariableDeclaration");function j(e){let r=e;for(;f(r)&&(r.type==="TSAsExpression"||r.type==="TSSatisfiesExpression");)r=r.expression;return r}u(j,"unwrapExpression");function E(e,r){return e.properties.find(n=>(n.type==="Property"||n.type==="ObjectProperty")&&n.shorthand!==!0&&n.computed!==!0&&g(n.key)===r)}u(E,"findPropertyByKey");function B(e,r){const n=[];for(const t of e.properties){if(t.type!=="Property"&&t.type!=="ObjectProperty")continue;const a=g(t.key);if(a!==void 0)if(a===r&&S(t.value))for(const i of t.value.properties){const o=g(i.key);o!==void 0&&n.push(`${r}.${o}`)}else A(t.value)&&n.push(a)}return n}u(B,"collectStageKeys");function S(e){return f(e)&&e.type==="ObjectExpression"&&Array.isArray(e.properties)}u(S,"isObjectExpression");function A(e){return f(e)&&e.type==="ArrayExpression"&&Array.isArray(e.elements)}u(A,"isArrayExpression");export{J as appendAccountToStage};
1
+ var T=Object.defineProperty;var d=(e,r)=>T(e,"name",{value:r,configurable:!0});import{failure as c,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as b,computeLinesDelta as k,extractProgramBody as x}from"../_internal.js";import{buildObjectProperty as h,detectQuoteStyle as D,parse as C,printFile as F}from"../fileRewriter/index.js";import{makeStringLiteral as L,toAstValue as O}from"./addResource/propertyBuilder.js";import{astToLiteral as w,isNodeShape as f,readKeyName as N}from"./modifyResource/literalConversion.js";import{findPropertyByKey as E,pushPropertyPreservingComma as I}from"./objectGraph.js";const K="ACCOUNTS",V="workloads";function W(e,r){const a=r.filePath??b,t=r.constName??K,n=r.nestedKey??V,{stage:o,displayName:s}=r,i=C(e,a);if(!i.success)return c(i.error);const l=x(i.data);if(l===void 0)return c({kind:"InvalidStageTargetError",stage:o,reason:"recast File is missing program.body"});const m=j(l,t);if(m===void 0)return c({kind:"ConstNotFoundError",constName:t});const p=D(i.data),u=_(m,{constName:t,stage:o,nestedKey:n,displayName:s,quoteStyle:p});if(!u.success)return c(u.error);if(u.data.created)return P(i.data,e);const v=u.data.array;return v.elements.some(A=>f(A)&&w(A)===s)?y({content:e,linesChanged:{added:0,removed:0},skipped:!0}):(v.elements.push(L(s,p)),P(i.data,e))}d(W,"appendAccountToStage");function P(e,r){const a=F(e,r);return y({content:a,linesChanged:k(r,a)})}d(P,"printSuccess");function _(e,r){const{constName:a,stage:t,nestedKey:n,displayName:o,quoteStyle:s}=r,i=E(e,t);if(i!==void 0)return S(i.value)?y({created:!1,array:i.value}):c({kind:"InvalidStageTargetError",stage:t,reason:`Top-level "${t}" is not an array literal.`});const l=E(e,n);if(l!==void 0&&g(l.value)){const m=l.value,p=E(m,t);if(p!==void 0)return S(p.value)?y({created:!1,array:p.value}):c({kind:"InvalidStageTargetError",stage:t,reason:`Nested "${n}.${t}" is not an array literal.`});const u=$(m,t,o,s);return u.success?y({created:!0}):c(u.error)}return c({kind:"StageNotFoundError",constName:a,stage:t,knownStages:q(e,n)})}d(_,"resolveStageArray");function $(e,r,a,t){const n=O([a],t);if(n===void 0)return c({kind:"InvalidStageTargetError",stage:r,reason:`Unable to build an array literal for "${r}".`});const o=h(r,n,t);return I(e,o),y(void 0)}d($,"appendStageProperty");function j(e,r){for(const a of e){const t=U(a);if(t===void 0)continue;const n=t.declarations;if(Array.isArray(n))for(const o of n){if(!f(o)||o.type!=="VariableDeclarator")continue;const s=o.id,i=B(o.init);if(f(s)&&s.type==="Identifier"&&s.name===r&&g(i))return i}}}d(j,"findConstObjectExpression");function U(e){if(e.type==="VariableDeclaration")return e;if(e.type==="ExportNamedDeclaration"){const r=e.declaration;if(f(r)&&r.type==="VariableDeclaration")return r}}d(U,"unwrapVariableDeclaration");function B(e){let r=e;for(;f(r)&&(r.type==="TSAsExpression"||r.type==="TSSatisfiesExpression");)r=r.expression;return r}d(B,"unwrapExpression");function q(e,r){const a=[];for(const t of e.properties){if(t.type!=="Property"&&t.type!=="ObjectProperty")continue;const n=N(t.key);if(n!==void 0)if(n===r&&g(t.value))for(const o of t.value.properties){const s=N(o.key);s!==void 0&&a.push(`${r}.${s}`)}else S(t.value)&&a.push(n)}return a}d(q,"collectStageKeys");function g(e){return f(e)&&e.type==="ObjectExpression"&&Array.isArray(e.properties)}d(g,"isObjectExpression");function S(e){return f(e)&&e.type==="ArrayExpression"&&Array.isArray(e.elements)}d(S,"isArrayExpression");export{W as appendAccountToStage};
@@ -0,0 +1,65 @@
1
+ import { type Result } from "../../types/Result.js";
2
+ import { type NodeShapeLike, type ObjectExpressionNodeLike } from "./modifyResource/literalConversion.js";
3
+ export interface ArrayExpressionNodeLike extends NodeShapeLike {
4
+ type: "ArrayExpression";
5
+ elements: unknown[];
6
+ }
7
+ export type ServiceLocateFailure = {
8
+ kind: "ServiceNotFound";
9
+ serviceName: string;
10
+ knownServices: string[];
11
+ } | {
12
+ kind: "AmbiguousService";
13
+ serviceName: string;
14
+ count: number;
15
+ };
16
+ export type ContainerLocateFailure =
17
+ /** No plain `containers` property. Absence is NOT yet proven — callers that
18
+ * act on absence must gate on `objectAbsenceIsProvable(service, "containers")`. */
19
+ {
20
+ kind: "NoContainersArray";
21
+ }
22
+ /** A plain `containers` property exists but its value is not a static array
23
+ * literal (`containers: SHARED`, `containers: buildContainers()`) — the
24
+ * service HAS containers the edit cannot see. */
25
+ | {
26
+ kind: "ContainersNotStaticArray";
27
+ } | {
28
+ kind: "ContainerIndexOutOfRange";
29
+ containerCount: number;
30
+ } | {
31
+ kind: "ContainerNotObjectLiteral";
32
+ containerIndex: number;
33
+ };
34
+ /**
35
+ * Every `ComputeFactory.build(<name>, { … })` config object in the file.
36
+ *
37
+ * Walks the whole tree rather than scanning top-level statements: the call is
38
+ * normally nested inside `app.addCompute(...)`, and may sit in a declarator,
39
+ * a bare expression statement, or a conditional.
40
+ */
41
+ export declare function collectComputeConfigs(body: NodeShapeLike[]): ObjectExpressionNodeLike[];
42
+ /**
43
+ * Locate the single service object literal named `serviceName` across every
44
+ * compute config in the file. Ambiguity (two services sharing the name, even
45
+ * across separate `ComputeFactory.build` calls) is a failure — an edit cannot
46
+ * be proven to target the right one.
47
+ */
48
+ export declare function locateServiceByName(body: NodeShapeLike[], serviceName: string): Result<ObjectExpressionNodeLike, ServiceLocateFailure>;
49
+ /**
50
+ * Resolve the container object literal at `containerIndex` within a located
51
+ * service.
52
+ */
53
+ export declare function locateContainer(service: ObjectExpressionNodeLike, containerIndex: number): Result<ObjectExpressionNodeLike, ContainerLocateFailure>;
54
+ /**
55
+ * Read a plain string-literal property from an object literal. `undefined`
56
+ * covers both "no plain property" and "value is not a string literal".
57
+ */
58
+ export declare function readStringProperty(obj: ObjectExpressionNodeLike, key: string): string | undefined;
59
+ export declare function isArrayExpression(value: unknown): value is ArrayExpressionNodeLike;
60
+ /**
61
+ * Index of the LAST plain (non-shorthand, non-computed) property named `key`:
62
+ * with a duplicate key the later one wins at runtime, so the earlier is a
63
+ * dead literal.
64
+ */
65
+ export declare function findLastPlainPropertyIndex(obj: ObjectExpressionNodeLike, key: string): number;
@@ -0,0 +1 @@
1
+ var g=Object.defineProperty;var i=(r,t)=>g(r,"name",{value:t,configurable:!0});import{failure as c,success as y}from"../../types/Result.js";import{FACTORY_IDENTIFIERS as x}from"../registry.js";import{astToLiteral as C,isNodeShape as s,NON_LITERAL as A,readKeyName as E}from"./modifyResource/literalConversion.js";import{findPropertyByKey as d,visit as O}from"./objectGraph.js";const h=x.compute,b="build";function v(r){const t=[];for(const n of r)O(n,e=>{if(e.type!=="CallExpression"||!P(e))return;const o=e.arguments;if(!Array.isArray(o))return;const u=o[1];s(u)&&u.type==="ObjectExpression"&&t.push(u)});return t}i(v,"collectComputeConfigs");function P(r){const t=r.callee;if(!s(t)||t.type!=="MemberExpression"||t.computed===!0)return!1;const n=t.object,e=t.property;return s(n)&&n.type==="Identifier"&&n.name===h&&s(e)&&e.type==="Identifier"&&e.name===b}i(P,"isComputeFactoryBuild");function L(r,t){const n=[],e=[];for(const u of v(r)){const f=d(u,"services");if(!(f===void 0||!m(f.value)))for(const p of f.value.elements){if(!s(p)||p.type!=="ObjectExpression")continue;const l=p,a=k(l,"name");a!==void 0&&(a===t?e.push(l):n.push(a))}}if(e.length>1)return c({kind:"AmbiguousService",serviceName:t,count:e.length});const[o]=e;return o!==void 0?y(o):c({kind:"ServiceNotFound",serviceName:t,knownServices:n})}i(L,"locateServiceByName");function F(r,t){const n=d(r,"containers");if(n===void 0)return c({kind:"NoContainersArray"});if(!m(n.value))return c({kind:"ContainersNotStaticArray"});const e=n.value.elements,o=e[t];return o===void 0?c({kind:"ContainerIndexOutOfRange",containerCount:e.length}):!s(o)||o.type!=="ObjectExpression"?c({kind:"ContainerNotObjectLiteral",containerIndex:t}):y(o)}i(F,"locateContainer");function k(r,t){const n=d(r,t);if(n===void 0||!s(n.value))return;const e=C(n.value);return e===A||typeof e!="string"?void 0:e}i(k,"readStringProperty");function m(r){return s(r)&&r.type==="ArrayExpression"&&Array.isArray(r.elements)}i(m,"isArrayExpression");function R(r,t){for(let n=r.properties.length-1;n>=0;n--){const e=r.properties[n];if(e!==void 0&&(e.type==="Property"||e.type==="ObjectProperty")&&e.shorthand!==!0&&e.computed!==!0&&E(e.key)===t)return n}return-1}i(R,"findLastPlainPropertyIndex");export{v as collectComputeConfigs,R as findLastPlainPropertyIndex,m as isArrayExpression,F as locateContainer,L as locateServiceByName,k as readStringProperty};
@@ -0,0 +1,65 @@
1
+ import { type Result } from "../../types/Result.js";
2
+ import type { LinesChanged, ParseError } from "../types.js";
3
+ declare const RESOURCE_FACTORIES: Readonly<{
4
+ readonly database: "DatabaseFactory";
5
+ readonly storage: "StorageFactory";
6
+ }>;
7
+ export type ConnectableResourceType = keyof typeof RESOURCE_FACTORIES;
8
+ export interface ConnectResourceOptions {
9
+ resourceType: ConnectableResourceType;
10
+ /** Factory name — the first argument of `XFactory.build("<name>", …)`. */
11
+ resourceName: string;
12
+ /**
13
+ * ECS service `name`s to wire. Resolved by the caller (compute-level
14
+ * wiring means every service of that compute) — the edit never expands
15
+ * compute names itself.
16
+ */
17
+ serviceNames: readonly string[];
18
+ filePath?: string;
19
+ }
20
+ export interface ConnectResourceSuccess {
21
+ /** Byte-identical to the input when `skipped` is true. */
22
+ content: string;
23
+ linesChanged: LinesChanged;
24
+ /** Binding the wiring references (existing or newly introduced). */
25
+ variableName: string;
26
+ /** Services actually wired this run (already-wired ones are skipped). */
27
+ wiredServices: string[];
28
+ skipped: boolean;
29
+ warnings: string[];
30
+ }
31
+ export interface ResourceStatementNotFoundError {
32
+ kind: "ResourceStatementNotFoundError";
33
+ resourceType: ConnectableResourceType;
34
+ resourceName: string;
35
+ }
36
+ export interface AmbiguousResourceStatementError {
37
+ kind: "AmbiguousResourceStatementError";
38
+ resourceType: ConnectableResourceType;
39
+ resourceName: string;
40
+ count: number;
41
+ }
42
+ export interface VariableNameConflictError {
43
+ kind: "VariableNameConflictError";
44
+ variableName: string;
45
+ }
46
+ export interface ConnectServiceNotFoundError {
47
+ kind: "ConnectServiceNotFoundError";
48
+ serviceName: string;
49
+ knownServices: string[];
50
+ }
51
+ /**
52
+ * `reason` is author-written text that may embed identifiers, property keys
53
+ * and resource/service NAMES read from the parsed source or CLI input —
54
+ * identifier-class data, never expression values (see security-standards §
55
+ * "Values, not identifiers"). It is never error-derived. The CLI boundary
56
+ * masks defensively regardless.
57
+ */
58
+ export interface UnsupportedConnectionShapeError {
59
+ kind: "UnsupportedConnectionShapeError";
60
+ reason: string;
61
+ serviceName?: string;
62
+ }
63
+ export type ConnectResourceError = ParseError | ResourceStatementNotFoundError | AmbiguousResourceStatementError | VariableNameConflictError | ConnectServiceNotFoundError | UnsupportedConnectionShapeError;
64
+ export declare function connectResourceToCompute(content: string, options: ConnectResourceOptions): Result<ConnectResourceSuccess, ConnectResourceError>;
65
+ export {};
@@ -0,0 +1 @@
1
+ var H=Object.defineProperty;var u=(t,e)=>H(t,"name",{value:e,configurable:!0});import{builders as E}from"ast-types";import{CREDENTIAL_KEYS as U,DATABASE_ACCESSORS as C,DATABASE_ENV_VARS as b,DATABASE_SSL_VALUE as z}from"../../generation/database.js";import{MESSAGING_ENV_VARS as Y}from"../../generation/messagingConnections.js";import{STORAGE_ACCESSORS as Q,STORAGE_ENV_VARS as O}from"../../generation/storageConnections.js";import{connectionEnvSuffix as J,connectionKeyOrdinal as T,toVariableName as X}from"../../generation/common.js";import{failure as c,success as S}from"../../types/Result.js";import{DEFAULT_FILE_PATH as Z,computeLinesDelta as q,extractProgramBody as ee}from"../_internal.js";import{buildObjectProperty as D,detectQuoteStyle as ne,parse as te,printFile as re}from"../fileRewriter/index.js";import{FACTORY_IDENTIFIERS as P,STATEMENT_REGISTRY as oe}from"../registry.js";import{makeStringLiteral as _}from"./addResource/propertyBuilder.js";import{findLastPlainPropertyIndex as j,isArrayExpression as ie,locateContainer as ae,locateServiceByName as se}from"./computeServiceLocator.js";import{isNodeShape as f,readKeyName as M}from"./modifyResource/literalConversion.js";import{unwrapTsWrappers as I}from"./moduleConstResolver.js";import{objectAbsenceIsProvable as $,pushPropertyPreservingComma as ce,visit as L}from"./objectGraph.js";const v=Object.freeze({database:P.database,storage:P.storage});function x(t){const e=oe[t].emitWrapper?.appMethod;if(e===void 0)throw new Error(`No app method registered for statement type "${t}"`);return e}u(x,"requireAppMethod");const A=Object.freeze({database:x("database"),storage:x("storage")}),F=new Map([[A.database,0],[A.storage,1],[x("messaging"),2]]);function Me(t,e){const n=e.filePath??Z,{resourceType:o,resourceName:r}=e,i=[...new Set(e.serviceNames)];if(i.length===0)return c({kind:"UnsupportedConnectionShapeError",reason:"No target services were supplied."});const a=te(t,n);if(!a.success)return c(a.error);const s=ee(a.data);if(s===void 0)return c({kind:"UnsupportedConnectionShapeError",reason:"recast File is missing program.body"});const d=de(s,o,r);if(!d.success)return c(d.error);const{variableName:p}=d.data,l=[],y=[];for(const h of i){const k=fe(s,h,p,o);if(!k.success)return c(k.error);if(k.data==="already-connected"){l.push(h);continue}y.push(k.data)}const m=l.map(h=>`Service "${h}" already lists "${p}" in its \`connections\` array \u2014 left untouched.`);for(const h of y)h.container===void 0&&m.push(`Service "${h.serviceName}" has no \`containers\` array \u2014 wired \`connections\` only, without env/secret entries (the generator lane emits the same shape for container-less services).`);if(y.length===0)return S({content:t,linesChanged:{added:0,removed:0},variableName:p,wiredServices:[],skipped:!0,warnings:m});const g=ne(a.data),G=Se(s);pe(s,d.data);for(const h of y)he(h,p,o,g,G);const w=re(a.data,t);return S({content:w,linesChanged:q(t,w),variableName:p,wiredServices:y.map(h=>h.serviceName),skipped:!1,warnings:m})}u(Me,"connectResourceToCompute");function de(t,e,n){const o=v[e],r=[];for(let p=0;p<t.length;p++){const l=t[p];if(l===void 0)continue;let y=!1;L(l,m=>{m.type==="CallExpression"&&R(m,o,n)&&(y=!0)}),y&&r.push({statementIndex:p})}if(r.length===0)return c({kind:"ResourceStatementNotFoundError",resourceType:e,resourceName:n});if(r.length>1)return c({kind:"AmbiguousResourceStatementError",resourceType:e,resourceName:n,count:r.length});const i=r[0];if(i===void 0)return c({kind:"ResourceStatementNotFoundError",resourceType:e,resourceName:n});const a=t[i.statementIndex];if(a===void 0)return c({kind:"ResourceStatementNotFoundError",resourceType:e,resourceName:n});if(a.type==="VariableDeclaration"){const p=a.declarations;if(!Array.isArray(p)||p.length!==1)return c({kind:"UnsupportedConnectionShapeError",reason:`The statement declaring "${n}" carries multiple declarators \u2014 the binding cannot be identified.`});const l=p[0].id;if(!f(l)||l.type!=="Identifier")return c({kind:"UnsupportedConnectionShapeError",reason:`The statement declaring "${n}" binds a pattern, not an identifier.`});const y=l.name;if(typeof y!="string")return c({kind:"UnsupportedConnectionShapeError",reason:`The binding for "${n}" has no readable name.`});const m=p[0].init;return!f(m)||!B(m,e,n)?c({kind:"UnsupportedConnectionShapeError",reason:`The binding for "${n}" is not a direct \`app.${A[e]}(${v[e]}.build(...))\` call \u2014 the bound value is not the construct \`connections\` needs.`}):S({variableName:y})}if(a.type!=="ExpressionStatement")return c({kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${n}" is a ${a.type}, which cannot be bound to a const.`});const s=a.expression;if(!f(s)||s.type!=="CallExpression")return c({kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${n}" is not an app-method call \u2014 there is no construct value to bind.`});if(R(s,v[e],n))return c({kind:"UnsupportedConnectionShapeError",reason:`"${n}" is a bare factory call not wrapped in an app method \u2014 there is no construct value to bind.`});if(!B(s,e,n))return c({kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${n}" is not a direct \`app.${A[e]}(...)\` call \u2014 binding it would wire a value \`connections\` cannot use.`});const d=X(n);return ue(t,d)?c({kind:"VariableNameConflictError",variableName:d}):S({variableName:d,wrap:{statementIndex:i.statementIndex,expression:s}})}u(de,"planBinding");function pe(t,e){if(e.wrap===void 0)return;const{statementIndex:n,expression:o}=e.wrap,r=t[n],i=E.variableDeclaration("const",[E.variableDeclarator(E.identifier(e.variableName),o)]),a=r?.comments;a!==void 0&&(i.comments=a),t[n]=i}u(pe,"applyBinding");function R(t,e,n){const o=t.callee;if(!f(o)||o.type!=="MemberExpression"||o.computed===!0)return!1;const r=o.object,i=o.property;if(!f(r)||r.type!=="Identifier"||r.name!==e||!f(i)||i.type!=="Identifier"||i.name!=="build")return!1;const a=t.arguments;if(!Array.isArray(a))return!1;const s=a[0];return!f(s)||s.type!=="StringLiteral"&&s.type!=="Literal"?!1:s.value===n}u(R,"isFactoryBuildOf");function N(t){if(t.type!=="ExportNamedDeclaration"&&t.type!=="ExportDefaultDeclaration")return t;const e=t.declaration;return f(e)?e:void 0}u(N,"unwrapExportDeclaration");function V(t){const e=I(t);if(e.type!=="CallExpression")return;const n=e.callee;if(!f(n)||n.type!=="MemberExpression"||n.computed===!0)return;const o=n.property;if(!f(o)||o.type!=="Identifier")return;const r=o.name;return typeof r=="string"?r:void 0}u(V,"appMethodNameOf");function B(t,e,n){const o=I(t);if(V(o)!==A[e])return!1;const r=o.arguments;if(!Array.isArray(r))return!1;const i=r[0];return f(i)?R(I(i),v[e],n):!1}u(B,"isAppMethodWrap");function ue(t,e){for(const n of t){const o=N(n);if(o!==void 0){if(o.type==="ImportDeclaration"){const r=o.specifiers;if(!Array.isArray(r))continue;for(const i of r){const a=i.local;if(f(a)&&a.name===e)return!0}continue}if(o.type==="VariableDeclaration"){const r=o.declarations;if(!Array.isArray(r))continue;for(const i of r){if(!f(i))continue;const a=i.id;if(!f(a))continue;let s=!1;if(L(a,d=>{d.type==="Identifier"&&d.name===e&&(s=!0)}),s)return!0}continue}if(o.type==="FunctionDeclaration"||o.type==="ClassDeclaration"){const r=o.id;if(f(r)&&r.name===e)return!0}}}return!1}u(ue,"moduleScopeDeclares");function fe(t,e,n,o){const r=se(t,e);if(!r.success){const m=r.error;return m.kind==="AmbiguousService"?c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:`${String(m.count)} services share the name "${e}" across ComputeFactory.build calls \u2014 the edit cannot be proven to target the right one.`}):c({kind:"ConnectServiceNotFoundError",serviceName:e,knownServices:m.knownServices})}const i=r.data,a=ae(i,0);let s;if(a.success)s=a.data;else switch(a.error.kind){case"ContainerNotObjectLiteral":return c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"The first container is not an object literal."});case"ContainersNotStaticArray":return c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"`containers` is not a static array literal, so the container to wire cannot be located."});case"NoContainersArray":if(!$(i,"containers"))return c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"Service carries a spread, shorthand or computed key that could supply `containers` invisibly, so an absent property cannot be proven."});break;case"ContainerIndexOutOfRange":break}const d=le(i,e,n);if(!d.success)return c(d.error);if(d.data.alreadyConnected)return S("already-connected");let p,l,y="";if(s!==void 0){const m=W(s,"environment",e);if(!m.success)return c(m.error);const g=W(s,"secretsImport",e);if(!g.success)return c(g.error);p=m.data,l=g.data,y=me(o,[...m.data.keys,...g.data.keys])}return S({serviceName:e,service:i,container:s,environment:p,secretsImport:l,suffix:y,connectionsArray:d.data.array})}u(fe,"planService");function le(t,e,n){const o=j(t,"connections");if(o===-1)return $(t,"connections")?S({array:void 0,alreadyConnected:!1}):c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"Service carries a spread, shorthand or computed key that could supply `connections` invisibly, so an absent property cannot be proven."});const r=t.properties[o]?.value;if(!ie(r))return c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"`connections` is not an array literal."});for(const i of r.elements)if(f(i)){if(i.type==="Identifier"){if(i.name===n)return S({array:r,alreadyConnected:!0});continue}return c({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:`\`connections\` contains a ${i.type}, so "${n}" cannot be proven absent from it.`})}return S({array:r,alreadyConnected:!1})}u(le,"inspectConnections");function W(t,e,n){const o=j(t,e);if(o===-1)return $(t,e)?S({obj:void 0,keys:[]}):c({kind:"UnsupportedConnectionShapeError",serviceName:n,reason:`The first container carries a spread, shorthand or computed key that could supply \`${e}\` invisibly, so an absent property cannot be proven.`});const r=t.properties[o]?.value;if(!f(r)||r.type!=="ObjectExpression")return c({kind:"UnsupportedConnectionShapeError",serviceName:n,reason:`\`${e}\` is not an object literal.`});const i=r,a=[];for(const s of i.properties){if(s.type==="SpreadElement"||s.type==="SpreadProperty")return c({kind:"UnsupportedConnectionShapeError",serviceName:n,reason:`\`${e}\` contains a spread, so existing connection keys cannot be enumerated to derive the next suffix.`});if(s.type!=="Property"&&s.type!=="ObjectProperty")continue;if(s.computed===!0)return c({kind:"UnsupportedConnectionShapeError",serviceName:n,reason:`\`${e}\` contains a computed key.`});const d=M(s.key);d!==void 0&&a.push(d)}return S({obj:i,keys:a})}u(W,"collectWiringTarget");function me(t,e){const n=Object.values(t==="database"?b:O),o=new Set;for(const r of e)for(const i of n){const a=T(r,i);a!==void 0&&o.add(a)}return J(o.size===0?0:Math.max(...o))}u(me,"nextConnectionSuffix");function ye(t,e,n,o){const r=u((s,d,p=[])=>E.callExpression(E.memberExpression(s,E.identifier(d),!1),p),"call"),i=u(()=>E.identifier(e),"variable");if(t==="storage")return[{key:`${O.NAME}${n}`,value:r(i(),Q.BUCKET_NAME),target:"environment"}];const a=u(s=>r(r(i(),C.CREDENTIALS),C.IMPORT,[_(s,o)]),"credential");return[{key:`${b.HOST}${n}`,value:r(i(),C.HOST),target:"environment"},{key:`${b.PORT}${n}`,value:r(i(),C.PORT),target:"environment"},{key:`${b.NAME}${n}`,value:r(i(),C.NAME),target:"environment"},{key:`${b.SSL}${n}`,value:_(z,o),target:"environment"},{key:`${b.USERNAME}${n}`,value:a(U.USERNAME),target:"secretsImport"},{key:`${b.PASSWORD}${n}`,value:a(U.PASSWORD),target:"secretsImport"}]}u(ye,"buildWiringEntries");function he(t,e,n,o,r){if(t.connectionsArray!==void 0){const d=Ee(t.connectionsArray,n,r);t.connectionsArray.elements.splice(d,0,E.identifier(e))}else K(t.service,"connections",E.arrayExpression([E.identifier(e)]),o);const i=t.container;if(i===void 0)return;const a=ye(n,e,t.suffix,o),s=[{key:"environment",state:t.environment},{key:"secretsImport",state:t.secretsImport}];for(const{key:d,state:p}of s){const l=a.filter(y=>y.target===d);l.length!==0&&Ae(i,d,p,l,o)}}u(he,"applyServiceWiring");function Ee(t,e,n){const o=F.get(A[e])??0;for(let r=0;r<t.elements.length;r++){const i=t.elements[r];if(!f(i)||i.type!=="Identifier")continue;const a=i.name;if(typeof a!="string")continue;const s=n.get(a);if(s!==void 0&&s>o)return r}return t.elements.length}u(Ee,"connectionInsertIndex");function Se(t){const e=new Map;for(const n of t){const o=N(n);if(o===void 0||o.type!=="VariableDeclaration")continue;const r=o.declarations;if(Array.isArray(r))for(const i of r){if(!f(i))continue;const a=i.id,s=i.init;if(!f(a)||a.type!=="Identifier"||!f(s))continue;const d=a.name;if(typeof d!="string")continue;const p=V(s);if(p===void 0)continue;const l=F.get(p);l!==void 0&&e.set(d,l)}}return e}u(Se,"collectConnectionRanks");const be=Object.freeze([...Object.values(b),...Object.values(O),...Object.values(Y)]);function ge(t){let e=-1;for(let n=0;n<t.properties.length;n++){const o=t.properties[n];if(o===void 0||o.type!=="Property"&&o.type!=="ObjectProperty"||o.computed===!0)continue;const r=M(o.key);if(r===void 0)continue;be.some(a=>T(r,a)!==void 0)&&(e=n)}return e===-1?t.properties.length:e+1}u(ge,"connectionEntryInsertIndex");function Ae(t,e,n,o,r){const i=o.map(d=>D(d.key,d.value,r)),a=n?.obj;if(a===void 0){K(t,e,E.objectExpression(i),r);return}const s=ge(a);a.properties.splice(s,0,...i)}u(Ae,"insertObjectEntries");function K(t,e,n,o){const r=D(e,n,o);ce(t,r)}u(K,"appendProperty");export{Me as connectResourceToCompute};
@@ -1 +1 @@
1
- var T=Object.defineProperty;var u=(r,e)=>T(r,"name",{value:e,configurable:!0});import{failure as s,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as A,computeLinesDelta as F,extractProgramBody as L,isRecord as g}from"../_internal.js";import{buildObjectProperty as G,detectQuoteStyle as O,parse as Q,printFile as U}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as b}from"../registry.js";import{locateAllShapes as I,locateByShape as D}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as K}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as V}from"./controlFlowPolicy.js";import{driftGate as B,runPipeline as _,schemaGate as M}from"../validationGate/index.js";import{toAstValue as $}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as v,collectPropertyKeys as H,isNodeShape as S,readKeyName as Y}from"./modifyResource/literalConversion.js";import{evaluateEmitGuard as q,UNRESOLVED as z}from"../emitGuard.js";import{projectEmittedProperties as J,projectionRefusal as W}from"../emitProjection.js";function he(r,e,t={}){const n=e.filePath??A,i=Q(r,n);if(!i.success)return s(i.error);const a=D(r,{type:e.type,name:e.name},n);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?s(a.error):s({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data===void 0)return s({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:ne(r,e.type,n)});if(a.data.managed===!1)return s(K(e.type,"modify"));const o=V({ast:i.data,target:a.data,resource:{type:e.type,name:e.name},op:"modify"});if(o.refusal!==void 0)return s(o.refusal);const c=_([M,B],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:t.baseline,policy:e.driftPolicy});if(!c.success)return s(X(c.error));if(c.data.action==="skip")return y({content:r,linesChanged:{added:0,removed:0},skipped:!0});const d=L(i.data);if(d===void 0)return s({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const l=Z(d,a.data);if(l===void 0)return s({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const R=O(i.data),x=v(l,e.properties),C=b[e.type].emitGuard,E=u(f=>q(C,f)??W(e.type,f),"judge"),N=E(w(l,v(l,{}))),p=E(w(l,x));if(p!==void 0&&p.property!==N?.property)return s(p);const h=b[e.type].schemaFragment.safeParse(e.properties);if(!h.success){const f=h.error.issues[0];return s({kind:"InvalidPropertyError",property:f!==void 0&&f.path.length>0?String(f.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:f?.message??"Schema validation failed"})}const m=J(e.type,e.properties,{editingExisting:!0});if("refusal"in m)return s(m.refusal);const k=ee(l,m.props,R);if(!k.success)return s(k.error);const P=U(i.data,r),j=o.warning!==void 0?[o.warning.message]:void 0;return y({content:P,linesChanged:F(r,P),warnings:j})}u(he,"modifyResource");function w(r,e){const t={...e};for(const n of H(r))n in t||(t[n]=z);return t}u(w,"buildGuardView");function X(r){switch(r.kind){case"ParseError":case"ResourceNotFoundError":case"InvalidPropertyError":case"TemplateLiteralNameError":case"SemanticQueryError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}u(X,"narrowGateError");function Z(r,e){const t=e.start+e.length;let n;const i=u(a=>{if(n!==void 0||a.type!=="CallExpression")return;const o=a.arguments;if(!Array.isArray(o)||o.length<2)return;const c=o[0];if(!S(c)||c.type!=="StringLiteral"||c.start!==e.start||c.end!==t)return;const d=o[1];S(d)&&d.type==="ObjectExpression"&&(n=d)},"visitor");for(const a of r)if(ie(a,i),n!==void 0)break;return n}u(Z,"findConfigObject");function ee(r,e,t){const n=te(r);for(const{key:i,value:a}of e){const o=$(a,t);if(o===void 0)return s({kind:"InvalidPropertyError",property:i,reason:`Unsupported property value for "${i}" (accepts string/number/boolean/null/array/object of the same).`});const c=re(r,i);if(c!==void 0){c.value=o;continue}const d=G(i,o,t);n&&(d.extra={...d.extra??{},trailingComma:!0}),r.properties.push(d)}return y(void 0)}u(ee,"applyPropertyEdits");function re(r,e){return r.properties.find(t=>(t.type==="Property"||t.type==="ObjectProperty")&&t.shorthand!==!0&&t.computed!==!0&&Y(t.key)===e)}u(re,"findPropertyByKey");function te(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}u(te,"detectTrailingCommaStyle");function ne(r,e,t){const n=I(r,t);return n.success?n.data.filter(i=>i.type===e).map(i=>i.symbolName):[]}u(ne,"collectKnownNames");function ie(r,e){const t=[r];for(;t.length>0;){const n=t.pop();if(g(n)){typeof n.type=="string"&&e(n);for(const i of Object.keys(n)){if(i==="loc"||i==="comments"||i==="tokens")continue;const a=n[i];if(Array.isArray(a))for(const o of a)g(o)&&t.push(o);else g(a)&&t.push(a)}}}}u(ie,"visit");export{he as modifyResource};
1
+ var T=Object.defineProperty;var d=(r,e)=>T(r,"name",{value:e,configurable:!0});import{failure as i,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as F,computeLinesDelta as L,extractProgramBody as j}from"../_internal.js";import{buildObjectProperty as A,detectQuoteStyle as G,parse as Q,printFile as U}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as P}from"../registry.js";import{locateAllShapes as I,locateByShape as D}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as O}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as V}from"./controlFlowPolicy.js";import{driftGate as B,runPipeline as K,schemaGate as _}from"../validationGate/index.js";import{toAstValue as M}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as b,collectPropertyKeys as $,isNodeShape as S}from"./modifyResource/literalConversion.js";import{findPropertyByKey as H,visit as Y}from"./objectGraph.js";import{evaluateEmitGuard as q,UNRESOLVED as z}from"../emitGuard.js";import{projectEmittedProperties as J,projectionRefusal as W}from"../emitProjection.js";function Ee(r,e,s={}){const n=e.filePath??F,t=Q(r,n);if(!t.success)return i(t.error);const a=D(r,{type:e.type,name:e.name},n);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?i(a.error):i({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data===void 0)return i({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:te(r,e.type,n)});if(a.data.managed===!1)return i(O(e.type,"modify"));const o=V({ast:t.data,target:a.data,resource:{type:e.type,name:e.name},op:"modify"});if(o.refusal!==void 0)return i(o.refusal);const u=K([_,B],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:s.baseline,policy:e.driftPolicy});if(!u.success)return i(X(u.error));if(u.data.action==="skip")return y({content:r,linesChanged:{added:0,removed:0},skipped:!0});const c=j(t.data);if(c===void 0)return i({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=Z(c,a.data);if(f===void 0)return i({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const w=G(t.data),x=b(f,e.properties),C=P[e.type].emitGuard,g=d(l=>q(C,l)??W(e.type,l),"judge"),R=g(v(f,b(f,{}))),p=g(v(f,x));if(p!==void 0&&p.property!==R?.property)return i(p);const E=P[e.type].schemaFragment.safeParse(e.properties);if(!E.success){const l=E.error.issues[0];return i({kind:"InvalidPropertyError",property:l!==void 0&&l.path.length>0?String(l.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:l?.message??"Schema validation failed"})}const m=J(e.type,e.properties,{editingExisting:!0});if("refusal"in m)return i(m.refusal);const h=ee(f,m.props,w);if(!h.success)return i(h.error);const k=U(t.data,r),N=o.warning!==void 0?[o.warning.message]:void 0;return y({content:k,linesChanged:L(r,k),warnings:N})}d(Ee,"modifyResource");function v(r,e){const s={...e};for(const n of $(r))n in s||(s[n]=z);return s}d(v,"buildGuardView");function X(r){switch(r.kind){case"ParseError":case"ResourceNotFoundError":case"InvalidPropertyError":case"TemplateLiteralNameError":case"SemanticQueryError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}d(X,"narrowGateError");function Z(r,e){const s=e.start+e.length;let n;const t=d(a=>{if(n!==void 0||a.type!=="CallExpression")return;const o=a.arguments;if(!Array.isArray(o)||o.length<2)return;const u=o[0];if(!S(u)||u.type!=="StringLiteral"||u.start!==e.start||u.end!==s)return;const c=o[1];S(c)&&c.type==="ObjectExpression"&&(n=c)},"visitor");for(const a of r)if(Y(a,t),n!==void 0)break;return n}d(Z,"findConfigObject");function ee(r,e,s){const n=re(r);for(const{key:t,value:a}of e){const o=M(a,s);if(o===void 0)return i({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (accepts string/number/boolean/null/array/object of the same).`});const u=H(r,t);if(u!==void 0){u.value=o;continue}const c=A(t,o,s);n&&(c.extra={...c.extra??{},trailingComma:!0}),r.properties.push(c)}return y(void 0)}d(ee,"applyPropertyEdits");function re(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}d(re,"detectTrailingCommaStyle");function te(r,e,s){const n=I(r,s);return n.success?n.data.filter(t=>t.type===e).map(t=>t.symbolName):[]}d(te,"collectKnownNames");export{Ee as modifyResource};
@@ -0,0 +1,25 @@
1
+ import { type NodeShapeLike } from "./modifyResource/literalConversion.js";
2
+ export interface ModuleConstResolver {
3
+ /**
4
+ * Strings of `const NAME = ["A", "B"] as const`. `undefined` when NAME is
5
+ * not a uniquely-bound module-scope const initialised to a flat array of
6
+ * string literals (nested spreads do not resolve).
7
+ */
8
+ resolveStringArray(name: string): readonly string[] | undefined;
9
+ /** Value of `const NAME = "A"`; `undefined` when not uniquely so bound. */
10
+ resolveString(name: string): string | undefined;
11
+ /**
12
+ * Statically-known keys of the object a node denotes: an object literal
13
+ * (following nested same-file spreads) or an identifier naming a
14
+ * uniquely-bound module-scope const object. `undefined` when any key is
15
+ * computed or any spread does not resolve.
16
+ */
17
+ objectKeysOf(node: NodeShapeLike): readonly string[] | undefined;
18
+ }
19
+ export declare function buildModuleConstResolver(body: NodeShapeLike[]): ModuleConstResolver;
20
+ /**
21
+ * The string a node statically denotes: a string literal or an
22
+ * expressionless template literal. `undefined` for anything else.
23
+ */
24
+ export declare function readStaticString(node: NodeShapeLike): string | undefined;
25
+ export declare function unwrapTsWrappers(node: NodeShapeLike): NodeShapeLike;
@@ -0,0 +1 @@
1
+ var b=Object.defineProperty;var f=(a,r)=>b(a,"name",{value:r,configurable:!0});import{isRecord as l}from"../_internal.js";import{isNodeShape as d,readKeyName as S}from"./modifyResource/literalConversion.js";function w(a){const r=k(a),s=x(a),t=f(n=>r.get(n)===1?s.get(n):void 0,"initFor");return{resolveString(n){const e=t(n);return e===void 0?void 0:g(e)},resolveStringArray(n){const e=t(n);if(e===void 0)return;const i=y(e);if(i.type!=="ArrayExpression")return;const o=i.elements;if(!Array.isArray(o))return;const u=[];for(const p of o){if(!d(p))return;const A=g(p);if(A===void 0)return;u.push(A)}return u},objectKeysOf:f(n=>m(n,t,new Set),"objectKeysOf")}}f(w,"buildModuleConstResolver");function g(a){const r=y(a);if(r.type==="StringLiteral"){const s=r.value;return typeof s=="string"?s:void 0}if(r.type==="TemplateLiteral"){const s=r.expressions,t=r.quasis;if(!Array.isArray(s)||s.length!==0||!Array.isArray(t)||t.length!==1)return;const[c]=t;return!l(c)||!l(c.value)?void 0:typeof c.value.cooked=="string"?c.value.cooked:void 0}}f(g,"readStaticString");const h=new Set(["TSAsExpression","TSSatisfiesExpression","TSTypeAssertion","TSNonNullExpression","ParenthesizedExpression"]);function y(a){let r=a;for(;h.has(r.type);){const s=r.expression;if(!d(s))return r;r=s}return r}f(y,"unwrapTsWrappers");function m(a,r,s){const t=y(a);if(t.type==="Identifier"){const e=t.name;if(typeof e!="string"||s.has(e))return;s.add(e);const i=r(e);return i===void 0?void 0:m(i,r,s)}if(t.type!=="ObjectExpression")return;const c=t.properties;if(!Array.isArray(c))return;const n=[];for(const e of c){if(!d(e))return;if(e.type==="SpreadElement"||e.type==="SpreadProperty"){const u=e.argument;if(!d(u))return;const p=m(u,r,s);if(p===void 0)return;n.push(...p);continue}if(e.type!=="Property"&&e.type!=="ObjectProperty"&&e.type!=="ObjectMethod"||e.computed===!0)return;const i=e.key;if(!d(i))return;const o=S(i);if(o===void 0)return;n.push(o)}return n}f(m,"objectKeysOfNode");function k(a){const r=new Map,s=f(n=>{r.set(n,(r.get(n)??0)+1)},"bump"),t=f(n=>{if(d(n))switch(n.type){case"Identifier":{const e=n.name;typeof e=="string"&&s(e);return}case"ObjectPattern":{const e=n.properties;if(!Array.isArray(e))return;for(const i of e)d(i)&&(i.type==="RestElement"||i.type==="RestProperty"?t(i.argument):t(i.value));return}case"ArrayPattern":{const e=n.elements;if(!Array.isArray(e))return;for(const i of e)t(i);return}case"AssignmentPattern":t(n.left);return;case"RestElement":t(n.argument);return;case"TSParameterProperty":t(n.parameter);return;default:return}},"bumpPattern"),c=f(n=>{const e=[n];for(;e.length>0;){const i=e.pop();if(l(i)){if(typeof i.type=="string"){const o=i;switch(o.type){case"VariableDeclarator":t(o.id);break;case"FunctionDeclaration":case"FunctionExpression":case"ArrowFunctionExpression":{t(o.id);const u=o.params;if(Array.isArray(u))for(const p of u)t(p);break}case"ClassDeclaration":case"ClassExpression":t(o.id);break;case"ImportSpecifier":case"ImportDefaultSpecifier":case"ImportNamespaceSpecifier":t(o.local);break;case"CatchClause":t(o.param);break;default:break}}for(const o of Object.keys(i)){if(o==="loc"||o==="comments"||o==="tokens")continue;const u=i[o];if(Array.isArray(u))for(const p of u)l(p)&&e.push(p);else l(u)&&e.push(u)}}}},"visitForBindings");for(const n of a)c(n);return r}f(k,"countBindings");function x(a){const r=new Map;for(const s of a){const t=s.type==="ExportNamedDeclaration"?s.declaration:s;if(!d(t)||t.type!=="VariableDeclaration"||t.kind!=="const")continue;const c=t.declarations;if(Array.isArray(c))for(const n of c){if(!d(n)||n.type!=="VariableDeclarator")continue;const e=n.id,i=n.init;if(!d(e)||e.type!=="Identifier"||!d(i))continue;const o=e.name;typeof o=="string"&&r.set(o,i)}}return r}f(x,"collectTopLevelConstInits");export{w as buildModuleConstResolver,g as readStaticString,y as unwrapTsWrappers};
@@ -0,0 +1,34 @@
1
+ import { type NodeShapeLike, type ObjectExpressionNodeLike, type PropertyNodeLike } from "./modifyResource/literalConversion.js";
2
+ /**
3
+ * Finds a plain (non-shorthand, non-computed) property by key name.
4
+ *
5
+ * `undefined` means "no plain property with that key" — NOT "the key is
6
+ * absent". A spread, a shorthand, or a computed key can still supply it.
7
+ * Callers that act on absence must gate on {@link objectAbsenceIsProvable}.
8
+ */
9
+ export declare function findPropertyByKey(obj: ObjectExpressionNodeLike, key: string): PropertyNodeLike | undefined;
10
+ /**
11
+ * True when a `findPropertyByKey(obj, key) === undefined` result may safely be
12
+ * read as "the key is absent from this object".
13
+ *
14
+ * False when the object carries a spread (which can supply any key), a
15
+ * computed property (whose key is not statically known), or a shorthand
16
+ * property named `key` — each of which makes the key present while
17
+ * {@link findPropertyByKey} reports nothing. Appending in those cases would
18
+ * emit a duplicate that silently overrides, or is overridden by, the invisible
19
+ * one depending on source order.
20
+ */
21
+ export declare function objectAbsenceIsProvable(obj: ObjectExpressionNodeLike, key: string): boolean;
22
+ /**
23
+ * Append a property to an object literal, copying the previous last
24
+ * property's trailing-comma marker so recast keeps multiline formatting.
25
+ * Shared by every edit that appends into an existing object literal.
26
+ */
27
+ export declare function pushPropertyPreservingComma(obj: ObjectExpressionNodeLike, property: ObjectExpressionNodeLike["properties"][number]): void;
28
+ /**
29
+ * Non-recursive depth-first walk over every typed node reachable from `root`.
30
+ *
31
+ * Skips `loc`, `comments` and `tokens` so large fixtures do not descend into
32
+ * parser bookkeeping.
33
+ */
34
+ export declare function visit(root: NodeShapeLike, visitor: (node: NodeShapeLike) => void): void;
@@ -0,0 +1 @@
1
+ var a=Object.defineProperty;var o=(t,r)=>a(t,"name",{value:r,configurable:!0});import{isRecord as u}from"../_internal.js";import{readKeyName as f}from"./modifyResource/literalConversion.js";function l(t,r){return t.properties.find(e=>(e.type==="Property"||e.type==="ObjectProperty")&&e.shorthand!==!0&&e.computed!==!0&&f(e.key)===r)}o(l,"findPropertyByKey");function h(t,r){return!t.properties.some(e=>e.type==="SpreadElement"||e.type==="SpreadProperty"?!0:e.type!=="Property"&&e.type!=="ObjectProperty"?!1:e.computed===!0?!0:e.shorthand===!0&&f(e.key)===r)}o(h,"objectAbsenceIsProvable");function d(t,r){t.properties[t.properties.length-1]?.extra?.trailingComma===!0&&(r.extra={...r.extra??{},trailingComma:!0}),t.properties.push(r)}o(d,"pushPropertyPreservingComma");function P(t,r){const e=[t];for(;e.length>0;){const n=e.pop();if(u(n)){typeof n.type=="string"&&r(n);for(const i of Object.keys(n)){if(i==="loc"||i==="comments"||i==="tokens")continue;const s=n[i];if(Array.isArray(s))for(const c of s)u(c)&&e.push(c);else u(s)&&e.push(s)}}}}o(P,"visit");export{l as findPropertyByKey,h as objectAbsenceIsProvable,d as pushPropertyPreservingComma,P as visit};
@@ -0,0 +1,48 @@
1
+ import { type ModuleConstResolver } from "./moduleConstResolver.js";
2
+ import { type ObjectExpressionNodeLike } from "./modifyResource/literalConversion.js";
3
+ /** One element of a `secrets` array, classified for provability. */
4
+ export type SecretsElement = {
5
+ kind: "literal";
6
+ name: string;
7
+ description: string;
8
+ } | {
9
+ kind: "identifier";
10
+ name: string;
11
+ description: string;
12
+ } | {
13
+ kind: "spread";
14
+ names: readonly string[];
15
+ description: string;
16
+ } | {
17
+ kind: "unresolvable";
18
+ description: string;
19
+ };
20
+ export type ProvabilityCheck = {
21
+ ok: true;
22
+ warnings: string[];
23
+ } | {
24
+ ok: false;
25
+ reason: string;
26
+ };
27
+ export declare function classifySecretsElement(element: unknown, resolver: ModuleConstResolver): SecretsElement;
28
+ export declare function describeElements(elements: readonly SecretsElement[]): string;
29
+ /**
30
+ * True when `key` is provably absent from the container object — either
31
+ * structurally (no spread/shorthand/computed at all) or because every spread
32
+ * resolves to a same-file const object whose keys are known not to include it.
33
+ */
34
+ export declare function keyProvablyAbsent(container: ObjectExpressionNodeLike, key: string, resolver: ModuleConstResolver): boolean;
35
+ /**
36
+ * A spread placed AFTER the `secrets` property overrides it at runtime when
37
+ * the spread object also carries a `secrets` key — the edit would mutate a
38
+ * dead literal while reporting success. Refuses unless every later spread is
39
+ * proven not to redefine `secrets`.
40
+ */
41
+ export declare function checkShadowingSpread(container: ObjectExpressionNodeLike, secretsPropIndex: number, resolver: ModuleConstResolver): ProvabilityCheck;
42
+ /**
43
+ * A name present in both `secrets` and `secretsImport` fails `fjall deploy`
44
+ * at synth (the construct rejects the overlap). Proven collisions refuse;
45
+ * an unenumerable `secretsImport` degrades to a warning because the
46
+ * construct's own validation is the authoritative, clearly-worded gate.
47
+ */
48
+ export declare function checkSecretsImportConflicts(container: ObjectExpressionNodeLike, namesToAdd: readonly string[], resolver: ModuleConstResolver): ProvabilityCheck;
@@ -0,0 +1 @@
1
+ var m=Object.defineProperty;var o=(t,r)=>m(t,"name",{value:r,configurable:!0});import{readStaticString as g}from"./moduleConstResolver.js";import{isNodeShape as c,readKeyName as h}from"./modifyResource/literalConversion.js";import{findPropertyByKey as d,objectAbsenceIsProvable as b}from"./objectGraph.js";const u="secretsImport";function w(t,r){if(!c(t))return{kind:"unresolvable",description:"an unrecognised element"};if(t.type==="SpreadElement"||t.type==="SpreadProperty"){const e=t.argument;if(c(e)&&e.type==="Identifier"){const n=e.name;if(typeof n=="string"){const s=r.resolveStringArray(n);return s!==void 0?{kind:"spread",names:s,description:`...${n}`}:{kind:"unresolvable",description:`...${n}`}}}return{kind:"unresolvable",description:"...<expression>"}}const i=g(t);if(i!==void 0)return{kind:"literal",name:i,description:JSON.stringify(i)};if(t.type==="Identifier"){const e=t.name;if(typeof e=="string"){const n=r.resolveString(e);return n!==void 0?{kind:"identifier",name:n,description:e}:{kind:"unresolvable",description:e}}}return{kind:"unresolvable",description:"an expression element"}}o(w,"classifySecretsElement");function $(t){const r=t.slice(0,3).map(e=>`\`${e.description}\``),i=t.length>3?", \u2026":"";return r.join(", ")+i}o($,"describeElements");function k(t,r,i){if(d(t,r)!==void 0)return!1;if(b(t,r))return!0;for(const e of t.properties){if(e.type==="SpreadElement"||e.type==="SpreadProperty"){const n=e.argument;if(!c(n))return!1;const s=i.objectKeysOf(n);if(s===void 0||s.includes(r))return!1;continue}if(!(e.type!=="Property"&&e.type!=="ObjectProperty")&&(e.computed===!0||e.shorthand===!0&&h(e.key)===r))return!1}return!0}o(k,"keyProvablyAbsent");function x(t,r,i){for(const e of t.properties.slice(r+1)){if(e.type!=="SpreadElement"&&e.type!=="SpreadProperty")continue;const n=e.argument,s=c(n)&&n.type==="Identifier"?n.name:void 0,a=typeof s=="string"?`...${s}`:"...<expression>";if(!c(n))return{ok:!1,reason:p(a,"cannot be resolved")};const f=i.objectKeysOf(n);if(f===void 0)return{ok:!1,reason:p(a,"does not resolve to a same-file const object")};if(f.includes("secrets"))return{ok:!1,reason:`The container spreads \`${a}\` after \`secrets\`, and it redefines \`secrets\` \u2014 the edit would be overridden at runtime. Edit that object, or move the spread above \`secrets\`.`}}return{ok:!0,warnings:[]}}o(x,"checkShadowingSpread");function p(t,r){return`The container spreads \`${t}\` after \`secrets\`, which ${r}, so the edit cannot be proven to take effect at runtime. Move the spread above \`secrets\` or edit the file by hand.`}o(p,"shadowingReason");function E(t,r,i){if(r.length===0)return{ok:!0,warnings:[]};const e=d(t,u);if(e===void 0)return k(t,u,i)?{ok:!0,warnings:[]}:{ok:!0,warnings:[l(r,"the container may supply `secretsImport` indirectly")]};const n=e.value!==void 0&&c(e.value)?i.objectKeysOf(e.value):void 0;if(n===void 0)return{ok:!0,warnings:[l(r,"`secretsImport` is not statically enumerable here")]};const s=r.filter(a=>n.includes(a));if(s.length>0){const a=s.map(y=>JSON.stringify(y)).join(", "),f=s.length===1?"is":"are";return{ok:!1,reason:`${a} ${f} already wired via \`secretsImport\`; declaring the same name in \`secrets\` fails \`fjall deploy\` at synth. Remove it from \`secretsImport\` first, or use a different name.`}}return{ok:!0,warnings:[]}}o(E,"checkSecretsImportConflicts");function l(t,r){return`Could not check ${t.map(e=>JSON.stringify(e)).join(", ")} against \`secretsImport\` (${r}); a name declared in both is rejected by \`fjall deploy\` at synth.`}o(l,"buildImportWarning");export{E as checkSecretsImportConflicts,x as checkShadowingSpread,w as classifySecretsElement,$ as describeElements,k as keyProvablyAbsent};