@fjall/generator 8.0.0 → 10.1.1

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 (47) hide show
  1. package/dist/.build-source-hash +32 -29
  2. package/dist/.minified +1 -1
  3. package/dist/src/ast/astTestHelpers.d.ts +1 -0
  4. package/dist/src/ast/parsers/resources/astComputeParserHelpers.js +1 -1
  5. package/dist/src/codemod/edits/addResource.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 +1 -0
  13. package/dist/src/codemod/edits/moduleConstResolver.js +1 -1
  14. package/dist/src/codemod/edits/objectGraph.d.ts +6 -0
  15. package/dist/src/codemod/edits/objectGraph.js +1 -1
  16. package/dist/src/codemod/edits/setContainerSecrets.js +1 -1
  17. package/dist/src/codemod/emitGuard.d.ts +5 -6
  18. package/dist/src/codemod/index.d.ts +1 -0
  19. package/dist/src/codemod/index.js +1 -1
  20. package/dist/src/codemod/registry.d.ts +28 -7
  21. package/dist/src/codemod/registry.js +1 -1
  22. package/dist/src/codemod/types.d.ts +9 -1
  23. package/dist/src/codemod/types.js +1 -1
  24. package/dist/src/codemod/validationGate/gates/schema.js +1 -1
  25. package/dist/src/generation/common.d.ts +15 -0
  26. package/dist/src/generation/common.js +6 -6
  27. package/dist/src/generation/compute/ecs.js +14 -13
  28. package/dist/src/generation/database.d.ts +20 -0
  29. package/dist/src/generation/database.js +18 -18
  30. package/dist/src/generation/messagingConnections.js +1 -1
  31. package/dist/src/generation/storageConnections.d.ts +9 -0
  32. package/dist/src/generation/storageConnections.js +1 -1
  33. package/dist/src/planning/index.d.ts +2 -1
  34. package/dist/src/planning/index.js +1 -1
  35. package/dist/src/planning/planBuilders.d.ts +48 -0
  36. package/dist/src/planning/planBuilders.js +1 -0
  37. package/dist/src/planning/resourceAddition.d.ts +3 -0
  38. package/dist/src/planning/resourceAddition.js +1 -1
  39. package/dist/src/planning/resourcePlanning.js +1 -1
  40. package/dist/src/schemas/applicationSchemas.d.ts +4 -0
  41. package/dist/src/schemas/computeSchemas.d.ts +13 -1
  42. package/dist/src/schemas/computeSchemas.js +1 -1
  43. package/dist/src/schemas/constants.d.ts +2 -0
  44. package/dist/src/schemas/constants.js +1 -1
  45. package/dist/src/version.d.ts +1 -1
  46. package/dist/src/version.js +1 -1
  47. package/package.json +2 -2
@@ -9,7 +9,7 @@
9
9
  "package.json",
10
10
  "tsconfig.json"
11
11
  ],
