@fjall/generator 0.95.0 → 0.99.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 (166) hide show
  1. package/dist/.minified +1 -1
  2. package/dist/src/ast/astClickHouseParser.d.ts +25 -0
  3. package/dist/src/ast/astClickHouseParser.js +1 -0
  4. package/dist/src/ast/astCodeInjection.d.ts +9 -0
  5. package/dist/src/ast/astCodeInjection.js +8 -0
  6. package/dist/src/ast/astComputeParser.js +1 -1
  7. package/dist/src/ast/astComputeParserHelpers.js +1 -1
  8. package/dist/src/ast/astDatabaseParser.d.ts +5 -2
  9. package/dist/src/ast/astDatabaseParser.js +1 -1
  10. package/dist/src/ast/astInfrastructureParser.d.ts +7 -1
  11. package/dist/src/ast/astInfrastructureParser.js +1 -1
  12. package/dist/src/ast/astPlanConverter.js +2 -2
  13. package/dist/src/ast/astScheduleParser.d.ts +18 -0
  14. package/dist/src/ast/astScheduleParser.js +1 -0
  15. package/dist/src/ast/astStatementClassifier.d.ts +2 -2
  16. package/dist/src/ast/astStatementClassifier.js +1 -1
  17. package/dist/src/ast/astStatementQueries.d.ts +4 -4
  18. package/dist/src/ast/astStatementQueries.js +3 -3
  19. package/dist/src/ast/astSurgicalModification.d.ts +14 -12
  20. package/dist/src/ast/astSurgicalModification.js +6 -13
  21. package/dist/src/ast/astTestHelpers.d.ts +41 -7
  22. package/dist/src/ast/index.d.ts +3 -2
  23. package/dist/src/ast/index.js +1 -1
  24. package/dist/src/codemod/_internal.d.ts +6 -1
  25. package/dist/src/codemod/_internal.js +1 -1
  26. package/dist/src/codemod/drift/detect.d.ts +11 -0
  27. package/dist/src/codemod/drift/detect.js +1 -0
  28. package/dist/src/codemod/drift/index.d.ts +4 -0
  29. package/dist/src/codemod/drift/index.js +1 -0
  30. package/dist/src/codemod/drift/merge.d.ts +19 -0
  31. package/dist/src/codemod/drift/merge.js +1 -0
  32. package/dist/src/codemod/drift/snapshot.d.ts +4 -0
  33. package/dist/src/codemod/drift/snapshot.js +1 -0
  34. package/dist/src/codemod/drift/types.d.ts +60 -0
  35. package/dist/src/codemod/drift/types.js +1 -0
  36. package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +1 -1
  37. package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -1
  38. package/dist/src/codemod/edits/addResource.d.ts +8 -3
  39. package/dist/src/codemod/edits/addResource.js +1 -1
  40. package/dist/src/codemod/edits/controlFlowPolicy.d.ts +19 -0
  41. package/dist/src/codemod/edits/controlFlowPolicy.js +1 -0
  42. package/dist/src/codemod/edits/crossPlanConnection.d.ts +20 -0
  43. package/dist/src/codemod/edits/crossPlanConnection.js +1 -0
  44. package/dist/src/codemod/edits/driftPolicy.d.ts +7 -0
  45. package/dist/src/codemod/edits/driftPolicy.js +1 -0
  46. package/dist/src/codemod/edits/findInsertionPosition.js +1 -1
  47. package/dist/src/codemod/edits/index.d.ts +3 -0
  48. package/dist/src/codemod/edits/index.js +1 -1
  49. package/dist/src/codemod/edits/modifyResource.d.ts +9 -3
  50. package/dist/src/codemod/edits/modifyResource.js +1 -1
  51. package/dist/src/codemod/edits/removeResource.d.ts +2 -2
  52. package/dist/src/codemod/edits/removeResource.js +1 -1
  53. package/dist/src/codemod/edits/vpcPeer.d.ts +24 -0
  54. package/dist/src/codemod/edits/vpcPeer.js +1 -0
  55. package/dist/src/codemod/edits/vpcPeerAccepter.d.ts +20 -0
  56. package/dist/src/codemod/edits/vpcPeerAccepter.js +1 -0
  57. package/dist/src/codemod/index.d.ts +16 -4
  58. package/dist/src/codemod/index.js +1 -1
  59. package/dist/src/codemod/llmFallback/apply.d.ts +10 -0
  60. package/dist/src/codemod/llmFallback/apply.js +1 -0
  61. package/dist/src/codemod/llmFallback/claudeTier.d.ts +6 -0
  62. package/dist/src/codemod/llmFallback/claudeTier.js +1 -0
  63. package/dist/src/codemod/llmFallback/egressGate.d.ts +5 -0
  64. package/dist/src/codemod/llmFallback/egressGate.js +1 -0
  65. package/dist/src/codemod/llmFallback/egressGate.types.d.ts +9 -0
  66. package/dist/src/codemod/llmFallback/egressGate.types.js +0 -0
  67. package/dist/src/codemod/llmFallback/index.d.ts +6 -0
  68. package/dist/src/codemod/llmFallback/index.js +1 -0
  69. package/dist/src/codemod/llmFallback/morphTier.d.ts +2 -0
  70. package/dist/src/codemod/llmFallback/morphTier.js +3 -0
  71. package/dist/src/codemod/llmFallback/prompt.d.ts +12 -0
  72. package/dist/src/codemod/llmFallback/prompt.js +36 -0
  73. package/dist/src/codemod/llmFallback/runFallback.d.ts +13 -0
  74. package/dist/src/codemod/llmFallback/runFallback.js +1 -0
  75. package/dist/src/codemod/llmFallback/shouldTryFallback.d.ts +13 -0
  76. package/dist/src/codemod/llmFallback/shouldTryFallback.js +1 -0
  77. package/dist/src/codemod/llmFallback/signals.d.ts +4 -0
  78. package/dist/src/codemod/llmFallback/signals.js +1 -0
  79. package/dist/src/codemod/llmFallback/telemetryEvents.d.ts +141 -0
  80. package/dist/src/codemod/llmFallback/telemetryEvents.js +1 -0
  81. package/dist/src/codemod/llmFallback/tierRunner.d.ts +7 -0
  82. package/dist/src/codemod/llmFallback/tierRunner.js +1 -0
  83. package/dist/src/codemod/llmFallback/types.d.ts +104 -0
  84. package/dist/src/codemod/llmFallback/types.js +1 -0
  85. package/dist/src/codemod/registry.d.ts +4 -1
  86. package/dist/src/codemod/registry.js +1 -1
  87. package/dist/src/codemod/semanticIndex/classifyControlFlow.d.ts +2 -0
  88. package/dist/src/codemod/semanticIndex/classifyControlFlow.js +1 -0
  89. package/dist/src/codemod/semanticIndex/findReferences.js +2 -2
  90. package/dist/src/codemod/telemetry/errorKinds.d.ts +2 -0
  91. package/dist/src/codemod/telemetry/errorKinds.js +1 -0
  92. package/dist/src/codemod/types.d.ts +110 -1
  93. package/dist/src/codemod/types.js +1 -1
  94. package/dist/src/codemod/validationGate/gates/classify.d.ts +2 -0
  95. package/dist/src/codemod/validationGate/gates/classify.js +1 -0
  96. package/dist/src/codemod/validationGate/gates/drift.d.ts +2 -0
  97. package/dist/src/codemod/validationGate/gates/drift.js +1 -0
  98. package/dist/src/codemod/validationGate/gates/locate.d.ts +7 -0
  99. package/dist/src/codemod/validationGate/gates/locate.js +1 -0
  100. package/dist/src/codemod/validationGate/gates/parse.d.ts +2 -0
  101. package/dist/src/codemod/validationGate/gates/parse.js +1 -0
  102. package/dist/src/codemod/validationGate/gates/schema.d.ts +2 -0
  103. package/dist/src/codemod/validationGate/gates/schema.js +1 -0
  104. package/dist/src/codemod/validationGate/index.d.ts +6 -0
  105. package/dist/src/codemod/validationGate/index.js +1 -0
  106. package/dist/src/codemod/validationGate/types.d.ts +35 -0
  107. package/dist/src/codemod/validationGate/types.js +1 -0
  108. package/dist/src/detection/index.d.ts +148 -0
  109. package/dist/src/detection/index.js +1 -0
  110. package/dist/src/generation/common.d.ts +22 -0
  111. package/dist/src/generation/common.js +5 -4
  112. package/dist/src/generation/compute/ec2.d.ts +2 -0
  113. package/dist/src/generation/compute/ec2.js +4 -0
  114. package/dist/src/generation/compute/ecs.d.ts +2 -0
  115. package/dist/src/generation/compute/ecs.js +42 -0
  116. package/dist/src/generation/compute/lambda.d.ts +3 -0
  117. package/dist/src/generation/compute/lambda.js +26 -0
  118. package/dist/src/generation/compute/shared.d.ts +22 -0
  119. package/dist/src/generation/compute/shared.js +4 -0
  120. package/dist/src/generation/compute.d.ts +4 -5
  121. package/dist/src/generation/compute.js +6 -86
  122. package/dist/src/generation/database.d.ts +11 -0
  123. package/dist/src/generation/database.js +23 -12
  124. package/dist/src/generation/index.d.ts +1 -1
  125. package/dist/src/generation/index.js +1 -1
  126. package/dist/src/generation/infrastructure.js +5 -5
  127. package/dist/src/generation/storage.js +30 -30
  128. package/dist/src/index.d.ts +1 -1
  129. package/dist/src/index.js +1 -1
  130. package/dist/src/planning/index.d.ts +2 -1
  131. package/dist/src/planning/index.js +1 -1
  132. package/dist/src/planning/openNextPlanning.d.ts +38 -0
  133. package/dist/src/planning/openNextPlanning.js +1 -0
  134. package/dist/src/planning/resourceAddition.d.ts +5 -1
  135. package/dist/src/planning/resourceAddition.js +1 -1
  136. package/dist/src/planning/resourcePlanning.d.ts +0 -46
  137. package/dist/src/planning/resourcePlanning.js +1 -1
  138. package/dist/src/presets/clickhouseTierPreset.d.ts +35 -0
  139. package/dist/src/presets/clickhouseTierPreset.js +0 -0
  140. package/dist/src/presets/tierPresets.d.ts +5 -12
  141. package/dist/src/presets/tierPresets.js +1 -1
  142. package/dist/src/presets/tierTypes.d.ts +9 -19
  143. package/dist/src/schemas/applicationSchemas.d.ts +67 -8
  144. package/dist/src/schemas/applicationSchemas.js +1 -1
  145. package/dist/src/schemas/baseSchemas.d.ts +24 -5
  146. package/dist/src/schemas/baseSchemas.js +2 -2
  147. package/dist/src/schemas/computeSchemas.d.ts +108 -14
  148. package/dist/src/schemas/computeSchemas.js +1 -1
  149. package/dist/src/schemas/constants.d.ts +14 -0
  150. package/dist/src/schemas/constants.js +1 -1
  151. package/dist/src/schemas/databaseSchemas.d.ts +80 -0
  152. package/dist/src/schemas/databaseSchemas.js +1 -1
  153. package/dist/src/schemas/networkSchemas.d.ts +126 -11
  154. package/dist/src/schemas/networkSchemas.js +1 -1
  155. package/dist/src/schemas/patternSchemas.js +1 -1
  156. package/dist/src/schemas/sharedTypes.d.ts +1 -1
  157. package/dist/src/schemas/sharedTypes.js +1 -1
  158. package/dist/src/validation/patterns.d.ts +2 -318
  159. package/dist/src/validation/patterns.js +1 -1
  160. package/dist/src/validation/validationMessages.d.ts +315 -0
  161. package/dist/src/validation/validationMessages.js +1 -0
  162. package/dist/src/validation/validationPatterns.d.ts +34 -0
  163. package/dist/src/validation/validationPatterns.js +1 -0
  164. package/dist/src/version.d.ts +1 -1
  165. package/dist/src/version.js +1 -1
  166. package/package.json +19 -13