12
- "hash": "74a0bb134e5609fe93c1b79a77239f6b6d70c8db41fba13d0416c41d87bb28b0",
12
+ "hash": "4856624d6025c5a2e6a9a336b17c91c472cf998e4704479bc5b056986815aff8",
13
13
  "files": {
14
14
  "src/ast/astTestHelpers.ts": "026cac849eb88bdb",
15
15
  "src/ast/domain/astDomainParser.ts": "940ce5742507477d",
@@ -26,7 +26,7 @@
26
26
  "src/ast/parsers/resources/astClickHouseParser.ts": "cf49943b3d2bbd48",
27
27
  "src/ast/parsers/resources/astComputeConnectionParser.ts": "e0f1533845f3ce8a",
28
28
  "src/ast/parsers/resources/astComputeParser.ts": "98e4a2e6b2d634fa",
29
- "src/ast/parsers/resources/astComputeParserHelpers.ts": "6e0349d365bcf6cf",
29
+ "src/ast/parsers/resources/astComputeParserHelpers.ts": "b824f221f8c7e3d9",
30
30
  "src/ast/parsers/resources/astDatabaseParser.ts": "e18f5483f5e23297",
31
31
  "src/ast/parsers/resources/astDynamoDBParser.ts": "809c2c633447b388",
32
32
  "src/ast/parsers/resources/astMessagingParser.ts": "b185ec22e6b96943",
@@ -41,30 +41,32 @@
41
41
  "src/codemod/drift/merge.ts": "29093929befa9abd",
42
42
  "src/codemod/drift/snapshot.ts": "d3c70df4f8537237",
43
43
  "src/codemod/drift/types.ts": "7f1d7899e420e4d7",
44
- "src/codemod/edits/addResource.ts": "c8fe476d5ef589fe",
44
+ "src/codemod/edits/addResource.ts": "dacb2e18657b74cf",
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": "8c01227ad85021f2",
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": "c27380cf9dae5dfc",
57
+ "src/codemod/edits/modifyResource.ts": "2c47fdf60ad340e4",
56
58
  "src/codemod/edits/modifyResource/literalConversion.ts": "31295cccd59131b7",
57
- "src/codemod/edits/moduleConstResolver.ts": "33f3e7ccac89b325",
58
- "src/codemod/edits/objectGraph.ts": "beb4025daf6525d5",
59
- "src/codemod/edits/removeResource.ts": "2c7c8fe67bc3a866",
59
+ "src/codemod/edits/moduleConstResolver.ts": "85a8597427849a80",
60
+ "src/codemod/edits/objectGraph.ts": "5efc4181547237f8",
61
+ "src/codemod/edits/removeResource.ts": "6af70ee482fabc06",
60
62
  "src/codemod/edits/removeResource/commentHeuristic.ts": "90b6ce7ba5aa2a48",
61
63
  "src/codemod/edits/removeResource/importPruning.ts": "f22783108b40f6cb",
62
64
  "src/codemod/edits/secretsProvability.ts": "d723283918e31efd",
63
- "src/codemod/edits/setContainerSecrets.ts": "07cbfac49b5329be",
65
+ "src/codemod/edits/setContainerSecrets.ts": "24478c4205e79cbd",
64
66
  "src/codemod/edits/unmanagedShapeErrors.ts": "47a2644913c8e619",
65
67
  "src/codemod/edits/vpcPeer.ts": "0bcf90c2e6d16ca4",
66
68
  "src/codemod/edits/vpcPeerAccepter.ts": "c9eace933e9e2345",
67
- "src/codemod/emitGuard.ts": "652d9b188276acf8",
69
+ "src/codemod/emitGuard.ts": "d11e4297781ca81c",
68
70
  "src/codemod/emitProjection.ts": "9a47ef44995be65f",
69
71
  "src/codemod/fileRewriter/builders.ts": "46a0d43240ff0818",
70
72
  "src/codemod/fileRewriter/index.ts": "fd715b41176a7999",
@@ -72,7 +74,7 @@
72
74
  "src/codemod/fileRewriter/parse.ts": "b12026c31562a13c",
73
75
  "src/codemod/fileRewriter/print.ts": "f5ff7afb5b7786bf",
74
76
  "src/codemod/historyPaths.ts": "ef8084013146db57",
75
- "src/codemod/index.ts": "71ebede4ab133f9c",
77
+ "src/codemod/index.ts": "db90315eab333aab",
76
78
  "src/codemod/listResources.ts": "97f206a50edbea20",
77
79
  "src/codemod/llmFallback/apply.ts": "2e656a6e55b3b4e3",
78
80
  "src/codemod/llmFallback/claudeTier.ts": "0a37fe782c85f75b",
@@ -87,7 +89,7 @@
87
89
  "src/codemod/llmFallback/telemetryEvents.ts": "33a85939739693ab",
88
90
  "src/codemod/llmFallback/tierRunner.ts": "a26094accd78cf15",
89
91
  "src/codemod/llmFallback/types.ts": "14af8d2bd9afae12",
90
- "src/codemod/registry.ts": "bb0d629f33e5bf59",
92
+ "src/codemod/registry.ts": "fca9df965dd2d7ed",
91
93
  "src/codemod/semanticIndex/classifyControlFlow.ts": "ed96215d91a3cae3",
92
94
  "src/codemod/semanticIndex/findReferences.ts": "96aea37418d1e91a",
93
95
  "src/codemod/semanticIndex/index.ts": "cfcd212d34ab20fb",
@@ -96,12 +98,12 @@
96
98
  "src/codemod/semanticIndex/projectCache.ts": "dfd9b265c9d233c9",
97
99
  "src/codemod/semanticIndex/resolveConstructByLiteralProperty.ts": "2d013a330af15c5c",
98
100
  "src/codemod/telemetry/errorKinds.ts": "66c736abfa8b3a67",
99
- "src/codemod/types.ts": "4097b650c1bde13a",
100
- "src/codemod/validationGate/gates/classify.ts": "edb92a1f7a2d9aeb",
101
+ "src/codemod/types.ts": "0cd929df5bb46696",
102
+ "src/codemod/validationGate/gates/classify.ts": "3cba0ee8fe6d94d9",
101
103
  "src/codemod/validationGate/gates/drift.ts": "bd603a216fbb91a9",
102
104
  "src/codemod/validationGate/gates/locate.ts": "2c186c32edbb97ce",
103
105
  "src/codemod/validationGate/gates/parse.ts": "5433c5c8ffa35324",
104
- "src/codemod/validationGate/gates/schema.ts": "aa904146e30219bd",
106
+ "src/codemod/validationGate/gates/schema.ts": "7ed5acaec0620a46",
105
107
  "src/codemod/validationGate/index.ts": "df5754bea9070410",
106
108
  "src/codemod/validationGate/types.ts": "af466ee5f3433042",
107
109
  "src/detection/index.ts": "b4ad9a935564cb3e",
@@ -111,26 +113,27 @@
111
113
  "src/dns/domainRecords.ts": "ab917006b92ae916",
112
114
  "src/dns/index.ts": "b476ef3d7b381dc8",
113
115
  "src/dns/types.ts": "82d6db9d7d26dbc2",
114
- "src/generation/common.ts": "73fa0ad5ffeeeed4",
116
+ "src/generation/common.ts": "ab66eac580bc227f",
115
117
  "src/generation/compute.ts": "4029a0d8e3197686",
116
118
  "src/generation/compute/ec2.ts": "4d8187d293a57fb1",
117
- "src/generation/compute/ecs.ts": "72190132fdaa1847",
119
+ "src/generation/compute/ecs.ts": "38a345cbd45c40d4",
118
120
  "src/generation/compute/lambda.ts": "4f5e31080941b83a",
119
121
  "src/generation/compute/shared.ts": "3724d4bfe92cfcb7",
120
- "src/generation/database.ts": "a28f791f0f028343",
122
+ "src/generation/database.ts": "dd4a1540986ad350",
121
123
  "src/generation/generatePatternCode.ts": "de16f42105a45358",
122
124
  "src/generation/index.ts": "fd58a833e13bcf07",
123
125
  "src/generation/infrastructure.ts": "6381d502f4733926",
124
- "src/generation/messagingConnections.ts": "1f070088c39e9749",
126
+ "src/generation/messagingConnections.ts": "fef976a8261c6751",
125
127
  "src/generation/storage.ts": "2c0171aeeec3d79e",
126
- "src/generation/storageConnections.ts": "db1ab6ccdc19afab",
128
+ "src/generation/storageConnections.ts": "a4020c9d6c36dc3f",
127
129
  "src/index.ts": "fc8f27b8ffade9ef",
128
130
  "src/planning/generateResourceChange.ts": "1c6411f9a12e7acb",
129
- "src/planning/index.ts": "64c4a88a38e9956d",
131
+ "src/planning/index.ts": "8ef807b31c43310c",
130
132
  "src/planning/openNextPlanning.ts": "4af9cb9061f7d21e",
131
- "src/planning/resourceAddition.ts": "45b010d2eaf96522",
133
+ "src/planning/planBuilders.ts": "bea93d0c05caef21",
134
+ "src/planning/resourceAddition.ts": "ba27203af283d840",
132
135
  "src/planning/resourceConnections.ts": "a6b7db8f733e560f",
133
- "src/planning/resourcePlanning.ts": "6c966fe586fff080",
136
+ "src/planning/resourcePlanning.ts": "1fefdbc93e12ba7f",
134
137
  "src/planning/staticSitePlanning.ts": "242af1e9618821ab",
135
138
  "src/presets/clickhouseTierPreset.ts": "72b2b8a8caf4bdb4",
136
139
  "src/presets/index.ts": "8332c0198b2a6fe9",
@@ -147,8 +150,8 @@
147
150
  "src/schemas/baseSchemas.ts": "93d9bd1c0adfcaa0",
148
151
  "src/schemas/buildkiteSchemas.ts": "a28ec3b40f7851ec",
149
152
  "src/schemas/cdnSchemas.ts": "a982034c7903a31a",
150
- "src/schemas/computeSchemas.ts": "516df862131921fe",
151
- "src/schemas/constants.ts": "1df67cde0522a514",
153
+ "src/schemas/computeSchemas.ts": "907747add0b1e1a9",
154
+ "src/schemas/constants.ts": "52cabac20382fbc9",
152
155
  "src/schemas/databaseSchemas.ts": "3c05f176e1aadb46",
153
156
  "src/schemas/devRolePolicies.ts": "6ca70fb20f5fbebc",
154
157
  "src/schemas/index.ts": "a1500a885048074b",
@@ -166,11 +169,11 @@
166
169
  "src/validation/patterns.ts": "f9629eafdad7ac3e",
167
170
  "src/validation/validationMessages.ts": "c727ade4690274f4",
168
171
  "src/validation/validationPatterns.ts": "865f3d688975b7c8",
169
- "src/version.ts": "d2ac361c506b072c",
172
+ "src/version.ts": "d71e0506ffdb38e9",
170
173
  "../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
171
- "package.json": "175b4806c4526e18",
174
+ "package.json": "f4ee64b559581220",
172
175
  "tsconfig.json": "1929cf3f99fe9b1e"
173
176
  },
174
- "outputHash": "328c5bda6ca2ae851022ef763790754a86c127a24c8de327ca3ed6ab00291f65",
175
- "outputFileCount": 313
177
+ "outputHash": "d02bb6d6b912e1f596139d1e3aaeb46f7c3660eca2e2b1669d3773442663b6ef",
178
+ "outputFileCount": 319
176
179
  }
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 156 files minified at 2026-08-09T06:27:43.898Z
1
+ 159 files minified at 2026-08-11T21:56:53.001Z
@@ -216,6 +216,7 @@ export declare function parseAndConvert(code: string): {
216
216
  priority?: number | undefined;
217
217
  healthCheckPath?: string | undefined;
218
218
  }[] | undefined;
219
+ serviceType?: "web" | "worker" | undefined;
219
220
  cpu?: number | undefined;
220
221
  memoryLimitMiB?: number | undefined;
221
222
  desiredCount?: number | undefined;
@@ -1 +1 @@
1
- var S=Object.defineProperty;var a=(e,n)=>S(e,"name",{value:n,configurable:!0});import{isPlainObject as y,isParsedObject as s,isExpressionRef as C,isCallRef as h,asString as r,asNumber as i,asBoolean as f,asStringArray as m,asStringUnion as d,captureExtraProperties as p}from"../common/astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as E,LOAD_BALANCER_TYPES as P,SCALING_TYPES as _,AMI_HARDWARE_TYPES as x}from"../../../schemas/constants.js";function A(e){return e!==void 0&&y(e)}a(A,"isEnvironmentRecord");function N(e){if(!s(e))return;const n={};for(const[t,o]of Object.entries(e))if(s(o)){const c=r(o.id),u=r(o.name);c&&u&&(n[t]={id:c,name:u,field:r(o.field)})}return Object.keys(n).length>0?n:void 0}a(N,"parseContainerSecretsImport");function g(e){if(!s(e))return;const n=m(e.command);if(!(!n||n.length===0))return{command:n,interval:i(e.interval),timeout:i(e.timeout),retries:i(e.retries),startPeriod:i(e.startPeriod)}}a(g,"parseContainerHealthCheck");function O(e){const t=p(e,new Set(["name","image","port","environment","essential","command","entryPoint","secretsImport","secrets","healthCheck"]));return{name:r(e.name),image:r(e.image),port:i(e.port),environment:A(e.environment)?e.environment:void 0,essential:f(e.essential),command:m(e.command),entryPoint:m(e.entryPoint),secretsImport:N(e.secretsImport),ssmSecrets:m(e.secrets),healthCheck:g(e.healthCheck),extraProperties:t.length>0?t:void 0}}a(O,"parseServiceContainer");function T(e){if(Array.isArray(e))return e.filter(s).map(n=>({path:r(n.path),host:r(n.host),priority:i(n.priority),healthCheckPath:r(n.healthCheckPath)}));if(s(e))return{path:r(e.path),host:r(e.host),priority:i(e.priority),healthCheckPath:r(e.healthCheckPath)}}a(T,"parseServiceRouting");function I(e){if(e===!1)return!1;if(s(e))return{minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),desiredCount:i(e.desiredCount),scalingType:d(e.scalingType,_)}}a(I,"parseServiceScaling");const R=new Set(["instanceType","amiHardwareType","minCapacity","maxCapacity","memoryLimitMiB","warmPool"]);function l(e){if(!s(e))return;const n=e.warmPool,t=s(n)?{minSize:i(n.minSize),reuseOnScaleIn:f(n.reuseOnScaleIn)}:void 0,o=p(e,R);return{instanceType:r(e.instanceType),amiHardwareType:d(e.amiHardwareType,x),minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),memoryLimitMiB:i(e.memoryLimitMiB),warmPool:t,extraProperties:o.length>0?o:void 0}}a(l,"parseServiceEc2Config");const B=new Set(["domain","loadBalancer","directAccess"]);function k(e){if(!s(e))return;const n=e.loadBalancer,t=p(e,B);return{domain:r(e.domain),loadBalancer:n===!1?!1:d(n,P),directAccess:f(e.directAccess),...t.length>0&&{extraProperties:t}}}a(k,"extractClusterConfig");function W(e){const n=e.containers,t=Array.isArray(n)?n.filter(s).map(O):void 0,c=p(e,new Set(["name","image","docker","ssmSecretsPath","containers","routing","connections","cpu","memoryLimitMiB","desiredCount","scaling","capacityProvider","ec2Config"]));return{name:r(e.name)??"",image:r(e.image),docker:K(e.docker),ssmSecretsPath:r(e.ssmSecretsPath),containers:t,routing:T(e.routing),cpu:i(e.cpu),memoryLimitMiB:i(e.memoryLimitMiB),desiredCount:i(e.desiredCount),scaling:I(e.scaling),capacityProvider:d(e.capacityProvider,E)??"FARGATE",ec2Config:l(e.ec2Config),...c.length>0&&{extraProperties:c}}}a(W,"parseEcsService");function K(e){if(!s(e))return;const n=r(e.path);if(n===void 0)return;const t=r(e.context),o=r(e.target);return{path:n,...t!==void 0&&{context:t},...o!==void 0&&{target:o}}}a(K,"parseServiceDocker");function M(e,n){const t=r(e);if(t)return t;if(C(e)&&e.__expression.startsWith(n+"."))return e.__expression.slice(n.length+1)}a(M,"extractEnumString");function b(e){return h(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}a(b,"extractCallStringArg");function D(e,n,t){t!==void 0&&(e[n]=t)}a(D,"assignIfDefined");export{D as assignIfDefined,b as extractCallStringArg,k as extractClusterConfig,M as extractEnumString,A as isEnvironmentRecord,W as parseEcsService};
1
+ var S=Object.defineProperty;var a=(e,n)=>S(e,"name",{value:n,configurable:!0});import{isPlainObject as y,isParsedObject as s,isExpressionRef as C,isCallRef as h,asString as r,asNumber as i,asBoolean as f,asStringArray as d,asStringUnion as m,captureExtraProperties as p}from"../common/astCommonParser.js";import{ECS_CAPACITY_PROVIDERS as E,ECS_SERVICE_TYPES as P,LOAD_BALANCER_TYPES as _,SCALING_TYPES as x,AMI_HARDWARE_TYPES as A}from"../../../schemas/constants.js";function N(e){return e!==void 0&&y(e)}a(N,"isEnvironmentRecord");function T(e){if(!s(e))return;const n={};for(const[t,o]of Object.entries(e))if(s(o)){const c=r(o.id),u=r(o.name);c&&u&&(n[t]={id:c,name:u,field:r(o.field)})}return Object.keys(n).length>0?n:void 0}a(T,"parseContainerSecretsImport");function g(e){if(!s(e))return;const n=d(e.command);if(!(!n||n.length===0))return{command:n,interval:i(e.interval),timeout:i(e.timeout),retries:i(e.retries),startPeriod:i(e.startPeriod)}}a(g,"parseContainerHealthCheck");function O(e){const t=p(e,new Set(["name","image","port","environment","essential","command","entryPoint","secretsImport","secrets","healthCheck"]));return{name:r(e.name),image:r(e.image),port:i(e.port),environment:N(e.environment)?e.environment:void 0,essential:f(e.essential),command:d(e.command),entryPoint:d(e.entryPoint),secretsImport:T(e.secretsImport),ssmSecrets:d(e.secrets),healthCheck:g(e.healthCheck),extraProperties:t.length>0?t:void 0}}a(O,"parseServiceContainer");function I(e){if(Array.isArray(e))return e.filter(s).map(n=>({path:r(n.path),host:r(n.host),priority:i(n.priority),healthCheckPath:r(n.healthCheckPath)}));if(s(e))return{path:r(e.path),host:r(e.host),priority:i(e.priority),healthCheckPath:r(e.healthCheckPath)}}a(I,"parseServiceRouting");function R(e){if(e===!1)return!1;if(s(e))return{minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),desiredCount:i(e.desiredCount),scalingType:m(e.scalingType,x)}}a(R,"parseServiceScaling");const l=new Set(["instanceType","amiHardwareType","minCapacity","maxCapacity","memoryLimitMiB","warmPool"]);function B(e){if(!s(e))return;const n=e.warmPool,t=s(n)?{minSize:i(n.minSize),reuseOnScaleIn:f(n.reuseOnScaleIn)}:void 0,o=p(e,l);return{instanceType:r(e.instanceType),amiHardwareType:m(e.amiHardwareType,A),minCapacity:i(e.minCapacity),maxCapacity:i(e.maxCapacity),memoryLimitMiB:i(e.memoryLimitMiB),warmPool:t,extraProperties:o.length>0?o:void 0}}a(B,"parseServiceEc2Config");const K=new Set(["domain","loadBalancer","directAccess"]);function W(e){if(!s(e))return;const n=e.loadBalancer,t=p(e,K);return{domain:r(e.domain),loadBalancer:n===!1?!1:m(n,_),directAccess:f(e.directAccess),...t.length>0&&{extraProperties:t}}}a(W,"extractClusterConfig");function M(e){const n=e.containers,t=Array.isArray(n)?n.filter(s).map(O):void 0,c=p(e,new Set(["name","image","docker","ssmSecretsPath","containers","routing","connections","serviceType","cpu","memoryLimitMiB","desiredCount","scaling","capacityProvider","ec2Config"]));return{name:r(e.name)??"",image:r(e.image),docker:w(e.docker),ssmSecretsPath:r(e.ssmSecretsPath),containers:t,routing:I(e.routing),serviceType:m(e.serviceType,P),cpu:i(e.cpu),memoryLimitMiB:i(e.memoryLimitMiB),desiredCount:i(e.desiredCount),scaling:R(e.scaling),capacityProvider:m(e.capacityProvider,E)??"FARGATE",ec2Config:B(e.ec2Config),...c.length>0&&{extraProperties:c}}}a(M,"parseEcsService");function w(e){if(!s(e))return;const n=r(e.path);if(n===void 0)return;const t=r(e.context),o=r(e.target);return{path:n,...t!==void 0&&{context:t},...o!==void 0&&{target:o}}}a(w,"parseServiceDocker");function b(e,n){const t=r(e);if(t)return t;if(C(e)&&e.__expression.startsWith(n+"."))return e.__expression.slice(n.length+1)}a(b,"extractEnumString");function D(e){return h(e)?e.__call.match(/\(\s*"([^"]+)"\s*\)/)?.[1]:void 0}a(D,"extractCallStringArg");function H(e,n,t){t!==void 0&&(e[n]=t)}a(H,"assignIfDefined");export{H as assignIfDefined,D as extractCallStringArg,W as extractClusterConfig,b as extractEnumString,N as isEnvironmentRecord,M as parseEcsService};
@@ -1 +1 @@
1
- var D=Object.defineProperty;var u=(r,e)=>D(r,"name",{value:e,configurable:!0});import{failure as t,success as P}from"../../types/Result.js";import{DEFAULT_FILE_PATH as F,computeLinesDelta as M,extractProgramBody as C,isRecord as v}from"../_internal.js";import{evaluateEmitGuard as x}from"../emitGuard.js";import{projectEmittedProperties as w}from"../emitProjection.js";import{appendSpecifier as G,buildAppMethodWrappedStatement as N,buildFactoryStatement as Q,buildImportDeclaration as B,detectQuoteStyle as U,parse as _,printFile as O}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as W}from"../registry.js";import{locateAllShapes as j,locateByShape as Y}from"../semanticIndex/index.js";import{checkControlFlowPolicy as q}from"./controlFlowPolicy.js";import{driftGate as H,runPipeline as $,schemaGate as z}from"../validationGate/index.js";import{resolveAppBindingName as J}from"./addResource/appBinding.js";import{buildUnmanagedDuplicateError as K}from"./unmanagedShapeErrors.js";import{buildResourceLocations as V,indexBody as X,orderByEndPos as Z,resolveInsertIndex as ee}from"./addResource/bodyIndex.js";import{buildPropertyInputs as re}from"./addResource/propertyBuilder.js";import{findInsertionPosition as te}from"./findInsertionPosition.js";const k="@fjall/components-infrastructure";function ge(r,e,m={}){const s=e.filePath??F,o=_(r,s);if(!o.success)return t(o.error);const a=Y(r,{type:e.type,name:e.name},s);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?t(a.error):t({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data!==void 0){if(a.data.managed===!1)return t(K(e.type,a.data.symbolName));const d=q({ast:o.data,target:a.data,resource:{type:e.type,name:e.name},op:"add"});if(d.refusal!==void 0)return t(d.refusal);const h=$([z,H],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"},baseline:m.baseline,policy:e.driftPolicy});return h.success?h.data.action==="skip"?P({content:r,linesChanged:{added:0,removed:0},skipped:!0}):t({kind:"DuplicateResourceError",type:e.type,name:e.name}):t(ae(h.error))}const f=U(o.data),l=w(e.type,e.properties);if("refusal"in l)return t(l.refusal);const y=re(l.props,f);if(!y.success)return t(y.error);const c=C(o.data);if(c===void 0)return t({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const i=W[e.type],I=x(i.emitGuard,e.properties);if(I!==void 0)return t(I);const S={factory:i.factoryIdentifier,name:e.name,properties:y.data,quoteStyle:f};let E;if(i.emitWrapper!==void 0){const d=J(c);if(d===void 0)return t({kind:"MissingAppInitError",type:e.type,appMethod:i.emitWrapper.appMethod});E=N({...S,appIdentifier:d,appMethod:i.emitWrapper.appMethod})}else E=Q(S);const p=X(c,r),n=j(r,s);if(!n.success)return n.error.kind==="TemplateLiteralNameError"?t(n.error):t({kind:"SemanticQueryError",reason:n.error.reason,cause:n.error.cause});const L=V(p.anchors,n.data),R=Z([...p.appInitLocations,...L]),b=te(p.importInfos,R,e.type,p.programEnd),T=ee(p.anchors,b);c.splice(T,0,E),oe(c,i.factoryIdentifier,f);const g=O(o.data,r),A=M(r,g);return P({content:g,linesChanged:A})}u(ge,"addResource");function ae(r){switch(r.kind){case"ParseError":case"TemplateLiteralNameError":case"DuplicateResourceError":case"InvalidPropertyError":case"SemanticQueryError":case"MissingAppInitError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}u(ae,"narrowGateError");function oe(r,e,m){for(const o of r){if(o.type!=="ImportDeclaration")continue;const a=o.source;if(!(!v(a)||a.type!=="StringLiteral")&&a.value===k){G(o,e);return}}const s=B([e],k,m);r.unshift(s)}u(oe,"ensureFactoryImport");export{ge as addResource};
1
+ var M=Object.defineProperty;var u=(r,e)=>M(r,"name",{value:e,configurable:!0});import{failure as t,success as k}from"../../types/Result.js";import{DEFAULT_FILE_PATH as C,computeLinesDelta as v,extractProgramBody as x,isRecord as w}from"../_internal.js";import{evaluateEmitGuard as G}from"../emitGuard.js";import{projectEmittedProperties as N}from"../emitProjection.js";import{appendSpecifier as Q,buildAppMethodWrappedStatement as B,buildFactoryStatement as O,buildImportDeclaration as U,detectQuoteStyle as _,parse as W,printFile as j}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as Y}from"../registry.js";import{locateAllShapes as q,locateByShape as H}from"../semanticIndex/index.js";import{checkControlFlowPolicy as $}from"./controlFlowPolicy.js";import{driftGate as z,runPipeline as J,schemaGate as K}from"../validationGate/index.js";import{resolveAppBindingName as V}from"./addResource/appBinding.js";import{buildUnmanagedDuplicateError as X}from"./unmanagedShapeErrors.js";import{buildResourceLocations as Z,indexBody as ee,orderByEndPos as re,resolveInsertIndex as te}from"./addResource/bodyIndex.js";import{buildPropertyInputs as ae}from"./addResource/propertyBuilder.js";import{findInsertionPosition as ne}from"./findInsertionPosition.js";const L="@fjall/components-infrastructure";function Pe(r,e,m={}){const s=e.filePath??C,n=W(r,s);if(!n.success)return t(n.error);const a=H(r,{type:e.type,name:e.name},s);if(!a.success)return a.error.kind==="TemplateLiteralNameError"?t(a.error):t({kind:"SemanticQueryError",reason:a.error.reason,cause:a.error.cause});if(a.data!==void 0){if(a.data.managed===!1)return t(X(e.type,a.data.symbolName));const d=$({ast:n.data,target:a.data,resource:{type:e.type,name:e.name},op:"add"});if(d.refusal!==void 0)return t(d.refusal);const h=J([z],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"},baseline:m.baseline,policy:e.driftPolicy});return h.success?h.data.action==="skip"?k({content:r,linesChanged:{added:0,removed:0},skipped:!0}):t({kind:"DuplicateResourceError",type:e.type,name:e.name}):t(R(h.error))}const f=_(n.data),l=N(e.type,e.properties);if("refusal"in l)return t(l.refusal);const y=ae(l.props,f);if(!y.success)return t(y.error);const c=x(n.data);if(c===void 0)return t({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const o=Y[e.type],I=G(o.emitGuard,e.properties);if(I!==void 0)return t(I);const S=K.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"}});if(!S.success)return t(R(S.error));const g={factory:o.factoryIdentifier,name:e.name,properties:y.data,quoteStyle:f};let E;if(o.emitWrapper!==void 0){const d=V(c);if(d===void 0)return t({kind:"MissingAppInitError",type:e.type,appMethod:o.emitWrapper.appMethod});E=B({...g,appIdentifier:d,appMethod:o.emitWrapper.appMethod})}else E=O(g);const p=ee(c,r),i=q(r,s);if(!i.success)return i.error.kind==="TemplateLiteralNameError"?t(i.error):t({kind:"SemanticQueryError",reason:i.error.reason,cause:i.error.cause});const b=Z(p.anchors,i.data),T=re([...p.appInitLocations,...b]),A=ne(p.importInfos,T,e.type,p.programEnd),D=te(p.anchors,A);c.splice(D,0,E),oe(c,o.factoryIdentifier,f);const P=j(n.data,r),F=v(r,P);return k({content:P,linesChanged:F})}u(Pe,"addResource");function R(r){switch(r.kind){case"ParseError":case"TemplateLiteralNameError":case"DuplicateResourceError":case"InvalidPropertyError":case"SemanticQueryError":case"MissingAppInitError":case"DriftConflictError":case"ControlFlowClassifierError":return r;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${r.kind}`}}}u(R,"narrowGateError");function oe(r,e,m){for(const n of r){if(n.type!=="ImportDeclaration")continue;const a=n.source;if(!(!w(a)||a.type!=="StringLiteral")&&a.value===L){Q(n,e);return}}const s=U([e],L,m);r.unshift(s)}u(oe,"ensureFactoryImport");export{Pe as addResource};
@@ -1 +1 @@
1
- var x=Object.defineProperty;var u=(e,r)=>x(e,"name",{value:r,configurable:!0});import{failure as d,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as P,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 l,readKeyName as N}from"./modifyResource/literalConversion.js";import{findPropertyByKey as g}from"./objectGraph.js";const K="ACCOUNTS",V="workloads";function R(e,r){const i=r.filePath??P,t=r.constName??K,n=r.nestedKey??V,{stage:a,displayName:o}=r,s=C(e,i);if(!s.success)return d(s.error);const f=b(s.data);if(f===void 0)return d({kind:"InvalidStageTargetError",stage:a,reason:"recast File is missing program.body"});const m=O(f,t);if(m===void 0)return d({kind:"ConstNotFoundError",constName:t});const p=D(s.data),c=_(m,{constName:t,stage:a,nestedKey:n,displayName:o,quoteStyle:p});if(!c.success)return d(c.error);if(c.data.created)return T(s.data,e);const A=c.data.array;return A.elements.some(v=>l(v)&&I(v)===o)?y({content:e,linesChanged:{added:0,removed:0},skipped:!0}):(A.elements.push(L(o,p)),T(s.data,e))}u(R,"appendAccountToStage");function T(e,r){const i=F(e,r);return y({content:i,linesChanged:k(r,i)})}u(T,"printSuccess");function _(e,r){const{constName:i,stage:t,nestedKey:n,displayName:a,quoteStyle:o}=r,s=g(e,t);if(s!==void 0)return S(s.value)?y({created:!1,array:s.value}):d({kind:"InvalidStageTargetError",stage:t,reason:`Top-level "${t}" is not an array literal.`});const f=g(e,n);if(f!==void 0&&E(f.value)){const m=f.value,p=g(m,t);if(p!==void 0)return S(p.value)?y({created:!1,array:p.value}):d({kind:"InvalidStageTargetError",stage:t,reason:`Nested "${n}.${t}" is not an array literal.`});const c=$(m,t,a,o);return c.success?y({created:!0}):d(c.error)}return d({kind:"StageNotFoundError",constName:i,stage:t,knownStages:B(e,n)})}u(_,"resolveStageArray");function $(e,r,i,t){const n=w([i],t);if(n===void 0)return d({kind:"InvalidStageTargetError",stage:r,reason:`Unable to build an array literal for "${r}".`});const a=h(r,n,t);return e.properties[e.properties.length-1]?.extra?.trailingComma===!0&&(a.extra={...a.extra??{},trailingComma:!0}),e.properties.push(a),y(void 0)}u($,"appendStageProperty");function O(e,r){for(const i of e){const t=U(i);if(t===void 0)continue;const n=t.declarations;if(Array.isArray(n))for(const a of n){if(!l(a)||a.type!=="VariableDeclarator")continue;const o=a.id,s=j(a.init);if(l(o)&&o.type==="Identifier"&&o.name===r&&E(s))return s}}}u(O,"findConstObjectExpression");function U(e){if(e.type==="VariableDeclaration")return e;if(e.type==="ExportNamedDeclaration"){const r=e.declaration;if(l(r)&&r.type==="VariableDeclaration")return r}}u(U,"unwrapVariableDeclaration");function j(e){let r=e;for(;l(r)&&(r.type==="TSAsExpression"||r.type==="TSSatisfiesExpression");)r=r.expression;return r}u(j,"unwrapExpression");function B(e,r){const i=[];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&&E(t.value))for(const a of t.value.properties){const o=N(a.key);o!==void 0&&i.push(`${r}.${o}`)}else S(t.value)&&i.push(n)}return i}u(B,"collectStageKeys");function E(e){return l(e)&&e.type==="ObjectExpression"&&Array.isArray(e.properties)}u(E,"isObjectExpression");function S(e){return l(e)&&e.type==="ArrayExpression"&&Array.isArray(e.elements)}u(S,"isArrayExpression");export{R 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 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};
1
+ var T=Object.defineProperty;var d=(r,e)=>T(r,"name",{value:e,configurable:!0});import{failure as i,success as m}from"../../types/Result.js";import{DEFAULT_FILE_PATH as L,computeLinesDelta as F,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 D}from"../registry.js";import{locateAllShapes as I,locateByShape as O}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as V}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as B}from"./controlFlowPolicy.js";import{driftGate as K,runPipeline as _,schemaGate as M}from"../validationGate/index.js";import{toAstValue as $}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as k,collectPropertyKeys as H,isNodeShape as P}from"./modifyResource/literalConversion.js";import{findPropertyByKey as Y,visit as q}from"./objectGraph.js";import{evaluateEmitGuard as z,UNRESOLVED as J}from"../emitGuard.js";import{projectEmittedProperties as W,projectionRefusal as X}from"../emitProjection.js";function Ee(r,e,s={}){const n=e.filePath??L,t=Q(r,n);if(!t.success)return i(t.error);const a=O(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(V(e.type,"modify"));const o=B({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],{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(v(u.error));if(u.data.action==="skip")return m({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=k(f,e.properties),C=D[e.type].emitGuard,y=d(b=>z(C,b)??X(e.type,b),"judge"),R=y(S(f,k(f,{}))),l=y(S(f,x));if(l!==void 0&&l.property!==R?.property)return i(l);const g=M.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"}});if(!g.success)return i(v(g.error));const p=W(e.type,e.properties,{editingExisting:!0});if("refusal"in p)return i(p.refusal);const E=ee(f,p.props,w);if(!E.success)return i(E.error);const h=U(t.data,r),N=o.warning!==void 0?[o.warning.message]:void 0;return m({content:h,linesChanged:F(r,h),warnings:N})}d(Ee,"modifyResource");function S(r,e){const s={...e};for(const n of H(r))n in s||(s[n]=J);return s}d(S,"buildGuardView");function v(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(v,"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(!P(u)||u.type!=="StringLiteral"||u.start!==e.start||u.end!==s)return;const c=o[1];P(c)&&c.type==="ObjectExpression"&&(n=c)},"visitor");for(const a of r)if(q(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=$(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=Y(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 m(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};
@@ -22,3 +22,4 @@ export declare function buildModuleConstResolver(body: NodeShapeLike[]): ModuleC
22
22
  * expressionless template literal. `undefined` for anything else.
23
23
  */
24
24
  export declare function readStaticString(node: NodeShapeLike): string | undefined;
25
+ export declare function unwrapTsWrappers(node: NodeShapeLike): NodeShapeLike;
@@ -1 +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};
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};
@@ -19,6 +19,12 @@ export declare function findPropertyByKey(obj: ObjectExpressionNodeLike, key: st
19
19
  * one depending on source order.
20
20
  */
21
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;
22
28
  /**
23
29
  * Non-recursive depth-first walk over every typed node reachable from `root`.
24
30
  *
@@ -1 +1 @@
1
- var f=Object.defineProperty;var s=(t,r)=>f(t,"name",{value:r,configurable:!0});import{isRecord as u}from"../_internal.js";import{readKeyName as c}from"./modifyResource/literalConversion.js";function d(t,r){return t.properties.find(e=>(e.type==="Property"||e.type==="ObjectProperty")&&e.shorthand!==!0&&e.computed!==!0&&c(e.key)===r)}s(d,"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&&c(e.key)===r)}s(h,"objectAbsenceIsProvable");function l(t,r){const e=[t];for(;e.length>0;){const n=e.pop();if(u(n)){typeof n.type=="string"&&r(n);for(const o of Object.keys(n)){if(o==="loc"||o==="comments"||o==="tokens")continue;const i=n[o];if(Array.isArray(i))for(const y of i)u(y)&&e.push(y);else u(i)&&e.push(i)}}}}s(l,"visit");export{d as findPropertyByKey,h as objectAbsenceIsProvable,l as visit};
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};
@@ -1 +1 @@
1
- var I=Object.defineProperty;var d=(t,e)=>I(t,"name",{value:e,configurable:!0});import{failure as a,success as m}from"../../types/Result.js";import{DEFAULT_FILE_PATH as _,computeLinesDelta as D,extractProgramBody as M}from"../_internal.js";import{buildObjectProperty as R,detectQuoteStyle as B,parse as K,printFile as q}from"../fileRewriter/index.js";import{makeStringLiteral as H,toAstValue as J}from"./addResource/propertyBuilder.js";import{astToLiteral as W,isNodeShape as v,NON_LITERAL as Y,readKeyName as z}from"./modifyResource/literalConversion.js";import{buildModuleConstResolver as Q}from"./moduleConstResolver.js";import{findPropertyByKey as A,visit as V}from"./objectGraph.js";import{checkSecretsImportConflicts as j,checkShadowingSpread as G,classifySecretsElement as X,describeElements as F,keyProvablyAbsent as Z}from"./secretsProvability.js";const N="ComputeFactory",ee="build",x="secrets";function ve(t,e){const n=e.filePath??_,{serviceName:r}=e,o=e.containerIndex??0,i=e.add??[],u=e.remove??[],c=K(t,n);if(!c.success)return a(c.error);const p=M(c.data);if(p===void 0)return a({kind:"UnsupportedSecretsShapeError",serviceName:r,reason:"recast File is missing program.body"});const l=re(p,r);if(!l.success)return a(l.error);const{service:y}=l.data,h=oe(y,r,o);if(!h.success)return a(h.error);const g=ie(y,r,e.expectedSsmSecretsPath),k=Q(p),b=ae(h.data,r,k,{add:i,remove:u,quoteStyle:B(c.data)});if(!b.success)return a(b.error);const{added:w,removed:C}=b.data,P=[...g,...b.data.warnings];return w.length===0&&C.length===0?m({content:t,linesChanged:{added:0,removed:0},added:[],removed:[],skipped:!0,warnings:P}):m({...te(c.data,t),added:w,removed:C,skipped:!1,warnings:P})}d(ve,"setContainerSecrets");function te(t,e){const n=q(t,e);return{content:n,linesChanged:D(e,n)}}d(te,"printResult");function re(t,e){const n=[],r=[];for(const i of ne(t)){const u=A(i,"services");if(!(u===void 0||!$(u.value)))for(const c of u.value.elements){if(!v(c)||c.type!=="ObjectExpression")continue;const p=c,l=U(p,"name");l!==void 0&&(l===e?r.push(p):n.push(l))}}const[o]=r;return r.length>1?a(S(e,`${String(r.length)} services share the name "${e}" across ComputeFactory.build calls \u2014 the edit cannot be proven to target the right one. Edit the file by hand.`)):o!==void 0?m({service:o}):a({kind:"ServiceNotFoundError",serviceName:e,knownServices:n})}d(re,"locateService");function ne(t){const e=[];for(const n of t)V(n,r=>{if(r.type!=="CallExpression"||!se(r))return;const o=r.arguments;if(!Array.isArray(o))return;const i=o[1];v(i)&&i.type==="ObjectExpression"&&e.push(i)});return e}d(ne,"collectComputeConfigs");function se(t){const e=t.callee;if(!v(e)||e.type!=="MemberExpression"||e.computed===!0)return!1;const n=e.object,r=e.property;return v(n)&&n.type==="Identifier"&&n.name===N&&v(r)&&r.type==="Identifier"&&r.name===ee}d(se,"isComputeFactoryBuild");function oe(t,e,n){const r=A(t,"containers");if(r===void 0||!$(r.value))return a({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Service has no `containers` array literal."});const o=r.value.elements,i=o[n];return i===void 0?a({kind:"ContainerNotFoundError",serviceName:e,containerIndex:n,containerCount:o.length}):!v(i)||i.type!=="ObjectExpression"?a({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:`Container ${String(n)} is not an object literal.`}):m(i)}d(oe,"resolveContainer");function ie(t,e,n){if(n===void 0)return[];const r=U(t,"ssmSecretsPath");return r===void 0||r===n?[]:[`Service "${e}" declares ssmSecretsPath "${r}", but the secrets were written under "${n}". The task will read the declared path.`]}d(ie,"collectPathWarnings");function S(t,e){return{kind:"UnsupportedSecretsShapeError",serviceName:t,reason:e}}d(S,"unsupported");function ae(t,e,n,r){const{add:o,remove:i,quoteStyle:u}=r,c=ce(t,x);if(c===-1){if(!Z(t,x,n))return a(S(e,"Container carries a spread, shorthand or computed key that could supply `secrets` invisibly, so an absent property cannot be proven. Declare `secrets` explicitly first."));if(i.length>0&&o.length===0)return m({added:[],removed:[],warnings:[]});const h=O(o),g=j(t,h,n);if(!g.ok)return a(S(e,g.reason));const k=de(t,e,h,u);return k.success?m({...k.data,warnings:g.warnings}):k}const l=t.properties[c]?.value;if(!$(l))return a(S(e,"`secrets` is not an array literal."));const y=G(t,c,n);return y.ok?ue(l,t,e,n,r):a(S(e,y.reason))}d(ae,"applySecrets");function ce(t,e){for(let n=t.properties.length-1;n>=0;n--){const r=t.properties[n];if(r!==void 0&&(r.type==="Property"||r.type==="ObjectProperty")&&r.shorthand!==!0&&r.computed!==!0&&z(r.key)===e)return n}return-1}d(ce,"findLastPlainPropertyIndex");function de(t,e,n,r){const o=O(n);if(o.length===0)return m({added:[],removed:[]});const i=J(o,r);if(i===void 0)return a({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Unable to build a `secrets` array literal."});const u=R(x,i,r);return t.properties[t.properties.length-1]?.extra?.trailingComma===!0&&(u.extra={...u.extra??{},trailingComma:!0}),t.properties.push(u),m({added:o,removed:[]})}d(de,"createSecretsArray");function ue(t,e,n,r,o){const{add:i,remove:u,quoteStyle:c}=o,p=t.elements.map(s=>X(s,r)),l=p.filter(s=>s.kind==="unresolvable"),y=new Set(u);if(y.size>0){if(l.length>0)return a(S(n,`\`secrets\` contains ${F(l)}, which cannot be resolved to string literals in this file, so a removed name cannot be proven gone. Edit the array by hand.`));for(const s of p){if(s.kind!=="spread")continue;const E=s.names.filter(f=>y.has(f));if(E.length>0){const f=E.map(T=>JSON.stringify(T)).join(", "),L=E.length===1?"is":"are";return a(S(n,`${f} ${L} supplied by \`${s.description}\`, so this edit cannot undeclare it \u2014 the shared array may feed other services. Edit \`${s.description.slice(3)}\` by hand.`))}}}const h=[],g=[];t.elements=t.elements.filter((s,E)=>{const f=p[E];return f!==void 0&&(f.kind==="literal"||f.kind==="identifier")&&y.has(f.name)?(h.push(f.name),!1):(f!==void 0&&g.push(f),!0)});const k=new Set(g.flatMap(s=>s.kind==="unresolvable"?[]:s.kind==="spread"?[...s.names]:[s.name])),b=O(i).filter(s=>!k.has(s));if(b.length===0)return m({added:[],removed:h,warnings:[]});const w=g.filter(s=>s.kind==="unresolvable");if(w.length>0){const s=b.map(E=>JSON.stringify(E)).join(", ");return a(S(n,`\`secrets\` contains ${F(w)}, which cannot be resolved in this file, so ${s} cannot be proven absent \u2014 a duplicate name breaks \`fjall deploy\` at synth. Add it by hand.`))}const C=j(e,b,r);if(!C.ok)return a(S(n,C.reason));const P=[];for(const s of b)t.elements.push(H(s,c)),P.push(s);return m({added:P,removed:h,warnings:C.warnings})}d(ue,"mutateSecretsArray");function U(t,e){const n=A(t,e);if(n===void 0||!v(n.value))return;const r=W(n.value);return r===Y||typeof r!="string"?void 0:r}d(U,"readStringProperty");function $(t){return v(t)&&t.type==="ArrayExpression"&&Array.isArray(t.elements)}d($,"isArrayExpression");function O(t){return[...new Set(t)]}d(O,"dedupe");export{ve as setContainerSecrets};
1
+ var x=Object.defineProperty;var d=(r,e)=>x(r,"name",{value:e,configurable:!0});import{failure as o,success as l}from"../../types/Result.js";import{DEFAULT_FILE_PATH as L,computeLinesDelta as O,extractProgramBody as I}from"../_internal.js";import{buildObjectProperty as R,detectQuoteStyle as T,parse as D,printFile as _}from"../fileRewriter/index.js";import{makeStringLiteral as q,toAstValue as B}from"./addResource/propertyBuilder.js";import{findLastPlainPropertyIndex as J,isArrayExpression as M,locateContainer as W,locateServiceByName as z,readStringProperty as H}from"./computeServiceLocator.js";import{buildModuleConstResolver as K}from"./moduleConstResolver.js";import{pushPropertyPreservingComma as Q}from"./objectGraph.js";import{checkSecretsImportConflicts as A,checkShadowingSpread as V,classifySecretsElement as Y,describeElements as U,keyProvablyAbsent as G}from"./secretsProvability.js";const P="secrets";function fe(r,e){const t=e.filePath??L,{serviceName:n}=e,i=e.containerIndex??0,g=e.add??[],b=e.remove??[],a=D(r,t);if(!a.success)return o(a.error);const y=I(a.data);if(y===void 0)return o({kind:"UnsupportedSecretsShapeError",serviceName:n,reason:"recast File is missing program.body"});const p=Z(y,n);if(!p.success)return o(p.error);const{service:f}=p.data,u=N(f,n,i);if(!u.success)return o(u.error);const h=ee(f,n,e.expectedSsmSecretsPath),k=K(y),m=re(u.data,n,k,{add:g,remove:b,quoteStyle:T(a.data)});if(!m.success)return o(m.error);const{added:C,removed:w}=m.data,E=[...h,...m.data.warnings];return C.length===0&&w.length===0?l({content:r,linesChanged:{added:0,removed:0},added:[],removed:[],skipped:!0,warnings:E}):l({...X(a.data,r),added:C,removed:w,skipped:!1,warnings:E})}d(fe,"setContainerSecrets");function X(r,e){const t=_(r,e);return{content:t,linesChanged:O(e,t)}}d(X,"printResult");function Z(r,e){const t=z(r,e);if(t.success)return l({service:t.data});const n=t.error;return n.kind==="AmbiguousService"?o(S(e,`${String(n.count)} services share the name "${e}" across ComputeFactory.build calls \u2014 the edit cannot be proven to target the right one. Edit the file by hand.`)):o({kind:"ServiceNotFoundError",serviceName:e,knownServices:n.knownServices})}d(Z,"locateService");function N(r,e,t){const n=W(r,t);if(n.success)return l(n.data);const i=n.error;switch(i.kind){case"NoContainersArray":return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Service has no `containers` array literal."});case"ContainersNotStaticArray":return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Service's `containers` is not a static array literal."});case"ContainerIndexOutOfRange":return o({kind:"ContainerNotFoundError",serviceName:e,containerIndex:t,containerCount:i.containerCount});case"ContainerNotObjectLiteral":return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:`Container ${String(t)} is not an object literal.`})}}d(N,"resolveContainer");function ee(r,e,t){if(t===void 0)return[];const n=H(r,"ssmSecretsPath");return n===void 0||n===t?[]:[`Service "${e}" declares ssmSecretsPath "${n}", but the secrets were written under "${t}". The task will read the declared path.`]}d(ee,"collectPathWarnings");function S(r,e){return{kind:"UnsupportedSecretsShapeError",serviceName:r,reason:e}}d(S,"unsupported");function re(r,e,t,n){const{add:i,remove:g,quoteStyle:b}=n,a=J(r,P);if(a===-1){if(!G(r,P,t))return o(S(e,"Container carries a spread, shorthand or computed key that could supply `secrets` invisibly, so an absent property cannot be proven. Declare `secrets` explicitly first."));if(g.length>0&&i.length===0)return l({added:[],removed:[],warnings:[]});const u=$(i),h=A(r,u,t);if(!h.ok)return o(S(e,h.reason));const k=te(r,e,u,b);return k.success?l({...k.data,warnings:h.warnings}):k}const p=r.properties[a]?.value;if(!M(p))return o(S(e,"`secrets` is not an array literal."));const f=V(r,a,t);return f.ok?ne(p,r,e,t,n):o(S(e,f.reason))}d(re,"applySecrets");function te(r,e,t,n){const i=$(t);if(i.length===0)return l({added:[],removed:[]});const g=B(i,n);if(g===void 0)return o({kind:"UnsupportedSecretsShapeError",serviceName:e,reason:"Unable to build a `secrets` array literal."});const b=R(P,g,n);return Q(r,b),l({added:i,removed:[]})}d(te,"createSecretsArray");function ne(r,e,t,n,i){const{add:g,remove:b,quoteStyle:a}=i,y=r.elements.map(s=>Y(s,n)),p=y.filter(s=>s.kind==="unresolvable"),f=new Set(b);if(f.size>0){if(p.length>0)return o(S(t,`\`secrets\` contains ${U(p)}, which cannot be resolved to string literals in this file, so a removed name cannot be proven gone. Edit the array by hand.`));for(const s of y){if(s.kind!=="spread")continue;const v=s.names.filter(c=>f.has(c));if(v.length>0){const c=v.map(j=>JSON.stringify(j)).join(", "),F=v.length===1?"is":"are";return o(S(t,`${c} ${F} supplied by \`${s.description}\`, so this edit cannot undeclare it \u2014 the shared array may feed other services. Edit \`${s.description.slice(3)}\` by hand.`))}}}const u=[],h=[];r.elements=r.elements.filter((s,v)=>{const c=y[v];return c!==void 0&&(c.kind==="literal"||c.kind==="identifier")&&f.has(c.name)?(u.push(c.name),!1):(c!==void 0&&h.push(c),!0)});const k=new Set(h.flatMap(s=>s.kind==="unresolvable"?[]:s.kind==="spread"?[...s.names]:[s.name])),m=$(g).filter(s=>!k.has(s));if(m.length===0)return l({added:[],removed:u,warnings:[]});const C=h.filter(s=>s.kind==="unresolvable");if(C.length>0){const s=m.map(v=>JSON.stringify(v)).join(", ");return o(S(t,`\`secrets\` contains ${U(C)}, which cannot be resolved in this file, so ${s} cannot be proven absent \u2014 a duplicate name breaks \`fjall deploy\` at synth. Add it by hand.`))}const w=A(e,m,n);if(!w.ok)return o(S(t,w.reason));const E=[];for(const s of m)r.elements.push(q(s,a)),E.push(s);return l({added:E,removed:u,warnings:w.warnings})}d(ne,"mutateSecretsArray");function $(r){return[...new Set(r)]}d($,"dedupe");export{fe as setContainerSecrets};
@@ -36,12 +36,11 @@ export interface EmitGuardRule {
36
36
  /**
37
37
  * Standard tail for a refusal with no in-vocabulary alternative.
38
38
  *
39
- * It deliberately does NOT name a construct-prop spelling that would work
40
- * as an unvalidated passthrough (`fjall add` performs no property-key
41
- * validation today, so `--memorySize` or `--originType` reach the emitted
42
- * object untouched). Advertising those would document a surface no schema
43
- * checks and no test pins, and it would go stale the moment the schema gate
44
- * stops being a no-op. Hand-authoring is always correct.
39
+ * It deliberately does NOT name a construct-prop spelling: the schema gate
40
+ * validates property keys against the PLAN schemas, so `--memorySize` or
41
+ * `--originType` are refused as unrecognised keys a construct-vocabulary
42
+ * spelling is not an alternative the operator can reach. Hand-authoring is
43
+ * always correct.
45
44
  */
46
45
  export declare const AUTHOR_BY_HAND: string;
47
46
  /** True when the key holds a value the codemod itself could have written. */
@@ -3,6 +3,7 @@ export { removeResource, type RemoveResourceError, type RemoveResourceSuccess, }
3
3
  export { modifyResource, type ModifyResourceCallContext, type ModifyResourceError, type ModifyResourceSuccess, } from "./edits/modifyResource.js";
4
4
  export { appendAccountToStage, type AppendAccountToStageError, type AppendAccountToStageOptions, type AppendAccountToStageSuccess, } from "./edits/appendAccountToStage.js";
5
5
  export { setContainerSecrets, type SetContainerSecretsError, type SetContainerSecretsOptions, type SetContainerSecretsSuccess, } from "./edits/setContainerSecrets.js";
6
+ export { connectResourceToCompute, type ConnectableResourceType, type ConnectResourceError, type ConnectResourceOptions, type ConnectResourceSuccess, } from "./edits/connectResourceToCompute.js";
6
7
  export { addVpcPeer, modifyVpcPeer, removeVpcPeer, type VpcPeerAddOptions, type VpcPeerModifyOptions, type VpcPeerOrchestratorSuccess, type VpcPeerRemoveOptions, } from "./edits/vpcPeer.js";
7
8
  export { addVpcPeerAccepter, modifyVpcPeerAccepter, removeVpcPeerAccepter, type VpcPeerAccepterAddOptions, type VpcPeerAccepterModifyOptions, type VpcPeerAccepterOrchestratorSuccess, type VpcPeerAccepterRemoveOptions, } from "./edits/vpcPeerAccepter.js";
8
9
  export { addCrossPlanConnection, modifyCrossPlanConnection, removeCrossPlanConnection, type CrossPlanConnectionAddOptions, type CrossPlanConnectionModifyOptions, type CrossPlanConnectionOrchestratorSuccess, type CrossPlanConnectionRemoveOptions, } from "./edits/crossPlanConnection.js";