@@ -1 +1 @@
1
- import{isPlainObject as s,isIdentifierRef as a,isExpressionRef as o,isCallRef as t,isParsedObject as i,asString as n,asNumber as c,asBoolean as l,asStringArray as u,asStringUnion as p,captureExtraProperties as d}from"./astCommonParser.js";import{parseInfrastructure as m,convertToResourcePlan as g,classifyStatements as R,extractCustomCodeBlocks as y,findManagedResourcePosition as S,getLastManagedStatementOfType as x,getManagedResourcesByType as C}from"./astInfrastructureParser.js";import{addResourceSurgically as M,updateResourceSurgically as v,removeResourceSurgically as B,ensureImports as T,injectCustomCodeBlocks as b,validateModifiedFile as j}from"./astSurgicalModification.js";import{findDomainConstructCall as E,parseDomainProps as I,parseDomainErrorMessage as O,splitTopLevelArgs as k}from"./astDomainParser.js";export{M as addResourceSurgically,l as asBoolean,c as asNumber,n as asString,u as asStringArray,p as asStringUnion,d as captureExtraProperties,R as classifyStatements,g as convertToResourcePlan,T as ensureImports,y as extractCustomCodeBlocks,E as findDomainConstructCall,S as findManagedResourcePosition,x as getLastManagedStatementOfType,C as getManagedResourcesByType,b as injectCustomCodeBlocks,t as isCallRef,o as isExpressionRef,a as isIdentifierRef,i as isParsedObject,s as isPlainObject,O as parseDomainErrorMessage,I as parseDomainProps,m as parseInfrastructure,B as removeResourceSurgically,k as splitTopLevelArgs,v as updateResourceSurgically,j as validateModifiedFile};
1
+ import{isPlainObject as s,isIdentifierRef as o,isExpressionRef as a,isCallRef as t,isParsedObject as i,asString as n,asNumber as c,asBoolean as l,asStringArray as p,asStringUnion as u,captureExtraProperties as d}from"./astCommonParser.js";import{parseInfrastructure as m,convertToResourcePlan as g,classifyStatements as R,extractCustomCodeBlocks as x,findManagedResourcePosition as y,getLastManagedStatementOfType as S,getManagedResourcesByType as C}from"./astInfrastructureParser.js";import{addResourceSurgically as M,updateResourceSurgically as v,removeResourceSurgically as B}from"./astSurgicalModification.js";import{ensureImports as b,injectCustomCodeBlocks as j,validateModifiedFile as D}from"./astCodeInjection.js";import{findDomainConstructCall as I,parseDomainProps as O,parseDomainErrorMessage as k,splitTopLevelArgs as A}from"./astDomainParser.js";export{M as addResourceSurgically,l as asBoolean,c as asNumber,n as asString,p as asStringArray,u as asStringUnion,d as captureExtraProperties,R as classifyStatements,g as convertToResourcePlan,b as ensureImports,x as extractCustomCodeBlocks,I as findDomainConstructCall,y as findManagedResourcePosition,S as getLastManagedStatementOfType,C as getManagedResourcesByType,j as injectCustomCodeBlocks,t as isCallRef,a as isExpressionRef,o as isIdentifierRef,i as isParsedObject,s as isPlainObject,k as parseDomainErrorMessage,O as parseDomainProps,m as parseInfrastructure,B as removeResourceSurgically,A as splitTopLevelArgs,v as updateResourceSurgically,D as validateModifiedFile};
@@ -1,7 +1,12 @@
1
1
  import type { LinesChanged } from "./types.js";
2
2
  export declare const DEFAULT_FILE_PATH = "/__codemod__/input.ts";
3
3
  export declare function isRecord(value: unknown): value is Record<string, unknown>;
4
- export declare function extractProgramBody<T>(file: unknown): T[] | undefined;
4
+ /**
5
+ * @internal Runtime validates each element as `Record<string, unknown>` only.
6
+ * `T`'s extra shape is asserted at the type level — callers are responsible
7
+ * for ensuring the parsed AST nodes conform to the declared `T`.
8
+ */
9
+ export declare function extractProgramBody<T extends Record<string, unknown>>(file: unknown): T[] | undefined;
5
10
  /**
6
11
  * Bidirectional line-count delta between `before` and `after`. The source's
7
12
  * dominant line terminator is detected once; positive deltas map to
@@ -1 +1 @@
1
- import{detectLineTerminator as i}from"./fileRewriter/index.js";const c="/__codemod__/input.ts";function o(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function f(r){if(!o(r))return;const t=r.program;if(!o(t))return;const e=t.body;if(Array.isArray(e)&&e.every(n=>o(n)))return e}function d(r,t){return r.length===0?0:r.split(t).length}function a(r,t){const e=i(r),n=d(t,e)-d(r,e);return n>=0?{added:n,removed:0}:{added:0,removed:-n}}export{c as DEFAULT_FILE_PATH,a as computeLinesDelta,f as extractProgramBody,o as isRecord};
1
+ import{detectLineTerminator as i}from"./fileRewriter/index.js";const c="/__codemod__/input.ts";function o(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function f(r){if(!o(r))return;const t=r.program;if(!o(t))return;const e=t.body;if(Array.isArray(e)&&e.every(o))return e}function d(r,t){return r.length===0?0:r.split(t).length}function a(r,t){const e=i(r),n=d(t,e)-d(r,e);return n>=0?{added:n,removed:0}:{added:0,removed:-n}}export{c as DEFAULT_FILE_PATH,a as computeLinesDelta,f as extractProgramBody,o as isRecord};
@@ -0,0 +1,11 @@
1
+ import { type Result } from "../../types/Result.js";
2
+ import type { CodemodError, ResourceName, StatementType } from "../types.js";
3
+ import type { DriftState, ResourceSnapshot } from "./types.js";
4
+ export type DriftOp = "add" | "modify";
5
+ export interface DriftPlan {
6
+ type: StatementType;
7
+ name: ResourceName;
8
+ properties: Record<string, unknown>;
9
+ op: DriftOp;
10
+ }
11
+ export declare function detectDrift(content: string, plan: DriftPlan, baseline?: ResourceSnapshot): Result<DriftState, CodemodError>;
@@ -0,0 +1 @@
1
+ import{failure as c,success as m}from"../../types/Result.js";import{listResources as l}from"../listResources.js";import{mergeProperties as y}from"./merge.js";import{snapshotProperties as h}from"./snapshot.js";function R(o,e,n){const r=l(o);if(!r.success)return c(r.error);if(r.data.resources.find(s=>s.type===e.type&&s.name===e.name)===void 0)return e.op==="add"?m({resource:{type:e.type,name:e.name},deltas:[],summary:"clean"}):c({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:r.data.resources.filter(s=>s.type===e.type).map(s=>s.name)});const t=h(o,e.type,e.name);if(!t.success)return c(t.error);const i={...t.data.properties},d={...e.properties},u=n===void 0?void 0:{...n.properties},f=y(u,i,d),p=b(f.deltas,u!==void 0);return m({resource:{type:e.type,name:e.name},deltas:f.deltas,summary:p})}function b(o,e){if(o.length===0)return"clean";let n=!1,r=!1,a=!1,t=!1;for(const i of o)switch(i.verdict){case"conflict":n=!0;break;case"compatible":r=!0;break;case"clean":a=!0;break;case"no-op":t=!0;break}return n?"drifted-conflict":r?"drifted-compatible":t&&!a?"no-op":"clean"}export{R as detectDrift};
@@ -0,0 +1,4 @@
1
+ export { detectDrift, type DriftOp, type DriftPlan } from "./detect.js";
2
+ export { mergeProperties, type MergeResult } from "./merge.js";
3
+ export { snapshotProperties } from "./snapshot.js";
4
+ export { DriftPolicySchema, DriftStateSchema, PropertyDeltaSchema, ResourceSnapshotSchema, type DriftPolicy, type DriftState, type PropertyDelta, type ResourceSnapshot, } from "./types.js";
@@ -0,0 +1 @@
1
+ import{detectDrift as t}from"./detect.js";import{mergeProperties as m}from"./merge.js";import{snapshotProperties as a}from"./snapshot.js";import{DriftPolicySchema as f,DriftStateSchema as h,PropertyDeltaSchema as i,ResourceSnapshotSchema as s}from"./types.js";export{f as DriftPolicySchema,h as DriftStateSchema,i as PropertyDeltaSchema,s as ResourceSnapshotSchema,t as detectDrift,m as mergeProperties,a as snapshotProperties};
@@ -0,0 +1,19 @@
1
+ import type { PropertyDelta } from "./types.js";
2
+ export interface MergeResult {
3
+ merged: Record<string, unknown>;
4
+ deltas: PropertyDelta[];
5
+ }
6
+ /**
7
+ * 3-way merge for resource properties.
8
+ *
9
+ * Per-property verdicts:
10
+ * - `clean` — user untouched; apply Fjall's intent (or preserve base).
11
+ * - `no-op` — user edited the property to exactly match Fjall's intent.
12
+ * - `compatible` — user edited a property Fjall is not touching; keep user's.
13
+ * - `conflict` — user edited AND Fjall wants a different value.
14
+ *
15
+ * When `base` is undefined, falls back to a user-preserving 2-way merge:
16
+ * properties present in `theirs` but not `ours` are preserved; properties
17
+ * present in both with different values surface as `conflict`.
18
+ */
19
+ export declare function mergeProperties(base: Record<string, unknown> | undefined, theirs: Record<string, unknown>, ours: Record<string, unknown>): MergeResult;
@@ -0,0 +1 @@
1
+ import{isDeepStrictEqual as v}from"node:util";function P(e,t,n){const o=[...new Set([...e===void 0?[]:Object.keys(e),...Object.keys(t),...Object.keys(n)])].sort((r,u)=>r.localeCompare(u,"en")),i={},d=[];for(const r of o){const u=e!==void 0&&g(e,r),l=g(t,r),m=g(n,r),k=u?e[r]:void 0,p=l?t[r]:void 0,s=m?n[r]:void 0,y=e===void 0?j(l,p,m,s):b(u,k,l,p,m,s);d.push({property:r,base:k,theirs:p,ours:s,verdict:y.verdict}),y.merged.has&&(i[r]=y.merged.value)}return{merged:i,deltas:d}}function j(e,t,n,c){return!e&&n?f(c):e&&!n||v(t,c)?f(t):a()}function b(e,t,n,c,o,i){if(!e&&!n&&o)return f(i);if(e&&!n&&o)return a();const d=e===n&&v(t,c);return d&&o?f(i):d&&!o?f(t):o?n===o&&v(c,i)?{verdict:"no-op",merged:{has:!0,value:c}}:a():n?{verdict:"compatible",merged:{has:!0,value:c}}:{verdict:"compatible",merged:{has:!1}}}function f(e){return{verdict:"clean",merged:{has:!0,value:e}}}function a(){return{verdict:"conflict",merged:{has:!1}}}function g(e,t){return Object.prototype.hasOwnProperty.call(e,t)}export{P as mergeProperties};
@@ -0,0 +1,4 @@
1
+ import { type Result } from "../../types/Result.js";
2
+ import type { CodemodError, ResourceName, StatementType } from "../types.js";
3
+ import type { ResourceSnapshot } from "./types.js";
4
+ export declare function snapshotProperties(content: string, type: StatementType, name: ResourceName): Result<ResourceSnapshot, CodemodError>;
@@ -0,0 +1 @@
1
+ import{failure as a,success as y}from"../../types/Result.js";import{extractProgramBody as h,isRecord as p}from"../_internal.js";import{astToLiteral as g,isNodeShape as l,NON_LITERAL as k,readKeyName as b}from"../edits/modifyResource/literalConversion.js";import{parse as E}from"../fileRewriter/index.js";import{listResources as x}from"../listResources.js";import{STATEMENT_REGISTRY as N}from"../registry.js";function F(t,n,r){const e=x(t);if(!e.success)return a(e.error);const i=e.data.resources.find(o=>o.type===n&&o.name===r);if(i===void 0)return a({kind:"ResourceNotFoundError",type:n,name:r,knownNames:e.data.resources.filter(o=>o.type===n).map(o=>o.name)});const s=E(t,i.filePath);if(!s.success)return a(s.error);const c=h(s.data);if(c===void 0)return a({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=O(c,i);if(f===void 0)return a({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const u=new Set(Object.keys(N[n].schemaFragment.shape)),m={};for(const o of f.properties){if(o.type!=="Property"&&o.type!=="ObjectProperty"||o.shorthand===!0||o.computed===!0)continue;const d=b(o.key);d===void 0||!u.has(d)||o.value!==void 0&&(m[d]=j(o.value,t))}return y({type:n,name:r,properties:m,schemaVersion:1})}function O(t,n){const r=n.start+n.length;let e;const i=s=>{if(e!==void 0||s.type!=="CallExpression")return;const c=s.arguments;if(!Array.isArray(c)||c.length<2)return;const f=c[0];if(!l(f)||f.type!=="StringLiteral"||f.start!==n.start||f.end!==r)return;const u=c[1];l(u)&&u.type==="ObjectExpression"&&(e=u)};for(const s of t)if(v(s,i),e!==void 0)break;return e}function j(t,n){const r=g(t);return r!==k?r:S(t,n)}function S(t,n){const r=typeof t.start=="number"?t.start:void 0,e=typeof t.end=="number"?t.end:void 0;return{kind:"expression",text:r!==void 0&&e!==void 0&&r<e?n.slice(r,e):""}}function v(t,n){const r=[t];for(;r.length>0;){const e=r.pop();if(p(e)){typeof e.type=="string"&&n(e);for(const i of Object.keys(e)){if(i==="loc"||i==="comments"||i==="tokens")continue;const s=e[i];if(Array.isArray(s))for(const c of s)p(c)&&r.push(c);else p(s)&&r.push(s)}}}}export{F as snapshotProperties};
@@ -0,0 +1,60 @@
1
+ import { z } from "zod";
2
+ import { PropertyDeltaSchema } from "../types.js";
3
+ export { DriftPolicySchema, type DriftPolicy } from "../types.js";
4
+ export { PropertyDeltaSchema };
5
+ export declare const ResourceSnapshotSchema: z.ZodObject<{
6
+ type: z.ZodEnum<{
7
+ storage: "storage";
8
+ database: "database";
9
+ compute: "compute";
10
+ pattern: "pattern";
11
+ network: "network";
12
+ messaging: "messaging";
13
+ cdn: "cdn";
14
+ "vpc-peer": "vpc-peer";
15
+ "vpc-peer-accepter": "vpc-peer-accepter";
16
+ "cross-plan-connection": "cross-plan-connection";
17
+ }>;
18
+ name: z.ZodString;
19
+ properties: z.ZodRecord<z.ZodString, z.ZodUnknown>;
20
+ schemaVersion: z.ZodLiteral<1>;
21
+ }, z.core.$strict>;
22
+ export declare const DriftStateSchema: z.ZodObject<{
23
+ resource: z.ZodObject<{
24
+ type: z.ZodEnum<{
25
+ storage: "storage";
26
+ database: "database";
27
+ compute: "compute";
28
+ pattern: "pattern";
29
+ network: "network";
30
+ messaging: "messaging";
31
+ cdn: "cdn";
32
+ "vpc-peer": "vpc-peer";
33
+ "vpc-peer-accepter": "vpc-peer-accepter";
34
+ "cross-plan-connection": "cross-plan-connection";
35
+ }>;
36
+ name: z.ZodString;
37
+ }, z.core.$strict>;
38
+ deltas: z.ZodArray<z.ZodObject<{
39
+ property: z.ZodString;
40
+ base: z.ZodOptional<z.ZodUnknown>;
41
+ theirs: z.ZodUnknown;
42
+ ours: z.ZodUnknown;
43
+ verdict: z.ZodEnum<{
44
+ clean: "clean";
45
+ "no-op": "no-op";
46
+ compatible: "compatible";
47
+ conflict: "conflict";
48
+ }>;
49
+ }, z.core.$strict>>;
50
+ summary: z.ZodEnum<{
51
+ unknown: "unknown";
52
+ clean: "clean";
53
+ "no-op": "no-op";
54
+ "drifted-compatible": "drifted-compatible";
55
+ "drifted-conflict": "drifted-conflict";
56
+ }>;
57
+ }, z.core.$strict>;
58
+ export type PropertyDelta = z.infer<typeof PropertyDeltaSchema>;
59
+ export type ResourceSnapshot = z.infer<typeof ResourceSnapshotSchema>;
60
+ export type DriftState = z.infer<typeof DriftStateSchema>;
@@ -0,0 +1 @@
1
+ import{z as e}from"zod";import{PropertyDeltaSchema as t,ResourceNameSchema as r,StatementTypeSchema as o}from"../types.js";import{DriftPolicySchema as s}from"../types.js";const m=e.object({type:o,name:r,properties:e.record(e.string(),e.unknown()),schemaVersion:e.literal(1)}).strict(),n=e.object({resource:e.object({type:o,name:r}).strict(),deltas:e.array(t),summary:e.enum(["clean","no-op","drifted-compatible","drifted-conflict","unknown"])}).strict();export{s as DriftPolicySchema,n as DriftStateSchema,t as PropertyDeltaSchema,m as ResourceSnapshotSchema};
@@ -1,6 +1,6 @@
1
1
  import { type namedTypes as n } from "ast-types";
2
2
  import { type Result } from "../../../types/Result.js";
3
- import type { ObjectPropertyInput, QuoteStyle } from "../../fileRewriter/index.js";
3
+ import { type ObjectPropertyInput, type QuoteStyle } from "../../fileRewriter/index.js";
4
4
  import type { InvalidPropertyError } from "../../types.js";
5
5
  export declare function buildPropertyInputs(properties: Record<string, unknown>, quoteStyle: QuoteStyle): Result<ObjectPropertyInput[], InvalidPropertyError>;
6
6
  export declare function toAstValue(value: unknown, quoteStyle: QuoteStyle): n.Property["value"] | undefined;
@@ -1 +1 @@
1
- import{builders as o}from"ast-types";import{failure as p,success as u}from"../../../types/Result.js";function d(r,e){const n=[];for(const[t,i]of Object.entries(r)){const s=a(i,e);if(s===void 0)return p({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (Phase 1 accepts string/number/boolean/null only).`});n.push({key:t,value:s})}return u(n)}function a(r,e){if(typeof r=="string")return l(r,e);if(typeof r=="number"&&Number.isFinite(r))return o.numericLiteral(r);if(typeof r=="boolean")return o.booleanLiteral(r);if(r===null)return o.nullLiteral()}function l(r,e){const n=e==="single"?"'":'"',t=e==="single"?r.replace(/\\/g,"\\\\").replace(/'/g,"\\'"):r.replace(/\\/g,"\\\\").replace(/"/g,'\\"'),i=`${n}${t}${n}`;return o.stringLiteral.from({value:r,extra:{rawValue:r,raw:i}})}export{d as buildPropertyInputs,l as makeStringLiteral,a as toAstValue};
1
+ import{builders as i}from"ast-types";import{failure as p,success as c}from"../../../types/Result.js";import{buildObjectProperty as u}from"../../fileRewriter/index.js";function m(r,n){const e=[];for(const[t,o]of Object.entries(r)){const s=f(o,n);if(s===void 0)return p({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (accepts string/number/boolean/null/array/object of the same).`});e.push({key:t,value:s})}return c(e)}function f(r,n){if(typeof r=="string")return a(r,n);if(typeof r=="number"&&Number.isFinite(r))return i.numericLiteral(r);if(typeof r=="boolean")return i.booleanLiteral(r);if(r===null)return i.nullLiteral();if(Array.isArray(r)){const e=[];for(const t of r){const o=f(t,n);if(o===void 0)return;e.push(o)}return i.arrayExpression(e)}if(typeof r=="object"&&r!==null){const e=[];for(const[t,o]of Object.entries(r)){const s=f(o,n);if(s===void 0)return;e.push(u(t,s,n))}return i.objectExpression(e)}}function a(r,n){const e=n==="single"?"'":'"',t=n==="single"?r.replace(/\\/g,"\\\\").replace(/'/g,"\\'"):r.replace(/\\/g,"\\\\").replace(/"/g,'\\"'),o=`${e}${t}${e}`;return i.stringLiteral.from({value:r,extra:{rawValue:r,raw:o}})}export{m as buildPropertyInputs,a as makeStringLiteral,f as toAstValue};
@@ -1,9 +1,14 @@
1
1
  import { type Result } from "../../types/Result.js";
2
- import type { AddOptions, DuplicateResourceError, InvalidPropertyError, LinesChanged, ParseError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
2
+ import { type ResourceSnapshot } from "../drift/index.js";
3
+ import type { AddOptions, ControlFlowClassifierError, DriftConflictError, DuplicateResourceError, InvalidPropertyError, LinesChanged, ParseError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
3
4
  export type { AddOptions, LinesChanged } from "../types.js";
4
- export type AddResourceError = ParseError | TemplateLiteralNameError | DuplicateResourceError | InvalidPropertyError | SemanticQueryError;
5
+ export type AddResourceError = ParseError | TemplateLiteralNameError | DuplicateResourceError | InvalidPropertyError | SemanticQueryError | DriftConflictError | ControlFlowClassifierError;
5
6
  export interface AddResourceSuccess {
6
7
  content: string;
7
8
  linesChanged: LinesChanged;
9
+ skipped?: boolean;
8
10
  }
9
- export declare function addResource(content: string, options: AddOptions): Result<AddResourceSuccess, AddResourceError>;
11
+ export interface AddResourceCallContext {
12
+ baseline?: ResourceSnapshot;
13
+ }
14
+ export declare function addResource(content: string, options: AddOptions, context?: AddResourceCallContext): Result<AddResourceSuccess, AddResourceError>;
@@ -1 +1 @@
1
- import{failure as o,success as h}from"../../types/Result.js";import{DEFAULT_FILE_PATH as T,computeLinesDelta as R,extractProgramBody as F,isRecord as P}from"../_internal.js";import{appendSpecifier as g,buildFactoryStatement as k,buildImportDeclaration as x,detectQuoteStyle as D,parse as b,printFile as A}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as _}from"../registry.js";import{locateAllShapes as B,locateByShape as O}from"../semanticIndex/index.js";import{buildResourceLocations as Q,indexBody as C,orderByEndPos as N,resolveInsertIndex as U}from"./addResource/bodyIndex.js";import{buildPropertyInputs as v}from"./addResource/propertyBuilder.js";import{findInsertionPosition as w}from"./findInsertionPosition.js";const f="@fjall/components-infrastructure";function V(t,r){const i=r.filePath??T,n=b(t,i);if(!n.success)return o(n.error);const e=O(t,{type:r.type,name:r.name},i);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?o(e.error):o({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data!==void 0)return o({kind:"DuplicateResourceError",type:r.type,name:r.name});const a=D(n.data),m=v(r.properties,a);if(!m.success)return o(m.error);const d=_[r.type].factoryIdentifier,l=k({factory:d,name:r.name,properties:m.data,quoteStyle:a}),u=F(n.data);if(u===void 0)return o({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const c=C(u,t),s=B(t,i);if(!s.success)return s.error.kind==="TemplateLiteralNameError"?o(s.error):o({kind:"SemanticQueryError",reason:s.error.reason,cause:s.error.cause});const y=Q(c.anchors,s.data),E=N([...c.appInitLocations,...y]),S=w(c.importInfos,E,r.type,c.programEnd),I=U(c.anchors,S);u.splice(I,0,l),M(u,d,a);const p=A(n.data,t),L=R(t,p);return h({content:p,linesChanged:L})}function M(t,r,i){for(const e of t){if(e.type!=="ImportDeclaration")continue;const a=e.source;if(!(!P(a)||a.type!=="StringLiteral")&&a.value===f){g(e,r);return}}const n=x([r],f,i);t.unshift(n)}export{V as addResource};
1
+ import{failure as o,success as E}from"../../types/Result.js";import{DEFAULT_FILE_PATH as g,computeLinesDelta as T,extractProgramBody as F,isRecord as C}from"../_internal.js";import{appendSpecifier as D,buildFactoryStatement as b,buildImportDeclaration as x,detectQuoteStyle as w,parse as Q,printFile as v}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as A}from"../registry.js";import{locateAllShapes as _,locateByShape as B}from"../semanticIndex/index.js";import{checkControlFlowPolicy as G}from"./controlFlowPolicy.js";import{driftGate as N,runPipeline as O,schemaGate as U}from"../validationGate/index.js";import{buildResourceLocations as M,indexBody as Y,orderByEndPos as j,resolveInsertIndex as q}from"./addResource/bodyIndex.js";import{buildPropertyInputs as H}from"./addResource/propertyBuilder.js";import{findInsertionPosition as $}from"./findInsertionPosition.js";const S="@fjall/components-infrastructure";function nr(e,r,u={}){const i=r.filePath??g,a=Q(e,i);if(!a.success)return o(a.error);const t=B(e,{type:r.type,name:r.name},i);if(!t.success)return t.error.kind==="TemplateLiteralNameError"?o(t.error):o({kind:"SemanticQueryError",reason:t.error.reason,cause:t.error.cause});if(t.data!==void 0){const y=G({ast:a.data,target:t.data,resource:{type:r.type,name:r.name},op:"add"});if(y.refusal!==void 0)return o(y.refusal);const l=O([U,N],{content:e,plan:{type:r.type,name:r.name,properties:r.properties,op:"add"},baseline:u.baseline,policy:r.driftPolicy});return l.success?l.data.action==="skip"?E({content:e,linesChanged:{added:0,removed:0},skipped:!0}):o({kind:"DuplicateResourceError",type:r.type,name:r.name}):o(z(l.error))}const d=w(a.data),p=H(r.properties,d);if(!p.success)return o(p.error);const m=A[r.type].factoryIdentifier,I=b({factory:m,name:r.name,properties:p.data,quoteStyle:d}),c=F(a.data);if(c===void 0)return o({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const s=Y(c,e),n=_(e,i);if(!n.success)return n.error.kind==="TemplateLiteralNameError"?o(n.error):o({kind:"SemanticQueryError",reason:n.error.reason,cause:n.error.cause});const h=M(s.anchors,n.data),k=j([...s.appInitLocations,...h]),L=$(s.importInfos,k,r.type,s.programEnd),P=q(s.anchors,L);c.splice(P,0,I),J(c,m,d);const f=v(a.data,e),R=T(e,f);return E({content:f,linesChanged:R})}function z(e){switch(e.kind){case"ParseError":case"TemplateLiteralNameError":case"DuplicateResourceError":case"InvalidPropertyError":case"SemanticQueryError":case"DriftConflictError":case"ControlFlowClassifierError":return e;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${e.kind}`}}}function J(e,r,u){for(const a of e){if(a.type!=="ImportDeclaration")continue;const t=a.source;if(!(!C(t)||t.type!=="StringLiteral")&&t.value===S){D(a,r);return}}const i=x([r],S,u);e.unshift(i)}export{nr as addResource};
@@ -0,0 +1,19 @@
1
+ import type { ControlFlowClassifierError, NodeLocation, StatementType } from "../types.js";
2
+ export type ControlFlowPolicyOp = "add" | "remove" | "modify";
3
+ export interface ControlFlowPolicyInput {
4
+ ast: unknown;
5
+ target: NodeLocation;
6
+ resource: {
7
+ type: StatementType;
8
+ name: string;
9
+ };
10
+ op: ControlFlowPolicyOp;
11
+ }
12
+ export interface ControlFlowWarning {
13
+ message: string;
14
+ }
15
+ export interface ControlFlowPolicyResult {
16
+ refusal?: ControlFlowClassifierError;
17
+ warning?: ControlFlowWarning;
18
+ }
19
+ export declare function checkControlFlowPolicy(input: ControlFlowPolicyInput): ControlFlowPolicyResult;
@@ -0,0 +1 @@
1
+ import{isRecord as y}from"../_internal.js";const h=new Set(["loc","tokens","comments","original","range"]),p=new Set(["ForStatement","ForInStatement","ForOfStatement","WhileStatement","DoWhileStatement"]),m={"try-catch":"Move the resource declaration outside the try block.","switch-fall-through":"Add a break statement or convert to if/else.","nested-ternary":"Convert nested ternaries to if/else.",loop:"Extract the resource declaration before the loop.","generator-function":"Extract the resource declaration outside the generator.","async-iterator":"Extract the resource declaration outside the async iterator.","anonymous-helper":"Extract the resource to module scope.","decorator-return":"Extract the resource declaration outside the decorated function."};function g(e,r){if(!c(e))return;const n=[{node:e,ancestors:[]}];for(;n.length>0;){const s=n.pop();if(s===void 0)continue;const{node:o,ancestors:a}=s;if(o.type==="StringLiteral"&&typeof o.start=="number"&&o.start===r)return{node:o,ancestors:a};const t=[...a,o];for(const u of Object.keys(o)){if(h.has(u))continue;const f=o[u];if(Array.isArray(f))for(let d=f.length-1;d>=0;d-=1){const l=f[d];c(l)&&n.push({node:l,ancestors:t})}else c(f)&&n.push({node:f,ancestors:t})}}}function c(e){return typeof e=="object"&&e!==null&&typeof e.type=="string"}function i(e,r,n){return{kind:"ControlFlowClassifierError",reason:e,resource:r,location:S(n),remediation:m[e]}}function S(e){const r=e.loc;if(r?.start!==void 0&&typeof r.start.line=="number"&&typeof r.start.column=="number")return{line:r.start.line,column:r.start.column}}function F(e,r){const n=e.finalizer;return n!==void 0&&n===r}function E(e,r){const n=e.handler;return n!==void 0&&n===r}function b(e){const r=e.consequent;if(!Array.isArray(r)||r.length===0)return!0;const n=r[r.length-1];return c(n)?n.type!=="BreakStatement"&&n.type!=="ReturnStatement":!0}function k(e){const r=A(e.ast);if(r===void 0)return{};const n=g(r,e.target.start);if(n===void 0)return{};const{ancestors:s}=n;let o=n.node;for(let a=s.length-1;a>=0;a-=1){const t=s[a];if(t!==void 0){if(p.has(t.type))return{refusal:i("loop",e.resource,t)};if(t.type==="TryStatement"){if(E(t,o)||F(t,o))return{refusal:i("try-catch",e.resource,t)};o=t;continue}if(t.type==="CatchClause")return{refusal:i("try-catch",e.resource,t)};if(t.type==="SwitchCase"&&b(t))return{refusal:i("switch-fall-through",e.resource,t)};if(t.type==="ConditionalExpression"){const u=a-1;if((u>=0?s[u]:void 0)?.type==="ConditionalExpression")return{refusal:i("nested-ternary",e.resource,t)};if(e.op==="modify")return{warning:{message:`Modified property on resource "${e.resource.name}" declared in a ternary expression \u2014 consider converting to if/else.`}};if(e.op==="add"||e.op==="remove")return{refusal:i("nested-ternary",e.resource,t)}}if(t.type==="FunctionDeclaration"||t.type==="FunctionExpression"||t.type==="ArrowFunctionExpression"||t.type==="ObjectMethod"||t.type==="ClassMethod")return t.generator===!0?{refusal:i("generator-function",e.resource,t)}:t.async===!0&&w(t)?{refusal:i("async-iterator",e.resource,t)}:x(t)===void 0?{refusal:i("anonymous-helper",e.resource,t)}:{refusal:i("anonymous-helper",e.resource,t)};o=t}}return{}}function x(e){if(e.type==="FunctionDeclaration"){const r=e.id;if(c(r)&&typeof r.name=="string")return r.name}}function w(e){if(e.type!=="FunctionDeclaration"&&e.type!=="FunctionExpression")return!1;const r=e.body;if(!c(r)||r.type!=="BlockStatement")return!1;const n=r.body;return Array.isArray(n)?n.some(s=>c(s)&&s.type==="ForOfStatement"&&s.await===!0):!1}function A(e){if(!y(e))return;const r=e.program;if(y(r)&&typeof r.type=="string")return e}export{k as checkControlFlowPolicy};
@@ -0,0 +1,20 @@
1
+ import type { CrossPlanConnectionResourcePlan } from "../../schemas/applicationSchemas.js";
2
+ import { type Result } from "../../types/Result.js";
3
+ import type { CodemodError, EditOrchestratorSuccess } from "../types.js";
4
+ export type CrossPlanConnectionAddOptions = Omit<CrossPlanConnectionResourcePlan, "name"> & {
5
+ name: string;
6
+ filePath?: string;
7
+ };
8
+ export interface CrossPlanConnectionRemoveOptions {
9
+ name: string;
10
+ filePath?: string;
11
+ force?: boolean;
12
+ }
13
+ export type CrossPlanConnectionModifyOptions = Partial<Omit<CrossPlanConnectionResourcePlan, "name">> & {
14
+ name: string;
15
+ filePath?: string;
16
+ };
17
+ export type CrossPlanConnectionOrchestratorSuccess = EditOrchestratorSuccess;
18
+ export declare function addCrossPlanConnection(content: string, options: CrossPlanConnectionAddOptions): Result<CrossPlanConnectionOrchestratorSuccess, CodemodError>;
19
+ export declare function removeCrossPlanConnection(content: string, options: CrossPlanConnectionRemoveOptions): Result<CrossPlanConnectionOrchestratorSuccess, CodemodError>;
20
+ export declare function modifyCrossPlanConnection(content: string, options: CrossPlanConnectionModifyOptions): Result<CrossPlanConnectionOrchestratorSuccess, CodemodError>;
@@ -0,0 +1 @@
1
+ import{failure as i,success as d}from"../../types/Result.js";import{addResource as u}from"./addResource.js";import{modifyResource as f}from"./modifyResource.js";import{removeResource as l}from"./removeResource.js";function y(e,n){const{name:t,filePath:o,...s}=n,a={...s},r=u(e,{type:"cross-plan-connection",name:t,properties:a,...o!==void 0?{filePath:o}:{}});if(!r.success)return i(r.error);const c=m(n);return d({content:r.data.content,linesChanged:r.data.linesChanged,...c.length>0?{warnings:c}:{}})}function R(e,n){const t=l(e,{type:"cross-plan-connection",name:n.name,...n.filePath!==void 0?{filePath:n.filePath}:{},...n.force!==void 0?{force:n.force}:{}});return t.success?d({content:t.data.content,linesChanged:t.data.linesChanged}):i(t.error)}function A(e,n){const{name:t,filePath:o,...s}=n,a={...s},r=f(e,{type:"cross-plan-connection",name:t,properties:a,...o!==void 0?{filePath:o}:{}});if(!r.success)return i(r.error);const c=p(s);return d({content:r.data.content,linesChanged:r.data.linesChanged,...c.length>0?{warnings:c}:{}})}function m(e){return[`Cross-plan connection to "${e.remoteApp}/${e.remoteResource}" requires an accepter role granting ${e.permission} access on the remote plan.`]}function p(e){return e.remoteApp===void 0&&e.remoteResource===void 0&&e.permission===void 0?[]:["Updating remoteApp, remoteResource, or permission may require a corresponding change to the accepter role on the remote plan."]}export{y as addCrossPlanConnection,A as modifyCrossPlanConnection,R as removeCrossPlanConnection};
@@ -0,0 +1,7 @@
1
+ import type { DriftOp, DriftPolicy, DriftState } from "../drift/index.js";
2
+ export type DriftAction = "proceed" | "skip" | "reject";
3
+ export interface DriftDecision {
4
+ action: DriftAction;
5
+ driftState: DriftState;
6
+ }
7
+ export declare function resolveDriftPolicy(driftState: DriftState, op: DriftOp, policy: DriftPolicy | undefined): DriftDecision;
@@ -0,0 +1 @@
1
+ function t(e,o,n){const r=e.summary;return r==="clean"?{action:"proceed",driftState:e}:r==="no-op"?{action:"skip",driftState:e}:n?.force===!0?{action:"proceed",driftState:e}:r==="drifted-compatible"?{action:"proceed",driftState:e}:r==="drifted-conflict"?i(e,n)?{action:"proceed",driftState:e}:{action:"reject",driftState:e}:o==="add"?{action:"proceed",driftState:e}:{action:"reject",driftState:e}}function i(e,o){const n=o?.resolutionMap;if(n===void 0)return!1;const r=e.deltas.filter(c=>c.verdict==="conflict");return r.length===0?!1:r.every(c=>Object.prototype.hasOwnProperty.call(n,c.property))}export{t as resolveDriftPolicy};
@@ -1 +1 @@
1
- const s=["import","app-init","tags","database","storage","messaging","compute","network","cdn","pattern"];function d(i,a,c,r){const t=s.indexOf(c);if(t===-1)return r;let e;for(const n of i)s.indexOf("import")<=t&&(e=n.endPos);for(const n of a){const o=s.indexOf(n.type);o!==-1&&o<=t&&(e=n.endPos)}return e??r}export{d as findInsertionPosition};
1
+ const o=["import","app-init","tags","database","storage","messaging","compute","network","vpc-peer","vpc-peer-accepter","cross-plan-connection","cdn","pattern"];function d(c,i,p,r){const t=o.indexOf(p);if(t===-1)return r;let e;const a=o.indexOf("import");for(const n of c)a<=t&&(e=n.endPos);for(const n of i){const s=o.indexOf(n.type);s!==-1&&s<=t&&(e=n.endPos)}return e??r}export{d as findInsertionPosition};
@@ -3,3 +3,6 @@ export { findInsertionPosition, type ImportInfo, type InsertionStatementType, ty
3
3
  export { removeResource, type LinesChanged, type RemoveOptions, type RemoveResourceError, type RemoveResourceSuccess, } from "./removeResource.js";
4
4
  export { modifyResource, type ModifyOptions, type ModifyResourceError, type ModifyResourceSuccess, } from "./modifyResource.js";
5
5
  export { ensureImports, type EnsureImportsAddition, type EnsureImportsError, type EnsureImportsSuccess, } from "./ensureImports.js";
6
+ export { addVpcPeer, modifyVpcPeer, removeVpcPeer, type VpcPeerAddOptions, type VpcPeerModifyOptions, type VpcPeerOrchestratorSuccess, type VpcPeerRemoveOptions, } from "./vpcPeer.js";
7
+ export { addVpcPeerAccepter, modifyVpcPeerAccepter, removeVpcPeerAccepter, type VpcPeerAccepterAddOptions, type VpcPeerAccepterModifyOptions, type VpcPeerAccepterOrchestratorSuccess, type VpcPeerAccepterRemoveOptions, } from "./vpcPeerAccepter.js";
8
+ export { addCrossPlanConnection, modifyCrossPlanConnection, removeCrossPlanConnection, type CrossPlanConnectionAddOptions, type CrossPlanConnectionModifyOptions, type CrossPlanConnectionOrchestratorSuccess, type CrossPlanConnectionRemoveOptions, } from "./crossPlanConnection.js";
@@ -1 +1 @@
1
- import{addResource as e}from"./addResource.js";import{findInsertionPosition as t}from"./findInsertionPosition.js";import{removeResource as s}from"./removeResource.js";import{modifyResource as i}from"./modifyResource.js";import{ensureImports as x}from"./ensureImports.js";export{e as addResource,x as ensureImports,t as findInsertionPosition,i as modifyResource,s as removeResource};
1
+ import{addResource as r}from"./addResource.js";import{findInsertionPosition as p}from"./findInsertionPosition.js";import{removeResource as n}from"./removeResource.js";import{modifyResource as d}from"./modifyResource.js";import{ensureImports as s}from"./ensureImports.js";import{addVpcPeer as P,modifyVpcPeer as x,removeVpcPeer as a}from"./vpcPeer.js";import{addVpcPeerAccepter as V,modifyVpcPeerAccepter as u,removeVpcPeerAccepter as v}from"./vpcPeerAccepter.js";import{addCrossPlanConnection as l,modifyCrossPlanConnection as A,removeCrossPlanConnection as R}from"./crossPlanConnection.js";export{l as addCrossPlanConnection,r as addResource,P as addVpcPeer,V as addVpcPeerAccepter,s as ensureImports,p as findInsertionPosition,A as modifyCrossPlanConnection,d as modifyResource,x as modifyVpcPeer,u as modifyVpcPeerAccepter,R as removeCrossPlanConnection,n as removeResource,a as removeVpcPeer,v as removeVpcPeerAccepter};
@@ -1,9 +1,15 @@
1
1
  import { type Result } from "../../types/Result.js";
2
- import type { InvalidPropertyError, LinesChanged, ModifyOptions, ParseError, ResourceNotFoundError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
2
+ import { type ResourceSnapshot } from "../drift/index.js";
3
+ import type { ControlFlowClassifierError, DriftConflictError, InvalidPropertyError, LinesChanged, ModifyOptions, ParseError, ResourceNotFoundError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
3
4
  export type { LinesChanged, ModifyOptions } from "../types.js";
4
- export type ModifyResourceError = ParseError | ResourceNotFoundError | InvalidPropertyError | TemplateLiteralNameError | SemanticQueryError;
5
+ export type ModifyResourceError = ParseError | ResourceNotFoundError | InvalidPropertyError | TemplateLiteralNameError | SemanticQueryError | DriftConflictError | ControlFlowClassifierError;
5
6
  export interface ModifyResourceSuccess {
6
7
  content: string;
7
8
  linesChanged: LinesChanged;
9
+ skipped?: boolean;
10
+ warnings?: string[];
8
11
  }
9
- export declare function modifyResource(content: string, options: ModifyOptions): Result<ModifyResourceSuccess, ModifyResourceError>;
12
+ export interface ModifyResourceCallContext {
13
+ baseline?: ResourceSnapshot;
14
+ }
15
+ export declare function modifyResource(content: string, options: ModifyOptions, context?: ModifyResourceCallContext): Result<ModifyResourceSuccess, ModifyResourceError>;
@@ -1 +1 @@
1
- import{failure as u,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as g,computeLinesDelta as k,extractProgramBody as E,isRecord as d}from"../_internal.js";import{buildObjectProperty as b,detectQuoteStyle as P,parse as S,printFile as v}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as x}from"../registry.js";import{locateAllShapes as A,locateByShape as N}from"../semanticIndex/index.js";import{toAstValue as T}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as C,isNodeShape as h,readKeyName as L}from"./modifyResource/literalConversion.js";function V(o,e){const t=e.filePath??g,n=S(o,t);if(!n.success)return u(n.error);const r=N(o,{type:e.type,name:e.name},t);if(!r.success)return r.error.kind==="TemplateLiteralNameError"?u(r.error):u({kind:"SemanticQueryError",reason:r.error.reason,cause:r.error.cause});if(r.data===void 0)return u({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:R(o,e.type,t)});const i=E(n.data);if(i===void 0)return u({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const s=j(i,r.data);if(s===void 0)return u({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const a=P(n.data),c=C(s,e.properties),l=x[e.type].schemaFragment.safeParse(c);if(!l.success){const f=l.error.issues[0];return u({kind:"InvalidPropertyError",property:f!==void 0&&f.path.length>0?String(f.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:f?.message??"Schema validation failed"})}const p=w(s,e.properties,a);if(!p.success)return u(p.error);const m=v(n.data,o);return y({content:m,linesChanged:k(o,m)})}function j(o,e){const t=e.start+e.length;let n;const r=i=>{if(n!==void 0||i.type!=="CallExpression")return;const s=i.arguments;if(!Array.isArray(s)||s.length<2)return;const a=s[0];if(!h(a)||a.type!=="StringLiteral"||a.start!==e.start||a.end!==t)return;const c=s[1];h(c)&&c.type==="ObjectExpression"&&(n=c)};for(const i of o)if(I(i,r),n!==void 0)break;return n}function w(o,e,t){const n=O(o);for(const[r,i]of Object.entries(e)){const s=T(i,t);if(s===void 0)return u({kind:"InvalidPropertyError",property:r,reason:`Unsupported property value for "${r}" (Phase 1 accepts string/number/boolean/null only).`});const a=F(o,r);if(a!==void 0){a.value=s;continue}const c=b(r,s,t);n&&(c.extra={...c.extra??{},trailingComma:!0}),o.properties.push(c)}return y(void 0)}function F(o,e){return o.properties.find(t=>(t.type==="Property"||t.type==="ObjectProperty")&&t.shorthand!==!0&&t.computed!==!0&&L(t.key)===e)}function O(o){return o.properties[o.properties.length-1]?.extra?.trailingComma===!0}function R(o,e,t){const n=A(o,t);return n.success?n.data.filter(r=>r.type===e).map(r=>r.symbolName):[]}function I(o,e){const t=[o];for(;t.length>0;){const n=t.pop();if(d(n)){typeof n.type=="string"&&e(n);for(const r of Object.keys(n)){if(r==="loc"||r==="comments"||r==="tokens")continue;const i=n[r];if(Array.isArray(i))for(const s of i)d(s)&&t.push(s);else d(i)&&t.push(i)}}}}export{V as modifyResource};
1
+ import{failure as c,success as l}from"../../types/Result.js";import{DEFAULT_FILE_PATH as P,computeLinesDelta as S,extractProgramBody as v,isRecord as p}from"../_internal.js";import{buildObjectProperty as w,detectQuoteStyle as C,parse as N,printFile as x}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as T}from"../registry.js";import{locateAllShapes as A,locateByShape as F}from"../semanticIndex/index.js";import{checkControlFlowPolicy as R}from"./controlFlowPolicy.js";import{driftGate as L,runPipeline as j,schemaGate as O}from"../validationGate/index.js";import{toAstValue as Q}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as I,isNodeShape as h,readKeyName as G}from"./modifyResource/literalConversion.js";function ee(r,e,a={}){const i=e.filePath??P,t=N(r,i);if(!t.success)return c(t.error);const n=F(r,{type:e.type,name:e.name},i);if(!n.success)return n.error.kind==="TemplateLiteralNameError"?c(n.error):c({kind:"SemanticQueryError",reason:n.error.reason,cause:n.error.cause});if(n.data===void 0)return c({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:M(r,e.type,i)});const o=R({ast:t.data,target:n.data,resource:{type:e.type,name:e.name},op:"modify"});if(o.refusal!==void 0)return c(o.refusal);const s=j([O,L],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:a.baseline,policy:e.driftPolicy});if(!s.success)return c(U(s.error));if(s.data.action==="skip")return l({content:r,linesChanged:{added:0,removed:0},skipped:!0});const u=v(t.data);if(u===void 0)return c({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=B(u,n.data);if(f===void 0)return c({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const E=C(t.data),k=I(f,e.properties),m=T[e.type].schemaFragment.safeParse(k);if(!m.success){const d=m.error.issues[0];return c({kind:"InvalidPropertyError",property:d!==void 0&&d.path.length>0?String(d.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:d?.message??"Schema validation failed"})}const y=D(f,e.properties,E);if(!y.success)return c(y.error);const g=x(t.data,r),b=o.warning!==void 0?[o.warning.message]:void 0;return l({content:g,linesChanged:S(r,g),warnings:b})}function U(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}`}}}function B(r,e){const a=e.start+e.length;let i;const t=n=>{if(i!==void 0||n.type!=="CallExpression")return;const o=n.arguments;if(!Array.isArray(o)||o.length<2)return;const s=o[0];if(!h(s)||s.type!=="StringLiteral"||s.start!==e.start||s.end!==a)return;const u=o[1];h(u)&&u.type==="ObjectExpression"&&(i=u)};for(const n of r)if(V(n,t),i!==void 0)break;return i}function D(r,e,a){const i=_(r);for(const[t,n]of Object.entries(e)){const o=Q(n,a);if(o===void 0)return c({kind:"InvalidPropertyError",property:t,reason:`Unsupported property value for "${t}" (accepts string/number/boolean/null/array/object of the same).`});const s=K(r,t);if(s!==void 0){s.value=o;continue}const u=w(t,o,a);i&&(u.extra={...u.extra??{},trailingComma:!0}),r.properties.push(u)}return l(void 0)}function K(r,e){return r.properties.find(a=>(a.type==="Property"||a.type==="ObjectProperty")&&a.shorthand!==!0&&a.computed!==!0&&G(a.key)===e)}function _(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}function M(r,e,a){const i=A(r,a);return i.success?i.data.filter(t=>t.type===e).map(t=>t.symbolName):[]}function V(r,e){const a=[r];for(;a.length>0;){const i=a.pop();if(p(i)){typeof i.type=="string"&&e(i);for(const t of Object.keys(i)){if(t==="loc"||t==="comments"||t==="tokens")continue;const n=i[t];if(Array.isArray(n))for(const o of n)p(o)&&a.push(o);else p(n)&&a.push(n)}}}}export{ee as modifyResource};
@@ -1,7 +1,7 @@
1
1
  import { type Result } from "../../types/Result.js";
2
- import type { LinesChanged, ParseError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceNotFoundError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
2
+ import type { ControlFlowClassifierError, LinesChanged, ParseError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceNotFoundError, SemanticQueryError, TemplateLiteralNameError } from "../types.js";
3
3
  export type { LinesChanged, RemoveOptions } from "../types.js";
4
- export type RemoveResourceError = ParseError | TemplateLiteralNameError | ResourceNotFoundError | ReferencesRemainError | SemanticQueryError;
4
+ export type RemoveResourceError = ParseError | TemplateLiteralNameError | ResourceNotFoundError | ReferencesRemainError | SemanticQueryError | ControlFlowClassifierError;
5
5
  export interface RemoveResourceSuccess {
6
6
  content: string;
7
7
  linesChanged: LinesChanged;
@@ -1 +1 @@
1
- import{failure as c,success as u}from"../../types/Result.js";import{DEFAULT_FILE_PATH as l,computeLinesDelta as p,extractProgramBody as y,isRecord as d}from"../_internal.js";import{parse as g,printFile as h}from"../fileRewriter/index.js";import{findReferences as b,locateAllShapes as E,locateByShape as v}from"../semanticIndex/index.js";import{classifyLeadingComments as k}from"./removeResource/commentHeuristic.js";import{pruneUnusedImports as S}from"./removeResource/importPruning.js";function U(n,r){const a=r.filePath??l,t=g(n,a);if(!t.success)return c(t.error);const e=v(n,{type:r.type,name:r.name},a);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?c(e.error):c({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data===void 0)return c({kind:"ResourceNotFoundError",type:r.type,name:r.name,knownNames:F(n,r.type,a)});const i=y(t.data);if(i===void 0)return c({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const o=N(i,e.data);if(o===void 0)return c({kind:"SemanticQueryError",reason:"Unable to resolve enclosing statement for the located resource."});const s=R(n,o.statement,a);if(!s.success)return c(s.error);if(s.data.locations.length>0&&r.force!==!0)return c({kind:"ReferencesRemainError",variable:s.data.variable??r.name,references:s.data.locations});A(i,o.index,n),S(i);const f=h(t.data,n),m=p(n,f);return u({content:f,linesChanged:m,references:s.data.locations})}function N(n,r){const a=r.start+r.length;for(let t=0;t<n.length;t+=1){const e=n[t];if(e!==void 0&&!(typeof e.start!="number"||typeof e.end!="number")&&e.start<=r.start&&e.end>=a)return{index:t,statement:e}}}function R(n,r,a){const t=D(r);if(t===void 0)return u({variable:void 0,locations:[]});const e=b(n,t.location,a);return e.success?u({variable:t.name,locations:e.data}):c({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause})}function D(n){let r=n;if(n.type==="ExportNamedDeclaration"){const f=n.declaration;if(!d(f)||f.type!=="VariableDeclaration")return;r=f}if(r.type!=="VariableDeclaration")return;const a=r.declarations;if(!Array.isArray(a)||a.length!==1)return;const t=a[0];if(!d(t))return;const e=t.id;if(!d(e)||e.type!=="Identifier")return;const i=e.name,o=e.start,s=e.end;if(!(typeof i!="string"||typeof o!="number"||typeof s!="number"))return{name:i,location:{filePath:l,start:o,length:s-o,symbolName:i}}}function A(n,r,a){const t=n[r];if(t===void 0)return;const{preserved:e}=k(t,a);if(e.length>0){const i=n[r+1];if(i!==void 0){const o=e.map(s=>({...s,leading:!0,trailing:!1}));i.comments=[...o,...i.comments??[]]}else{const o=n[r-1];if(o!==void 0){const s=e.map(f=>({...f,leading:!1,trailing:!0}));o.comments=[...o.comments??[],...s]}}}n.splice(r,1)}function F(n,r,a){const t=E(n,a);if(!t.success)return[];const e=[];for(const i of t.data)i.type===r&&e.push(i.symbolName);return e}export{U as removeResource};
1
+ import{failure as f,success as u}from"../../types/Result.js";import{DEFAULT_FILE_PATH as m,computeLinesDelta as y,extractProgramBody as g,isRecord as d}from"../_internal.js";import{parse as h,printFile as b}from"../fileRewriter/index.js";import{findReferences as E,locateAllShapes as v,locateByShape as k}from"../semanticIndex/index.js";import{checkControlFlowPolicy as R}from"./controlFlowPolicy.js";import{classifyLeadingComments as S}from"./removeResource/commentHeuristic.js";import{pruneUnusedImports as N}from"./removeResource/importPruning.js";function V(n,r){const a=r.filePath??m,t=h(n,a);if(!t.success)return f(t.error);const e=k(n,{type:r.type,name:r.name},a);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?f(e.error):f({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data===void 0)return f({kind:"ResourceNotFoundError",type:r.type,name:r.name,knownNames:L(n,r.type,a)});const o=R({ast:t.data,target:e.data,resource:{type:r.type,name:r.name},op:"remove"});if(o.refusal!==void 0)return f(o.refusal);const i=g(t.data);if(i===void 0)return f({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const c=D(i,e.data);if(c===void 0)return f({kind:"SemanticQueryError",reason:"Unable to resolve enclosing statement for the located resource."});const s=F(n,c.statement,a);if(!s.success)return f(s.error);if(s.data.locations.length>0&&r.force!==!0)return f({kind:"ReferencesRemainError",variable:s.data.variable??r.name,references:s.data.locations});A(i,c.index,n),N(i);const l=b(t.data,n),p=y(n,l);return u({content:l,linesChanged:p,references:s.data.locations})}function D(n,r){const a=r.start+r.length;for(let t=0;t<n.length;t+=1){const e=n[t];if(e!==void 0&&!(typeof e.start!="number"||typeof e.end!="number")&&e.start<=r.start&&e.end>=a)return{index:t,statement:e}}}function F(n,r,a){const t=P(r);if(t===void 0)return u({variable:void 0,locations:[]});const e=E(n,t.location,a);return e.success?u({variable:t.name,locations:e.data}):f({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause})}function P(n){let r=n;if(n.type==="ExportNamedDeclaration"){const s=n.declaration;if(!d(s)||s.type!=="VariableDeclaration")return;r=s}if(r.type!=="VariableDeclaration")return;const a=r.declarations;if(!Array.isArray(a)||a.length!==1)return;const t=a[0];if(!d(t))return;const e=t.id;if(!d(e)||e.type!=="Identifier")return;const o=e.name,i=e.start,c=e.end;if(!(typeof o!="string"||typeof i!="number"||typeof c!="number"))return{name:o,location:{filePath:m,start:i,length:c-i,symbolName:o}}}function A(n,r,a){const t=n[r];if(t===void 0)return;const{preserved:e}=S(t,a);if(e.length>0){const o=n[r+1];if(o!==void 0){const i=e.map(c=>({...c,leading:!0,trailing:!1}));o.comments=[...i,...o.comments??[]]}else{const i=n[r-1];if(i!==void 0){const c=e.map(s=>({...s,leading:!1,trailing:!0}));i.comments=[...i.comments??[],...c]}}}n.splice(r,1)}function L(n,r,a){const t=v(n,a);if(!t.success)return[];const e=[];for(const o of t.data)o.type===r&&e.push(o.symbolName);return e}export{V as removeResource};
@@ -0,0 +1,24 @@
1
+ import type { VpcPeerResourcePlan } from "../../schemas/networkSchemas.js";
2
+ import { type Result } from "../../types/Result.js";
3
+ import type { CodemodError, EditOrchestratorSuccess, PermissionError } from "../types.js";
4
+ export type VpcPeerAddOptions = Omit<VpcPeerResourcePlan, "name"> & {
5
+ name: string;
6
+ filePath?: string;
7
+ currentAccount?: string;
8
+ };
9
+ export interface VpcPeerRemoveOptions {
10
+ name: string;
11
+ filePath?: string;
12
+ force?: boolean;
13
+ }
14
+ export type VpcPeerModifyOptions = Partial<Omit<VpcPeerResourcePlan, "name">> & {
15
+ name: string;
16
+ filePath?: string;
17
+ currentAccount?: string;
18
+ };
19
+ export type VpcPeerOrchestratorSuccess = EditOrchestratorSuccess;
20
+ export declare function addVpcPeer(content: string, options: VpcPeerAddOptions): Result<VpcPeerOrchestratorSuccess, CodemodError>;
21
+ export declare function removeVpcPeer(content: string, options: VpcPeerRemoveOptions): Result<VpcPeerOrchestratorSuccess, CodemodError>;
22
+ export declare function modifyVpcPeer(content: string, options: VpcPeerModifyOptions): Result<VpcPeerOrchestratorSuccess, CodemodError>;
23
+ export declare function buildWildcardRejection(resourceType: string, planProperties: Record<string, unknown>, remediation: string): PermissionError | undefined;
24
+ export declare function findWildcardField(value: unknown, path?: string): string | undefined;
@@ -0,0 +1 @@
1
+ import{failure as o,success as l}from"../../types/Result.js";import{addResource as m}from"./addResource.js";import{modifyResource as P}from"./modifyResource.js";import{removeResource as A}from"./removeResource.js";const f="vpc-peer";function j(e,n){const t=g(n);if(t!==void 0)return o(t);const{name:r,filePath:c,currentAccount:d,...a}=n,s={...a},i=m(e,{type:f,name:r,properties:s,...c!==void 0?{filePath:c}:{}});if(!i.success)return o(i.error);const u=y(n);return l({content:i.data.content,linesChanged:i.data.linesChanged,...u.length>0?{warnings:u}:{}})}function w(e,n){const t=A(e,{type:f,name:n.name,...n.filePath!==void 0?{filePath:n.filePath}:{},...n.force!==void 0?{force:n.force}:{}});return t.success?l({content:t.data.content,linesChanged:t.data.linesChanged}):o(t.error)}function V(e,n){const t=g(n);if(t!==void 0)return o(t);const{name:r,filePath:c,currentAccount:d,...a}=n,s={...a},i=P(e,{type:f,name:r,properties:s,...c!==void 0?{filePath:c}:{}});if(!i.success)return o(i.error);const u=$(a,d);return l({content:i.data.content,linesChanged:i.data.linesChanged,...u.length>0?{warnings:u}:{}})}function y(e){return h(e.peerAppName,e.peerAccountId,e.currentAccount)}function $(e,n){return e.peerAccountId===void 0?[]:h(e.peerAppName,e.peerAccountId,n)}function h(e,n,t){if(t!==void 0&&n===t)return[];const r=e!==void 0?` (peer app ${e})`:"";return[`VPC peer targets AWS account ${n}${r}. Peer requires a VpcPeerAccepter in that account trusting the local account. Deploy the accepter stack first, then the requester.`]}function C(e,n,t){const r=p(n);if(r!==void 0)return{kind:"PermissionError",reason:"wildcard-principal-rejected",details:`Wildcard value detected in ${e} field "${r}". Fjall refuses to emit a ${e} statement that could map to a wildcard principal in the generated trust policy.`,remediation:t}}function g(e){const{name:n,filePath:t,currentAccount:r,...c}=e;return C(f,c,"Replace the wildcard with a concrete 12-digit AWS account id, region, or vpc-id.")}function p(e,n=""){if(typeof e=="string")return e.includes("*")?n:void 0;if(Array.isArray(e)){for(let t=0;t<e.length;t+=1){const r=p(e[t],`${n}[${t}]`);if(r!==void 0)return r}return}if(e!==null&&typeof e=="object")for(const[t,r]of Object.entries(e)){const c=n.length>0?`${n}.${t}`:t,d=p(r,c);if(d!==void 0)return d}}export{j as addVpcPeer,C as buildWildcardRejection,p as findWildcardField,V as modifyVpcPeer,w as removeVpcPeer};
@@ -0,0 +1,20 @@
1
+ import type { VpcPeerAccepterResourcePlan } from "../../schemas/networkSchemas.js";
2
+ import { type Result } from "../../types/Result.js";
3
+ import type { CodemodError, EditOrchestratorSuccess } from "../types.js";
4
+ export type VpcPeerAccepterAddOptions = Omit<VpcPeerAccepterResourcePlan, "name"> & {
5
+ name: string;
6
+ filePath?: string;
7
+ };
8
+ export interface VpcPeerAccepterRemoveOptions {
9
+ name: string;
10
+ filePath?: string;
11
+ force?: boolean;
12
+ }
13
+ export type VpcPeerAccepterModifyOptions = Partial<Omit<VpcPeerAccepterResourcePlan, "name">> & {
14
+ name: string;
15
+ filePath?: string;
16
+ };
17
+ export type VpcPeerAccepterOrchestratorSuccess = EditOrchestratorSuccess;
18
+ export declare function addVpcPeerAccepter(content: string, options: VpcPeerAccepterAddOptions): Result<VpcPeerAccepterOrchestratorSuccess, CodemodError>;
19
+ export declare function removeVpcPeerAccepter(content: string, options: VpcPeerAccepterRemoveOptions): Result<VpcPeerAccepterOrchestratorSuccess, CodemodError>;
20
+ export declare function modifyVpcPeerAccepter(content: string, options: VpcPeerAccepterModifyOptions): Result<VpcPeerAccepterOrchestratorSuccess, CodemodError>;
@@ -0,0 +1 @@
1
+ import{failure as a,success as p}from"../../types/Result.js";import{addResource as m}from"./addResource.js";import{modifyResource as s}from"./modifyResource.js";import{removeResource as l}from"./removeResource.js";import{buildWildcardRejection as P}from"./vpcPeer.js";const i="vpc-peer-accepter";function f(e){return e.success?p({content:e.data.content,linesChanged:e.data.linesChanged}):a(e.error)}function E(e,r){const t=u(r);if(t!==void 0)return a(t);const{name:n,filePath:c,...d}=r,o={...d};return f(m(e,{type:i,name:n,properties:o,...c!==void 0?{filePath:c}:{}}))}function v(e,r){return f(l(e,{type:i,name:r.name,...r.filePath!==void 0?{filePath:r.filePath}:{},...r.force!==void 0?{force:r.force}:{}}))}function w(e,r){const t=u(r);if(t!==void 0)return a(t);const{name:n,filePath:c,...d}=r,o={...d};return f(s(e,{type:i,name:n,properties:o,...c!==void 0?{filePath:c}:{}}))}function u(e){const{name:r,filePath:t,...n}=e;return P(i,n,"Replace the wildcard with a concrete 12-digit AWS account id.")}export{E as addVpcPeerAccepter,w as modifyVpcPeerAccepter,v as removeVpcPeerAccepter};
@@ -1,7 +1,19 @@
1
- export { addResource, type AddResourceError, type AddResourceSuccess, } from "./edits/addResource.js";
1
+ export { addResource, type AddResourceCallContext, type AddResourceError, type AddResourceSuccess, } from "./edits/addResource.js";
2
2
  export { removeResource, type RemoveResourceError, type RemoveResourceSuccess, } from "./edits/removeResource.js";
3
- export { modifyResource, type ModifyResourceError, type ModifyResourceSuccess, } from "./edits/modifyResource.js";
3
+ export { modifyResource, type ModifyResourceCallContext, type ModifyResourceError, type ModifyResourceSuccess, } from "./edits/modifyResource.js";
4
+ export { addVpcPeer, modifyVpcPeer, removeVpcPeer, type VpcPeerAddOptions, type VpcPeerModifyOptions, type VpcPeerOrchestratorSuccess, type VpcPeerRemoveOptions, } from "./edits/vpcPeer.js";
5
+ export { addVpcPeerAccepter, modifyVpcPeerAccepter, removeVpcPeerAccepter, type VpcPeerAccepterAddOptions, type VpcPeerAccepterModifyOptions, type VpcPeerAccepterOrchestratorSuccess, type VpcPeerAccepterRemoveOptions, } from "./edits/vpcPeerAccepter.js";
6
+ export { addCrossPlanConnection, modifyCrossPlanConnection, removeCrossPlanConnection, type CrossPlanConnectionAddOptions, type CrossPlanConnectionModifyOptions, type CrossPlanConnectionOrchestratorSuccess, type CrossPlanConnectionRemoveOptions, } from "./edits/crossPlanConnection.js";
7
+ export { resolveDriftPolicy, type DriftAction, type DriftDecision, } from "./edits/driftPolicy.js";
4
8
  export { listResources, type ListResourcesError } from "./listResources.js";
5
9
  export { parse } from "./fileRewriter/parse.js";
6
- export { StatementTypeSchema } from "./types.js";
7
- export type { AddOptions, CodemodError, CodemodSuccess, DuplicateResourceError, InvalidPropertyError, LinesChanged, ModifyOptions, NodeLocation, ParseError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceListing, ResourceListingEntry, ResourceName, ResourceNotFoundError, SemanticQueryError, StatementType, TemplateLiteralNameError, } from "./types.js";
10
+ export { CrossPlanConnectionResourcePlanSchema, VpcPeerAccepterResourcePlanSchema, VpcPeerResourcePlanSchema, } from "../schemas/index.js";
11
+ export type { CrossPlanConnectionResourcePlan, VpcPeerAccepterResourcePlan, VpcPeerResourcePlan, } from "../schemas/index.js";
12
+ export { detectDrift, mergeProperties, snapshotProperties, type DriftOp, type DriftPlan, type DriftPolicy, type DriftState, type MergeResult, type PropertyDelta, type ResourceSnapshot, } from "./drift/index.js";
13
+ export { computeLinesDelta } from "./_internal.js";
14
+ export { ResourceNameSchema, StatementTypeSchema } from "./types.js";
15
+ export { CODEMOD_ERROR_KINDS } from "./telemetry/errorKinds.js";
16
+ export type { CodemodErrorKind } from "./telemetry/errorKinds.js";
17
+ export type { GateId } from "./validationGate/index.js";
18
+ export { buildEgressBlockedEvent, buildFiredEvent, buildGateFailedEvent, buildGatePassedEvent, buildRejectedEvent, buildSucceededEvent, buildTimeoutEvent, estimateCostUsd, FALLBACK_EVENTS, GATE_EVENTS, PARSE_GATE, RUNTIME_GATE, runFallback, shouldTryFallback, type AnthropicClientProvider, type FallbackClients, type FallbackDecision, type FallbackEgressBlockedEvent, type FallbackGuardConfig, type FallbackInput, type FallbackIntent, type FallbackOp, type FallbackOutput, type FallbackTelemetry, type FallbackTelemetryEvent, type MorphClientProvider, type RunFallbackInput, type TelemetrySource, type TriggerReason, } from "./llmFallback/index.js";
19
+ export type { AddOptions, CodemodError, CodemodSuccess, ControlFlowClassifierError, DriftConflictError, DriftUnmergeableError, DuplicateResourceError, EditOrchestratorSuccess, InvalidPropertyError, LinesChanged, LlmFallbackRejectedError, LlmFallbackTimeoutError, LlmFallbackTier, LlmFallbackUnsafeInputError, ModifyOptions, NodeLocation, ParseError, PermissionError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceListing, ResourceListingEntry, ResourceName, ResourceNotFoundError, SemanticQueryError, StatementType, TemplateLiteralNameError, } from "./types.js";
@@ -1 +1 @@
1
- import{addResource as r}from"./edits/addResource.js";import{removeResource as t}from"./edits/removeResource.js";import{modifyResource as f}from"./edits/modifyResource.js";import{listResources as x}from"./listResources.js";import{parse as a}from"./fileRewriter/parse.js";import{StatementTypeSchema as R}from"./types.js";export{R as StatementTypeSchema,r as addResource,x as listResources,f as modifyResource,a as parse,t as removeResource};
1
+ import{addResource as o}from"./edits/addResource.js";import{removeResource as c}from"./edits/removeResource.js";import{modifyResource as p}from"./edits/modifyResource.js";import{addVpcPeer as a,modifyVpcPeer as n,removeVpcPeer as d}from"./edits/vpcPeer.js";import{addVpcPeerAccepter as l,modifyVpcPeerAccepter as f,removeVpcPeerAccepter as u}from"./edits/vpcPeerAccepter.js";import{addCrossPlanConnection as E,modifyCrossPlanConnection as x,removeCrossPlanConnection as R}from"./edits/crossPlanConnection.js";import{resolveDriftPolicy as C}from"./edits/driftPolicy.js";import{listResources as A}from"./listResources.js";import{parse as b}from"./fileRewriter/parse.js";import{CrossPlanConnectionResourcePlanSchema as h,VpcPeerAccepterResourcePlanSchema as y,VpcPeerResourcePlanSchema as D}from"../schemas/index.js";import{detectDrift as F,mergeProperties as G,snapshotProperties as N}from"./drift/index.js";import{computeLinesDelta as L}from"./_internal.js";import{ResourceNameSchema as g,StatementTypeSchema as B}from"./types.js";import{CODEMOD_ERROR_KINDS as K}from"./telemetry/errorKinds.js";import{buildEgressBlockedEvent as U,buildFiredEvent as j,buildGateFailedEvent as q,buildGatePassedEvent as w,buildRejectedEvent as z,buildSucceededEvent as H,buildTimeoutEvent as J,estimateCostUsd as Q,FALLBACK_EVENTS as W,GATE_EVENTS as X,PARSE_GATE as Y,RUNTIME_GATE as Z,runFallback as $,shouldTryFallback as ee}from"./llmFallback/index.js";export{K as CODEMOD_ERROR_KINDS,h as CrossPlanConnectionResourcePlanSchema,W as FALLBACK_EVENTS,X as GATE_EVENTS,Y as PARSE_GATE,Z as RUNTIME_GATE,g as ResourceNameSchema,B as StatementTypeSchema,y as VpcPeerAccepterResourcePlanSchema,D as VpcPeerResourcePlanSchema,E as addCrossPlanConnection,o as addResource,a as addVpcPeer,l as addVpcPeerAccepter,U as buildEgressBlockedEvent,j as buildFiredEvent,q as buildGateFailedEvent,w as buildGatePassedEvent,z as buildRejectedEvent,H as buildSucceededEvent,J as buildTimeoutEvent,L as computeLinesDelta,F as detectDrift,Q as estimateCostUsd,A as listResources,G as mergeProperties,x as modifyCrossPlanConnection,p as modifyResource,n as modifyVpcPeer,f as modifyVpcPeerAccepter,b as parse,R as removeCrossPlanConnection,c as removeResource,d as removeVpcPeer,u as removeVpcPeerAccepter,C as resolveDriftPolicy,$ as runFallback,ee as shouldTryFallback,N as snapshotProperties};
@@ -0,0 +1,10 @@
1
+ import { type Result } from "../../types/Result.js";
2
+ import type { StrReplaceOp, ApplyResult } from "./types.js";
3
+ interface ApplyError {
4
+ kind: "ambiguous-str-replace";
5
+ opIndex: number;
6
+ old_str: string;
7
+ matchCount: number;
8
+ }
9
+ export declare function applyStrReplaceOps(content: string, ops: readonly StrReplaceOp[]): Result<ApplyResult, ApplyError>;
10
+ export {};
@@ -0,0 +1 @@
1
+ import{success as l,failure as d}from"../../types/Result.js";function x(c,r){let e=c,n=0,o=0;for(let i=0;i<r.length;i+=1){const t=r[i];if(t===void 0)continue;const s=e.indexOf(t.old_str);if(s===-1){o+=1;continue}if(e.indexOf(t.old_str,s+1)!==-1)return d({kind:"ambiguous-str-replace",opIndex:i,old_str:t.old_str,matchCount:u(e,t.old_str)});e=e.slice(0,s)+t.new_str+e.slice(s+t.old_str.length),n+=1}return l({content:e,appliedCount:n,skippedCount:o})}function u(c,r){let e=0,n=0;for(;;){const o=c.indexOf(r,n);if(o===-1)break;e+=1,n=o+1}return e}export{x as applyStrReplaceOps};
@@ -0,0 +1,6 @@
1
+ import { type AnthropicClientProvider, type FallbackInput, type FallbackOutput } from "./types.js";
2
+ export declare const TEXT_EDITOR_TOOL: {
3
+ name: "str_replace_based_edit_tool";
4
+ type: "text_editor_20250728";
5
+ };
6
+ export declare function runClaudeTier(input: FallbackInput, client: AnthropicClientProvider): Promise<FallbackOutput>;
@@ -0,0 +1 @@
1
+ import{gateEgress as p}from"./egressGate.js";import{buildPrompt as y}from"./prompt.js";import{applyStrReplaceOps as k}from"./apply.js";import{withTierTimeout as E}from"./tierRunner.js";import{PARSE_GATE as u}from"./types.js";const b=3e4,o="claude",m={name:"str_replace_based_edit_tool",type:"text_editor_20250728"};async function S(t,s){if(!t.orgAllowsFallback)return{state:"disabled",reason:"org-opt-out"};const r=p(t.content,o);if(r!==void 0)return r;const e=p(JSON.stringify(t.intent.properties),o);if(e!==void 0)return e;const{systemPrompt:i,userPrompt:c}=y({content:t.content,intent:t.intent,tier:o});return E(t.abortSignal,o,b,async({signal:f,started:_})=>{const a=await s.create({model:s.resolveModelId(),max_tokens:4096,system:i,messages:[{role:"user",content:c}],tools:[m],signal:f}),g=Date.now()-_,d=w(a.content);if(d.length===0)return{state:"rejected",tier:o,failedGate:u,diagnostics:"Model produced no str_replace operations"};const n=k(t.content,d);if(!n.success)return{state:"rejected",tier:o,failedGate:u,diagnostics:`Ambiguous str_replace at op ${n.error.opIndex}: "${n.error.old_str.slice(0,40)}\u2026" matched ${n.error.matchCount} times`};const l=p(n.data.content,o);if(l!==void 0)return l;const T={tier:o,elapsedMs:g,inputTokens:a.usage?.input_tokens??0,outputTokens:a.usage?.output_tokens??0,opsApplied:n.data.appliedCount};return{state:"applied",content:n.data.content,telemetry:T}})}function w(t){const s=[];for(const r of t){if(r.type!=="tool_use"||r.name!==m.name)continue;const e=r.input;if(!("command"in e)||e.command!=="str_replace"||!("old_str"in e)||!("new_str"in e))continue;const i=e.old_str,c=e.new_str;typeof i!="string"||typeof c!="string"||s.push({old_str:i,new_str:c})}return s}export{m as TEXT_EDITOR_TOOL,S as runClaudeTier};
@@ -0,0 +1,5 @@
1
+ import type { LlmFallbackTier } from "../types.js";
2
+ import type { EgressGateResult } from "./egressGate.types.js";
3
+ import type { FallbackOutput } from "./types.js";
4
+ export declare function scanForEgressRisk(content: string): EgressGateResult;
5
+ export declare function gateEgress(content: string, tier: LlmFallbackTier): FallbackOutput | undefined;
@@ -0,0 +1 @@
1
+ const E=32,l=4.5,T=8,c=/\barn:aws:[a-z0-9-]+:[a-z0-9-]*:[0-9]*:[^\s"']+/g,a=/(?<![A-Za-z0-9+/=_-])[A-Za-z0-9+/=_-]{32,}(?![A-Za-z0-9+/=_-])/g;function _(t){if(t.length===0)return 0;const e=new Map;for(const o of t)e.set(o,(e.get(o)??0)+1);let n=0;for(const o of e.values()){const s=o/t.length;n-=s*Math.log2(s)}return n}function r(t){return t.length<=8?t:`${t.slice(0,8)}\u2026`}function H(t){const e=[...t.matchAll(c)];if(e.length>0){const o=e[0]?.[0]??"";return{state:"block",reason:"arn-shape",count:e.length,sampleHint:r(o)}}const n=[];for(const o of t.matchAll(a)){const s=o[0]??"";s.length>=32&&_(s)>=4.5&&n.push(s)}return n.length>0?{state:"block",reason:"high-entropy",count:n.length,sampleHint:r(n[0]??"")}:{state:"pass"}}function h(t,e){const n=H(t);if(n.state==="block")return{state:"egress-blocked",tier:e,reason:n.reason,count:n.count}}export{h as gateEgress,H as scanForEgressRisk};
@@ -0,0 +1,9 @@
1
+ export type EgressRiskReason = "high-entropy" | "arn-shape";
2
+ export type EgressGateResult = {
3
+ state: "pass";
4
+ } | {
5
+ state: "block";
6
+ reason: EgressRiskReason;
7
+ count: number;
8
+ sampleHint: string;
9
+ };
@@ -0,0 +1,6 @@
1
+ export { runFallback, type FallbackClients, type RunFallbackInput, } from "./runFallback.js";
2
+ export { shouldTryFallback, type FallbackDecision, type FallbackGuardConfig, } from "./shouldTryFallback.js";
3
+ export { buildEgressBlockedEvent, buildFiredEvent, buildGateFailedEvent, buildGatePassedEvent, buildRejectedEvent, buildSucceededEvent, buildTimeoutEvent, estimateCostUsd, FALLBACK_EVENTS, GATE_EVENTS, type FallbackEgressBlockedEvent, type FallbackFiredEvent, type FallbackRejectedEvent, type FallbackSucceededEvent, type FallbackTelemetryEvent, type FallbackTimeoutEvent, type GateFailedEvent, type GatePassedEvent, type TelemetrySource, } from "./telemetryEvents.js";
4
+ export { PARSE_GATE, RUNTIME_GATE } from "./types.js";
5
+ export type { AnthropicClientProvider, AnthropicContentBlock, AnthropicResponse, ApplyResult, FallbackInput, FallbackIntent, FallbackOp, FallbackOutput, FallbackTelemetry, MorphClientProvider, MorphResponse, StrReplaceOp, TriggerReason, } from "./types.js";
6
+ export type { EgressGateResult, EgressRiskReason } from "./egressGate.types.js";
@@ -0,0 +1 @@
1
+ import{runFallback as E}from"./runFallback.js";import{shouldTryFallback as l}from"./shouldTryFallback.js";import{buildEgressBlockedEvent as r,buildFiredEvent as i,buildGateFailedEvent as u,buildGatePassedEvent as a,buildRejectedEvent as b,buildSucceededEvent as n,buildTimeoutEvent as s,estimateCostUsd as T,FALLBACK_EVENTS as v,GATE_EVENTS as c}from"./telemetryEvents.js";import{PARSE_GATE as A,RUNTIME_GATE as F}from"./types.js";export{v as FALLBACK_EVENTS,c as GATE_EVENTS,A as PARSE_GATE,F as RUNTIME_GATE,r as buildEgressBlockedEvent,i as buildFiredEvent,u as buildGateFailedEvent,a as buildGatePassedEvent,b as buildRejectedEvent,n as buildSucceededEvent,s as buildTimeoutEvent,T as estimateCostUsd,E as runFallback,l as shouldTryFallback};
@@ -0,0 +1,2 @@
1
+ import { type FallbackInput, type FallbackOutput, type MorphClientProvider } from "./types.js";
2
+ export declare function runMorphTier(input: FallbackInput, client: MorphClientProvider): Promise<FallbackOutput>;