@fjall/generator 14.1.0 → 14.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/.build-source-hash +50 -45
  2. package/dist/.minified +1 -1
  3. package/dist/src/ast/astTestHelpers.d.ts +2 -0
  4. package/dist/src/ast/domain/astDomainParser.d.ts +24 -0
  5. package/dist/src/ast/domain/astDomainParser.js +1 -1
  6. package/dist/src/ast/index.d.ts +1 -1
  7. package/dist/src/ast/index.js +1 -1
  8. package/dist/src/ast/parsers/resources/astCdnParser.js +1 -1
  9. package/dist/src/ast/parsers/resources/astComputeParser.js +1 -1
  10. package/dist/src/codemod/drift/index.d.ts +1 -1
  11. package/dist/src/codemod/drift/index.js +1 -1
  12. package/dist/src/codemod/drift/snapshot.d.ts +33 -1
  13. package/dist/src/codemod/drift/snapshot.js +1 -1
  14. package/dist/src/codemod/drift/types.d.ts +16 -1
  15. package/dist/src/codemod/drift/types.js +1 -1
  16. package/dist/src/codemod/edits/addResource/propertyBuilder.d.ts +8 -0
  17. package/dist/src/codemod/edits/addResource/propertyBuilder.js +1 -1
  18. package/dist/src/codemod/edits/addResource/siblingEmission.d.ts +61 -0
  19. package/dist/src/codemod/edits/addResource/siblingEmission.js +1 -0
  20. package/dist/src/codemod/edits/addResource.js +1 -1
  21. package/dist/src/codemod/edits/connectResourceToCompute.js +1 -1
  22. package/dist/src/codemod/edits/ensureImports.d.ts +18 -0
  23. package/dist/src/codemod/edits/ensureImports.js +1 -1
  24. package/dist/src/codemod/edits/modifyResource.js +1 -1
  25. package/dist/src/codemod/edits/resourceStatementLocator.d.ts +3 -0
  26. package/dist/src/codemod/edits/resourceStatementLocator.js +1 -1
  27. package/dist/src/codemod/edits/siblingBindingResolution.d.ts +54 -1
  28. package/dist/src/codemod/edits/siblingBindingResolution.js +1 -1
  29. package/dist/src/codemod/emitGuard.d.ts +2 -30
  30. package/dist/src/codemod/emitGuard.js +1 -1
  31. package/dist/src/codemod/emitProjection.d.ts +31 -2
  32. package/dist/src/codemod/emitProjection.js +1 -1
  33. package/dist/src/codemod/fileRewriter/builders.d.ts +18 -0
  34. package/dist/src/codemod/fileRewriter/builders.js +1 -1
  35. package/dist/src/codemod/fileRewriter/index.d.ts +1 -1
  36. package/dist/src/codemod/fileRewriter/index.js +1 -1
  37. package/dist/src/codemod/index.d.ts +3 -2
  38. package/dist/src/codemod/index.js +1 -1
  39. package/dist/src/codemod/llmFallback/index.d.ts +1 -1
  40. package/dist/src/codemod/llmFallback/index.js +1 -1
  41. package/dist/src/codemod/llmFallback/shouldTryFallback.d.ts +9 -0
  42. package/dist/src/codemod/llmFallback/shouldTryFallback.js +1 -1
  43. package/dist/src/codemod/registry.d.ts +26 -27
  44. package/dist/src/codemod/registry.js +1 -1
  45. package/dist/src/codemod/validationGate/gates/projection.js +1 -1
  46. package/dist/src/dns/domainFileGenerator.js +8 -3
  47. package/dist/src/dns/domainRecords.d.ts +30 -0
  48. package/dist/src/dns/domainRecords.js +1 -1
  49. package/dist/src/dns/tsEmitter.js +9 -9
  50. package/dist/src/generation/common.js +8 -8
  51. package/dist/src/generation/connectionWiring.d.ts +83 -0
  52. package/dist/src/generation/connectionWiring.js +1 -0
  53. package/dist/src/generation/database.d.ts +3 -34
  54. package/dist/src/generation/database.js +20 -20
  55. package/dist/src/generation/index.d.ts +1 -0
  56. package/dist/src/generation/index.js +1 -1
  57. package/dist/src/generation/infrastructure.d.ts +11 -0
  58. package/dist/src/generation/infrastructure.js +38 -28
  59. package/dist/src/generation/messagingConnections.d.ts +1 -4
  60. package/dist/src/generation/messagingConnections.js +1 -1
  61. package/dist/src/generation/storageConnections.d.ts +1 -12
  62. package/dist/src/generation/storageConnections.js +1 -1
  63. package/dist/src/planning/resourceAddition.d.ts +3 -0
  64. package/dist/src/planning/resourceAddition.js +1 -1
  65. package/dist/src/projection/compute.d.ts +31 -0
  66. package/dist/src/projection/compute.js +1 -0
  67. package/dist/src/projection/index.d.ts +3 -2
  68. package/dist/src/projection/index.js +1 -1
  69. package/dist/src/projection/project.d.ts +16 -1
  70. package/dist/src/projection/project.js +1 -1
  71. package/dist/src/projection/roundTripKeys.d.ts +12 -0
  72. package/dist/src/projection/roundTripKeys.js +1 -0
  73. package/dist/src/projection/tables.d.ts +13 -9
  74. package/dist/src/projection/tables.js +1 -1
  75. package/dist/src/projection/types.d.ts +204 -4
  76. package/dist/src/projection/unresolved.d.ts +17 -0
  77. package/dist/src/projection/unresolved.js +1 -0
  78. package/dist/src/schemas/applicationSchemas.d.ts +2 -0
  79. package/dist/src/schemas/cdnSchemas.d.ts +4 -0
  80. package/dist/src/schemas/cdnSchemas.js +1 -1
  81. package/dist/src/schemas/computeSchemas.js +1 -1
  82. package/dist/src/validation/validationMessages.d.ts +1 -0
  83. package/dist/src/validation/validationMessages.js +1 -1
  84. package/dist/src/version.d.ts +1 -1
  85. package/dist/src/version.js +1 -1
  86. package/package.json +2 -2
@@ -0,0 +1,61 @@
1
+ import { type namedTypes as n } from "ast-types";
2
+ import { type Result } from "../../../types/Result.js";
3
+ import type { EmittedSibling } from "../../emitProjection.js";
4
+ import { type QuoteStyle } from "../../fileRewriter/index.js";
5
+ import type { InvalidPropertyError } from "../../types.js";
6
+ import { type NodeShapeLike, type ObjectExpressionNodeLike } from "../modifyResource/literalConversion.js";
7
+ import type { PendingDeclaration } from "../siblingBindingResolution.js";
8
+ export interface SiblingEmissionPlan {
9
+ /** Sibling statements in derivation order, ready to splice after the
10
+ * primary statement. */
11
+ statements: n.ExpressionStatement[];
12
+ /**
13
+ * Set when a sibling prop references the primary construct: the caller must
14
+ * bind the primary statement under this name (`const <name> = app.<m>(…)`)
15
+ * — the substituted identifiers below point at it.
16
+ */
17
+ primaryBindingName?: string;
18
+ }
19
+ export interface PlanSiblingEmissionParams {
20
+ siblings: ReadonlyArray<EmittedSibling>;
21
+ body: NodeShapeLike[];
22
+ appIdentifier: string;
23
+ resourceName: string;
24
+ quoteStyle: QuoteStyle;
25
+ /**
26
+ * The `const` names this edit's pending wrap plans will declare. The body
27
+ * check below sees only PRE-mutation declarations, so a primary binding
28
+ * whose name a pending wrap already claims (`"Uploads"` and a connected
29
+ * `"uploads"` both derive `uploads`) must be refused here — applied
30
+ * together they write a file that does not parse.
31
+ */
32
+ pendingDeclarations?: ReadonlyArray<PendingDeclaration>;
33
+ }
34
+ /**
35
+ * Resolve the emitted siblings to AST statements, or the refusal that stops
36
+ * the add. Every refusal is attributed to the PLAN key that asked for the
37
+ * sibling, so the operator sees the flag they typed, never a derived
38
+ * construct id they did not.
39
+ */
40
+ export declare function planSiblingEmission(params: PlanSiblingEmissionParams): Result<SiblingEmissionPlan, InvalidPropertyError>;
41
+ /**
42
+ * True when any statement already carries `<recv>.<appMethod>("<id>", …)` for
43
+ * this sibling — wherever it sits (bare, `const`-bound, export-wrapped): the
44
+ * construct id is what collides at synth, not the statement shape.
45
+ *
46
+ * The scan matches only string-literal first arguments, so a same-id
47
+ * construct written as a template literal is invisible to it.
48
+ *
49
+ * Exported for the projection gate, which asserts the PRESENCE of derived
50
+ * sibling statements in fallback output through the same matcher the add
51
+ * path uses to refuse duplicates — two matchers would disagree on exactly
52
+ * the shapes that matter.
53
+ */
54
+ export declare function bodyCarriesSibling(body: NodeShapeLike[], sibling: Pick<EmittedSibling, "appMethod" | "constructId">): boolean;
55
+ /**
56
+ * The props object (second argument) of the sibling's emitted call, when the
57
+ * body carries the sibling and that argument is a plain object literal.
58
+ * Exported for the projection gate, which verifies the emitted statement
59
+ * carries every derived prop key — through the same matcher as above.
60
+ */
61
+ export declare function siblingCallPropsObject(body: NodeShapeLike[], sibling: Pick<EmittedSibling, "appMethod" | "constructId">): ObjectExpressionNodeLike | undefined;
@@ -0,0 +1 @@
1
+ var m=Object.defineProperty;var s=(e,t)=>m(e,"name",{value:t,configurable:!0});import{toVariableName as y}from"../../../generation/common.js";import{failure as u,success as b}from"../../../types/Result.js";import{buildAppMethodStatement as h}from"../../fileRewriter/index.js";import{isNodeShape as f}from"../modifyResource/literalConversion.js";import{visit as g}from"../objectGraph.js";import{appMethodNameOf as k,moduleScopeDeclares as w}from"../resourceStatementLocator.js";import{buildPropertyInputs as E,RESERVED_IDENTIFIER_NAMES as I}from"./propertyBuilder.js";function A(e){for(const r of e.siblings)if($(e.body,r))return u({kind:"InvalidPropertyError",property:r.planKey,reason:`\`${r.planKey}\` expands into the statement \`app.${r.appMethod}("${r.constructId}", \u2026)\`, and this file already carries one \u2014 the two would collide at synth. Remove or rename the existing statement, or drop the key.`});const t=e.siblings.find(r=>r.props.some(i=>i.kind==="structured"&&c(i.expression)));let n;if(t!==void 0){const r=y(e.resourceName);if(I.has(r))return u({kind:"InvalidPropertyError",property:t.planKey,reason:`\`${t.planKey}\` references the primary construct, which must be bound as \`const ${r}\` \u2014 but \`${r}\` is a JavaScript reserved word, so the binding would write a file that does not parse. Rename the resource.`});if(w(e.body,r))return u({kind:"InvalidPropertyError",property:t.planKey,reason:`\`${t.planKey}\` references the primary construct, which must be bound as \`const ${r}\` \u2014 but this file already declares \`${r}\`. Rename the resource or the existing binding.`});const i=e.pendingDeclarations?.find(o=>o.variableName===r);if(i!==void 0)return u({kind:"InvalidPropertyError",property:t.planKey,reason:`\`${t.planKey}\` references the primary construct, which must be bound as \`const ${r}\` \u2014 but this add already binds the connected resource "${i.resourceName}" under that name ("${e.resourceName}" and "${i.resourceName}" derive the same variable), and declaring it twice would write a file that does not parse. Rename one of the two resources.`});n=r}const a=[];for(const r of e.siblings){const i=n===void 0?r.props:S(r.props,n),o=E(i,e.quoteStyle);if(!o.success)return u(o.error);a.push(h({appIdentifier:e.appIdentifier,appMethod:r.appMethod,name:r.constructId,properties:o.data,quoteStyle:e.quoteStyle}))}return b({statements:a,...n!==void 0&&{primaryBindingName:n}})}s(A,"planSiblingEmission");function $(e,t){return p(e,t)!==void 0}s($,"bodyCarriesSibling");function C(e,t){const n=p(e,t);if(n===void 0)return;const a=n.arguments;if(!Array.isArray(a))return;const r=a[1];if(!(!f(r)||r.type!=="ObjectExpression"))return r}s(C,"siblingCallPropsObject");function p(e,t){let n;for(const a of e)if(g(a,r=>{if(n!==void 0||r.type!=="CallExpression"||k(r)!==t.appMethod)return;const i=r.arguments;if(!Array.isArray(i))return;const o=i[0];f(o)&&(o.type!=="StringLiteral"&&o.type!=="Literal"||o.value===t.constructId&&(n=r))}),n!==void 0)return n}s(p,"findSiblingCall");function c(e){switch(e.kind){case"primary-binding":return!0;case"member":return c(e.object);case"call":return c(e.callee);case"object":return e.entries.some(t=>c(t.value));case"array":return e.elements.some(c);case"literal":case"identifier":return!1}}s(c,"valueReferencesPrimary");function S(e,t){return e.map(n=>n.kind==="structured"?{...n,expression:d(n.expression,t)}:n)}s(S,"substitutePrimaryInProps");function d(e,t){switch(e.kind){case"literal":return e;case"object":return{kind:"object",entries:e.entries.map(n=>({key:n.key,value:d(n.value,t)}))};case"array":return{kind:"array",elements:e.elements.map(n=>d(n,t))};default:return l(e,t)}}s(d,"substituteValue");function l(e,t){switch(e.kind){case"primary-binding":return{kind:"identifier",name:t};case"member":return{...e,object:l(e.object,t)};case"call":return{...e,callee:l(e.callee,t)};case"identifier":return e}}s(l,"substituteExpression");export{$ as bodyCarriesSibling,A as planSiblingEmission,C as siblingCallPropsObject};
@@ -1 +1 @@
1
- var M=Object.defineProperty;var u=(r,e)=>M(r,"name",{value:e,configurable:!0});import{failure as t,success as R}from"../../types/Result.js";import{DEFAULT_FILE_PATH as C,computeLinesDelta as w,extractProgramBody as b,isRecord as x}from"../_internal.js";import{evaluateEmitGuard as N}from"../emitGuard.js";import{projectEmittedProperties as G}from"../emitProjection.js";import{appendSpecifier as Q,buildAppMethodWrappedStatement as O,buildFactoryStatement as U,buildImportDeclaration as W,detectQuoteStyle as _,parse as j,printFile as Y}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as q,constructIdFor as H}from"../registry.js";import{locateAllShapes as $,locateByShape as z}from"../semanticIndex/index.js";import{checkControlFlowPolicy as J}from"./controlFlowPolicy.js";import{driftGate as K,runPipeline as V,schemaGate as X}from"../validationGate/index.js";import{resolveAppBindingName as Z}from"./addResource/appBinding.js";import{buildUnmanagedDuplicateError as ee}from"./unmanagedShapeErrors.js";import{buildResourceLocations as re,indexBody as te,orderByEndPos as ae,resolveInsertIndex as ne}from"./addResource/bodyIndex.js";import{buildPropertyInputs as ie}from"./addResource/propertyBuilder.js";import{findInsertionPosition as oe}from"./findInsertionPosition.js";import{applyBinding as se}from"./resourceStatementLocator.js";import{createSiblingBindingResolution as ce}from"./siblingBindingResolution.js";const L="@fjall/components-infrastructure";function Fe(r,e,m={}){const p=e.filePath??C,n=j(r,p);if(!n.success)return t(n.error);const a=z(r,{type:e.type,name:e.name},p);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(ee(e.type,a.data.symbolName));const i=J({ast:n.data,target:a.data,resource:{type:e.type,name:e.name},op:"add"});if(i.refusal!==void 0)return t(i.refusal);const g=V([K],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"},baseline:m.baseline,policy:e.driftPolicy});return g.success?g.data.action==="skip"?R({content:r,linesChanged:{added:0,removed:0},skipped:!0}):t({kind:"DuplicateResourceError",type:e.type,name:e.name}):t(B(g.error))}const l=_(n.data),h=ce(e.type,()=>b(n.data)),f=G(e.type,e.properties,{resourceName:e.name,resolveBinding:h.resolveBinding});if("refusal"in f)return t(f.refusal);const y=ie(f.props,l);if(!y.success)return t(y.error);const o=b(n.data);if(o===void 0)return t({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const s=q[e.type],I=N(s.emitGuard,e.properties);if(I!==void 0)return t(I);const S=X.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"}});if(!S.success)return t(B(S.error));const P={factory:s.factoryIdentifier,name:H(e.type,e.name,e.properties),properties:y.data,quoteStyle:l};let E;if(s.emitWrapper!==void 0){const i=Z(o);if(i===void 0)return t({kind:"MissingAppInitError",type:e.type,appMethod:s.emitWrapper.appMethod});E=O({...P,appIdentifier:i,appMethod:s.emitWrapper.appMethod})}else E=U(P);const d=te(o,r),c=$(r,p);if(!c.success)return c.error.kind==="TemplateLiteralNameError"?t(c.error):t({kind:"SemanticQueryError",reason:c.error.reason,cause:c.error.cause});const F=re(d.anchors,c.data),T=ae([...d.appInitLocations,...F]),v=oe(d.importInfos,T,e.type,d.programEnd),A=ne(d.anchors,v);for(const i of h.takePendingWraps())se(o,i);o.splice(A,0,E),pe(o,s.factoryIdentifier,l);const k=Y(n.data,r),D=w(r,k);return R({content:k,linesChanged:D})}u(Fe,"addResource");function B(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(B,"narrowGateError");function pe(r,e,m){for(const n of r){if(n.type!=="ImportDeclaration")continue;const a=n.source;if(!(!x(a)||a.type!=="StringLiteral")&&a.value===L){Q(n,e);return}}const p=W([e],L,m);r.unshift(p)}u(pe,"ensureFactoryImport");export{Fe as addResource};
1
+ var Q=Object.defineProperty;var S=(t,e)=>Q(t,"name",{value:e,configurable:!0});import{builders as P}from"ast-types";import{failure as a,success as M}from"../../types/Result.js";import{DEFAULT_FILE_PATH as W,computeLinesDelta as U,extractProgramBody as R}from"../_internal.js";import{evaluateEmitGuard as _}from"../emitGuard.js";import{collectImportSpecifiers as j,projectEmittedProperties as q}from"../emitProjection.js";import{buildAppMethodWrappedStatement as O,buildFactoryStatement as H,detectQuoteStyle as Y,parse as z,printFile as J}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as V,constructIdFor as X}from"../registry.js";import{locateAllShapes as Z,locateByShape as ee}from"../semanticIndex/index.js";import{checkControlFlowPolicy as re}from"./controlFlowPolicy.js";import{driftGate as ae,runPipeline as te,schemaGate as ne}from"../validationGate/index.js";import{resolveAppBindingName as ie}from"./addResource/appBinding.js";import{buildUnmanagedDuplicateError as oe}from"./unmanagedShapeErrors.js";import{buildResourceLocations as se,indexBody as de,orderByEndPos as pe,resolveInsertIndex as ce}from"./addResource/bodyIndex.js";import{buildPropertyInputs as le}from"./addResource/propertyBuilder.js";import{planSiblingEmission as me}from"./addResource/siblingEmission.js";import{ensureBarrelSpecifiers as ue}from"./ensureImports.js";import{findInsertionPosition as fe}from"./findInsertionPosition.js";import{applyBinding as ye}from"./resourceStatementLocator.js";import{createSiblingBindingResolution as ge,findPendingWrapCollision as Ee}from"./siblingBindingResolution.js";function $e(t,e,A={}){const h=e.filePath??W,s=z(t,h);if(!s.success)return a(s.error);const i=ee(t,{type:e.type,name:e.name},h);if(!i.success)return i.error.kind==="TemplateLiteralNameError"?a(i.error):a({kind:"SemanticQueryError",reason:i.error.reason,cause:i.error.cause});if(i.data!==void 0){if(i.data.managed===!1)return a(oe(e.type,i.data.symbolName));const r=re({ast:s.data,target:i.data,resource:{type:e.type,name:e.name},op:"add"});if(r.refusal!==void 0)return a(r.refusal);const n=te([ae],{content:t,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"},baseline:A.baseline,policy:e.driftPolicy});return n.success?n.data.action==="skip"?M({content:t,linesChanged:{added:0,removed:0},skipped:!0}):a({kind:"DuplicateResourceError",type:e.type,name:e.name}):a(L(n.error))}const f=Y(s.data),l=ge(e.type,()=>R(s.data)),m=q(e.type,e.properties,{resourceName:e.name,resolveBinding:l.resolveBinding,resolveBindings:l.resolveBindings});if("refusal"in m)return a(m.refusal);const I=Ee(l.pendingDeclarations());if(I!==void 0){const{first:r,second:n}=I,$=r.planKey!==void 0?`\`${r.planKey}\``:"another property",G=n.planKey!==void 0?`\`${n.planKey}\``:"this add";return a({kind:"InvalidPropertyError",property:n.planKey??r.planKey??e.name,reason:`${G} binds "${n.resourceName}" as \`const ${n.variableName}\` \u2014 but ${$} already binds "${r.resourceName}" under that name in this add (both names derive the same variable), and declaring it twice would write a file that does not parse. Rename one of the two resources.`})}const b=le(m.props,f);if(!b.success)return a(b.error);const o=R(s.data);if(o===void 0)return a({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const d=V[e.type],v=_(d.emitGuard,e.properties);if(v!==void 0)return a(v);const k=ne.run({content:t,plan:{type:e.type,name:e.name,properties:e.properties,op:"add"}});if(!k.success)return a(L(k.error));const B={factory:d.factoryIdentifier,name:X(e.type,e.name,e.properties),properties:b.data,quoteStyle:f},y=m.siblings??[],N=d.emitWrapper?.appMethod??y[0]?.appMethod;let p;if(N!==void 0&&(p=ie(o),p===void 0))return a({kind:"MissingAppInitError",type:e.type,appMethod:N});let g;d.emitWrapper!==void 0&&p!==void 0?g=O({...B,appIdentifier:p,appMethod:d.emitWrapper.appMethod}):g=H(B);let E={statements:[]};if(y.length>0&&p!==void 0){const r=me({siblings:y,body:o,appIdentifier:p,resourceName:e.name,quoteStyle:f,pendingDeclarations:l.pendingDeclarations()});if(!r.success)return a(r.error);E=r.data}const u=de(o,t),c=Z(t,h);if(!c.success)return c.error.kind==="TemplateLiteralNameError"?a(c.error):a({kind:"SemanticQueryError",reason:c.error.reason,cause:c.error.cause});const T=se(u.anchors,c.data),x=pe([...u.appInitLocations,...T]),C=fe(u.importInfos,x,e.type,u.programEnd),w=ce(u.anchors,C);for(const r of l.takePendingWraps())ye(o,r);const F=E.primaryBindingName===void 0?g:P.variableDeclaration("const",[P.variableDeclarator(P.identifier(E.primaryBindingName),g.expression)]);o.splice(w,0,F),E.statements.forEach((r,n)=>{o.splice(w+1+n,0,r)}),ue(o,[d.factoryIdentifier,...j([...m.props,...y.flatMap(r=>r.props)])],f);const D=J(s.data,t),K=U(t,D);return M({content:D,linesChanged:K})}S($e,"addResource");function L(t){switch(t.kind){case"ParseError":case"TemplateLiteralNameError":case"DuplicateResourceError":case"InvalidPropertyError":case"SemanticQueryError":case"MissingAppInitError":case"DriftConflictError":case"ControlFlowClassifierError":return t;default:return{kind:"SemanticQueryError",reason:`Unexpected codemod error in validation-gate pipeline: ${t.kind}`}}}S(L,"narrowGateError");export{$e as addResource};
@@ -1 +1 @@
1
- var B=Object.defineProperty;var p=(n,e)=>B(n,"name",{value:e,configurable:!0});import{builders as y}from"ast-types";import{CREDENTIAL_KEYS as T,DATABASE_ACCESSORS as v,DATABASE_ENV_VARS as E,DATABASE_SSL_VALUE as V}from"../../generation/database.js";import{MESSAGING_ENV_VARS as F}from"../../generation/messagingConnections.js";import{STORAGE_ACCESSORS as K,STORAGE_ENV_VARS as A}from"../../generation/storageConnections.js";import{connectionEnvSuffix as W,connectionKeyOrdinal as w}from"../../generation/common.js";import{failure as d,success as S}from"../../types/Result.js";import{DEFAULT_FILE_PATH as G,computeLinesDelta as H,extractProgramBody as z}from"../_internal.js";import{buildObjectProperty as U,detectQuoteStyle as Y,parse as J,printFile as Q}from"../fileRewriter/index.js";import{FACTORY_IDENTIFIERS as I,STATEMENT_REGISTRY as X}from"../registry.js";import{makeStringLiteral as P}from"./addResource/propertyBuilder.js";import{findLastPlainPropertyIndex as _,isArrayExpression as Z,locateContainer as q,locateServiceByName as ee}from"./computeServiceLocator.js";import{isNodeShape as g,readKeyName as x}from"./modifyResource/literalConversion.js";import{objectAbsenceIsProvable as $,pushPropertyPreservingComma as ne}from"./objectGraph.js";import{applyBinding as te,appMethodNameOf as re,planBinding as oe,unwrapExportDeclaration as ie}from"./resourceStatementLocator.js";const j=Object.freeze({database:I.database,storage:I.storage});function O(n){const e=X[n].emitWrapper?.appMethod;if(e===void 0)throw new Error(`No app method registered for statement type "${n}"`);return e}p(O,"requireAppMethod");const k=Object.freeze({database:O("database"),storage:O("storage")}),M=new Map([[k.database,0],[k.storage,1],[O("messaging"),2]]);function Pe(n,e){const t=e.filePath??G,{resourceType:o,resourceName:r}=e,i=[...new Set(e.serviceNames)];if(i.length===0)return d({kind:"UnsupportedConnectionShapeError",reason:"No target services were supplied."});const a=J(n,t);if(!a.success)return d(a.error);const s=z(a.data);if(s===void 0)return d({kind:"UnsupportedConnectionShapeError",reason:"recast File is missing program.body"});const c=oe(s,{factory:j[o],appMethod:k[o]},r);if(!c.success)return d(ae(c.error,o,r));const{variableName:u}=c.data,l=[],h=[];for(const m of i){const C=se(s,m,u,o);if(!C.success)return d(C.error);if(C.data==="already-connected"){l.push(m);continue}h.push(C.data)}const f=l.map(m=>`Service "${m}" already lists "${u}" in its \`connections\` array \u2014 left untouched.`);for(const m of h)m.container===void 0&&f.push(`Service "${m.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(h.length===0)return S({content:n,linesChanged:{added:0,removed:0},variableName:u,wiredServices:[],skipped:!0,warnings:f});const b=Y(a.data),L=le(s);te(s,c.data);for(const m of h)ue(m,u,o,b,L);const R=Q(a.data,n);return S({content:R,linesChanged:H(n,R),variableName:u,wiredServices:h.map(m=>m.serviceName),skipped:!1,warnings:f})}p(Pe,"connectResourceToCompute");function ae(n,e,t){switch(n.kind){case"statement-not-found":return{kind:"ResourceStatementNotFoundError",resourceType:e,resourceName:t};case"ambiguous":return{kind:"AmbiguousResourceStatementError",resourceType:e,resourceName:t,count:n.count};case"multiple-declarators":return{kind:"UnsupportedConnectionShapeError",reason:`The statement declaring "${t}" carries multiple declarators \u2014 the binding cannot be identified.`};case"pattern-binding":return{kind:"UnsupportedConnectionShapeError",reason:`The statement declaring "${t}" binds a pattern, not an identifier.`};case"unreadable-name":return{kind:"UnsupportedConnectionShapeError",reason:`The binding for "${t}" has no readable name.`};case"init-not-app-method-wrap":return{kind:"UnsupportedConnectionShapeError",reason:`The binding for "${t}" is not a direct \`app.${k[e]}(${j[e]}.build(...))\` call \u2014 the bound value is not the construct \`connections\` needs.`};case"unbindable-statement":return{kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${t}" is a ${n.statementType}, which cannot be bound to a const.`};case"not-app-method-call":return{kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${t}" is not an app-method call \u2014 there is no construct value to bind.`};case"bare-factory-call":return{kind:"UnsupportedConnectionShapeError",reason:`"${t}" is a bare factory call not wrapped in an app method \u2014 there is no construct value to bind.`};case"foreign-wrapper":return{kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${t}" is not a direct \`app.${k[e]}(...)\` call \u2014 binding it would wire a value \`connections\` cannot use.`};case"name-conflict":return{kind:"VariableNameConflictError",variableName:n.variableName};case"reserved-word":return{kind:"UnsupportedConnectionShapeError",reason:`Binding "${t}" would derive the variable name "${n.variableName}", a JavaScript reserved word no \`const\` can carry \u2014 bind the statement to a const of your own naming, or rename the resource.`}}}p(ae,"mapLocatorFailure");function se(n,e,t,o){const r=ee(n,e);if(!r.success){const f=r.error;return f.kind==="AmbiguousService"?d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:`${String(f.count)} services share the name "${e}" across ComputeFactory.build calls \u2014 the edit cannot be proven to target the right one.`}):d({kind:"ConnectServiceNotFoundError",serviceName:e,knownServices:f.knownServices})}const i=r.data,a=q(i,0);let s;if(a.success)s=a.data;else switch(a.error.kind){case"ContainerNotObjectLiteral":return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"The first container is not an object literal."});case"ContainersNotStaticArray":return d({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 d({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 c=ce(i,e,t);if(!c.success)return d(c.error);if(c.data.alreadyConnected)return S("already-connected");let u,l,h="";if(s!==void 0){const f=N(s,"environment",e);if(!f.success)return d(f.error);const b=N(s,"secretsImport",e);if(!b.success)return d(b.error);u=f.data,l=b.data,h=de(o,[...f.data.keys,...b.data.keys])}return S({serviceName:e,service:i,container:s,environment:u,secretsImport:l,suffix:h,connectionsArray:c.data.array})}p(se,"planService");function ce(n,e,t){const o=_(n,"connections");if(o===-1)return $(n,"connections")?S({array:void 0,alreadyConnected:!1}):d({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=n.properties[o]?.value;if(!Z(r))return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"`connections` is not an array literal."});for(const i of r.elements)if(g(i)){if(i.type==="Identifier"){if(i.name===t)return S({array:r,alreadyConnected:!0});continue}return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:`\`connections\` contains a ${i.type}, so "${t}" cannot be proven absent from it.`})}return S({array:r,alreadyConnected:!1})}p(ce,"inspectConnections");function N(n,e,t){const o=_(n,e);if(o===-1)return $(n,e)?S({obj:void 0,keys:[]}):d({kind:"UnsupportedConnectionShapeError",serviceName:t,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=n.properties[o]?.value;if(!g(r)||r.type!=="ObjectExpression")return d({kind:"UnsupportedConnectionShapeError",serviceName:t,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 d({kind:"UnsupportedConnectionShapeError",serviceName:t,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 d({kind:"UnsupportedConnectionShapeError",serviceName:t,reason:`\`${e}\` contains a computed key.`});const c=x(s.key);c!==void 0&&a.push(c)}return S({obj:i,keys:a})}p(N,"collectWiringTarget");function de(n,e){const t=Object.values(n==="database"?E:A),o=new Set;for(const r of e)for(const i of t){const a=w(r,i);a!==void 0&&o.add(a)}return W(o.size===0?0:Math.max(...o))}p(de,"nextConnectionSuffix");function pe(n,e,t,o){const r=p((s,c,u=[])=>y.callExpression(y.memberExpression(s,y.identifier(c),!1),u),"call"),i=p(()=>y.identifier(e),"variable");if(n==="storage")return[{key:`${A.NAME}${t}`,value:r(i(),K.BUCKET_NAME),target:"environment"}];const a=p(s=>r(r(i(),v.CREDENTIALS),v.IMPORT,[P(s,o)]),"credential");return[{key:`${E.HOST}${t}`,value:r(i(),v.HOST),target:"environment"},{key:`${E.PORT}${t}`,value:r(i(),v.PORT),target:"environment"},{key:`${E.NAME}${t}`,value:r(i(),v.NAME),target:"environment"},{key:`${E.SSL}${t}`,value:P(V,o),target:"environment"},{key:`${E.USERNAME}${t}`,value:a(T.USERNAME),target:"secretsImport"},{key:`${E.PASSWORD}${t}`,value:a(T.PASSWORD),target:"secretsImport"}]}p(pe,"buildWiringEntries");function ue(n,e,t,o,r){if(n.connectionsArray!==void 0){const c=fe(n.connectionsArray,t,r);n.connectionsArray.elements.splice(c,0,y.identifier(e))}else D(n.service,"connections",y.arrayExpression([y.identifier(e)]),o);const i=n.container;if(i===void 0)return;const a=pe(t,e,n.suffix,o),s=[{key:"environment",state:n.environment},{key:"secretsImport",state:n.secretsImport}];for(const{key:c,state:u}of s){const l=a.filter(h=>h.target===c);l.length!==0&&Se(i,c,u,l,o)}}p(ue,"applyServiceWiring");function fe(n,e,t){const o=M.get(k[e])??0;for(let r=0;r<n.elements.length;r++){const i=n.elements[r];if(!g(i)||i.type!=="Identifier")continue;const a=i.name;if(typeof a!="string")continue;const s=t.get(a);if(s!==void 0&&s>o)return r}return n.elements.length}p(fe,"connectionInsertIndex");function le(n){const e=new Map;for(const t of n){const o=ie(t);if(o===void 0||o.type!=="VariableDeclaration")continue;const r=o.declarations;if(Array.isArray(r))for(const i of r){if(!g(i))continue;const a=i.id,s=i.init;if(!g(a)||a.type!=="Identifier"||!g(s))continue;const c=a.name;if(typeof c!="string")continue;const u=re(s);if(u===void 0)continue;const l=M.get(u);l!==void 0&&e.set(c,l)}}return e}p(le,"collectConnectionRanks");const me=Object.freeze([...Object.values(E),...Object.values(A),...Object.values(F)]);function he(n){let e=-1;for(let t=0;t<n.properties.length;t++){const o=n.properties[t];if(o===void 0||o.type!=="Property"&&o.type!=="ObjectProperty"||o.computed===!0)continue;const r=x(o.key);if(r===void 0)continue;me.some(a=>w(r,a)!==void 0)&&(e=t)}return e===-1?n.properties.length:e+1}p(he,"connectionEntryInsertIndex");function Se(n,e,t,o,r){const i=o.map(c=>U(c.key,c.value,r)),a=t?.obj;if(a===void 0){D(n,e,y.objectExpression(i),r);return}const s=he(a);a.properties.splice(s,0,...i)}p(Se,"insertObjectEntries");function D(n,e,t,o){const r=U(e,t,o);ne(n,r)}p(D,"appendProperty");export{Pe as connectResourceToCompute};
1
+ var L=Object.defineProperty;var p=(n,e)=>L(n,"name",{value:e,configurable:!0});import{builders as b}from"ast-types";import{CONNECTION_TYPE_ORDER as V,DATABASE_ACCESSORS as O,DATABASE_ENV_VARS as w,MESSAGING_ENV_VARS as B,STORAGE_ENV_VARS as T,buildConnectionWiringEntries as F}from"../../generation/connectionWiring.js";import{connectionEnvSuffix as K,connectionKeyOrdinal as R}from"../../generation/common.js";import{failure as d,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as W,computeLinesDelta as z,extractProgramBody as G}from"../_internal.js";import{buildObjectProperty as x,detectQuoteStyle as H,parse as Y,printFile as J}from"../fileRewriter/index.js";import{FACTORY_IDENTIFIERS as I,STATEMENT_REGISTRY as Q}from"../registry.js";import{makeStringLiteral as $}from"./addResource/propertyBuilder.js";import{findLastPlainPropertyIndex as U,isArrayExpression as X,locateContainer as Z,locateServiceByName as q}from"./computeServiceLocator.js";import{isNodeShape as S,readKeyName as P}from"./modifyResource/literalConversion.js";import{objectAbsenceIsProvable as k,pushPropertyPreservingComma as ee}from"./objectGraph.js";import{applyBinding as ne,appMethodNameOf as te,planBinding as re,unwrapExportDeclaration as oe}from"./resourceStatementLocator.js";const _=Object.freeze({database:I.database,storage:I.storage});function v(n){const e=Q[n].emitWrapper?.appMethod;if(e===void 0)throw new Error(`No app method registered for statement type "${n}"`);return e}p(v,"requireAppMethod");const C=Object.freeze({database:v("database"),storage:v("storage")}),j=new Map(V.map((n,e)=>[v(n),e]));function Ie(n,e){const t=e.filePath??W,{resourceType:r,resourceName:o}=e,i=[...new Set(e.serviceNames)];if(i.length===0)return d({kind:"UnsupportedConnectionShapeError",reason:"No target services were supplied."});const a=Y(n,t);if(!a.success)return d(a.error);const s=G(a.data);if(s===void 0)return d({kind:"UnsupportedConnectionShapeError",reason:"recast File is missing program.body"});const c=re(s,{factory:_[r],appMethod:C[r]},o);if(!c.success)return d(ie(c.error,r,o));const{variableName:u}=c.data,l=[],m=[];for(const h of i){const g=ae(s,h,u,r);if(!g.success)return d(g.error);if(g.data==="already-connected"){l.push(h);continue}m.push(g.data)}const f=l.map(h=>`Service "${h}" already lists "${u}" in its \`connections\` array \u2014 left untouched.`);for(const h of m)h.container===void 0&&f.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(m.length===0)return y({content:n,linesChanged:{added:0,removed:0},variableName:u,wiredServices:[],skipped:!0,warnings:f});const E=H(a.data),D=le(s);ne(s,c.data);for(const h of m)ue(h,u,r,E,D);const A=J(a.data,n);return y({content:A,linesChanged:z(n,A),variableName:u,wiredServices:m.map(h=>h.serviceName),skipped:!1,warnings:f})}p(Ie,"connectResourceToCompute");function ie(n,e,t){switch(n.kind){case"statement-not-found":return{kind:"ResourceStatementNotFoundError",resourceType:e,resourceName:t};case"ambiguous":return{kind:"AmbiguousResourceStatementError",resourceType:e,resourceName:t,count:n.count};case"multiple-declarators":return{kind:"UnsupportedConnectionShapeError",reason:`The statement declaring "${t}" carries multiple declarators \u2014 the binding cannot be identified.`};case"pattern-binding":return{kind:"UnsupportedConnectionShapeError",reason:`The statement declaring "${t}" binds a pattern, not an identifier.`};case"unreadable-name":return{kind:"UnsupportedConnectionShapeError",reason:`The binding for "${t}" has no readable name.`};case"init-not-app-method-wrap":return{kind:"UnsupportedConnectionShapeError",reason:`The binding for "${t}" is not a direct \`app.${C[e]}(${_[e]}.build(...))\` call \u2014 the bound value is not the construct \`connections\` needs.`};case"unbindable-statement":return{kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${t}" is a ${n.statementType}, which cannot be bound to a const.`};case"not-app-method-call":return{kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${t}" is not an app-method call \u2014 there is no construct value to bind.`};case"bare-factory-call":return{kind:"UnsupportedConnectionShapeError",reason:`"${t}" is a bare factory call not wrapped in an app method \u2014 there is no construct value to bind.`};case"foreign-wrapper":return{kind:"UnsupportedConnectionShapeError",reason:`The statement containing "${t}" is not a direct \`app.${C[e]}(...)\` call \u2014 binding it would wire a value \`connections\` cannot use.`};case"name-conflict":return{kind:"VariableNameConflictError",variableName:n.variableName};case"reserved-word":return{kind:"UnsupportedConnectionShapeError",reason:`Binding "${t}" would derive the variable name "${n.variableName}", a JavaScript reserved word no \`const\` can carry \u2014 bind the statement to a const of your own naming, or rename the resource.`}}}p(ie,"mapLocatorFailure");function ae(n,e,t,r){const o=q(n,e);if(!o.success){const f=o.error;return f.kind==="AmbiguousService"?d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:`${String(f.count)} services share the name "${e}" across ComputeFactory.build calls \u2014 the edit cannot be proven to target the right one.`}):d({kind:"ConnectServiceNotFoundError",serviceName:e,knownServices:f.knownServices})}const i=o.data,a=Z(i,0);let s;if(a.success)s=a.data;else switch(a.error.kind){case"ContainerNotObjectLiteral":return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"The first container is not an object literal."});case"ContainersNotStaticArray":return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"`containers` is not a static array literal, so the container to wire cannot be located."});case"NoContainersArray":if(!k(i,"containers"))return d({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 c=se(i,e,t);if(!c.success)return d(c.error);if(c.data.alreadyConnected)return y("already-connected");let u,l,m="";if(s!==void 0){const f=M(s,"environment",e);if(!f.success)return d(f.error);const E=M(s,"secretsImport",e);if(!E.success)return d(E.error);u=f.data,l=E.data,m=ce(r,[...f.data.keys,...E.data.keys])}return y({serviceName:e,service:i,container:s,environment:u,secretsImport:l,suffix:m,connectionsArray:c.data.array})}p(ae,"planService");function se(n,e,t){const r=U(n,"connections");if(r===-1)return k(n,"connections")?y({array:void 0,alreadyConnected:!1}):d({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 o=n.properties[r]?.value;if(!X(o))return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:"`connections` is not an array literal."});for(const i of o.elements)if(S(i)){if(i.type==="Identifier"){if(i.name===t)return y({array:o,alreadyConnected:!0});continue}return d({kind:"UnsupportedConnectionShapeError",serviceName:e,reason:`\`connections\` contains a ${i.type}, so "${t}" cannot be proven absent from it.`})}return y({array:o,alreadyConnected:!1})}p(se,"inspectConnections");function M(n,e,t){const r=U(n,e);if(r===-1)return k(n,e)?y({obj:void 0,keys:[]}):d({kind:"UnsupportedConnectionShapeError",serviceName:t,reason:`The first container carries a spread, shorthand or computed key that could supply \`${e}\` invisibly, so an absent property cannot be proven.`});const o=n.properties[r]?.value;if(!S(o)||o.type!=="ObjectExpression")return d({kind:"UnsupportedConnectionShapeError",serviceName:t,reason:`\`${e}\` is not an object literal.`});const i=o,a=[];for(const s of i.properties){if(s.type==="SpreadElement"||s.type==="SpreadProperty")return d({kind:"UnsupportedConnectionShapeError",serviceName:t,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 d({kind:"UnsupportedConnectionShapeError",serviceName:t,reason:`\`${e}\` contains a computed key.`});const c=P(s.key);c!==void 0&&a.push(c)}return y({obj:i,keys:a})}p(M,"collectWiringTarget");function ce(n,e){const t=Object.values(n==="database"?w:T),r=new Set;for(const o of e)for(const i of t){const a=R(o,i);a!==void 0&&r.add(a)}return K(r.size===0?0:Math.max(...r))}p(ce,"nextConnectionSuffix");function de(n,e,t,r){return F(n,t).map(o=>({key:o.key,value:pe(o.value,e,r),target:o.target}))}p(de,"buildWiringEntries");function pe(n,e,t){const r=p((o,i,a=[])=>b.callExpression(b.memberExpression(o,b.identifier(i),!1),a),"call");switch(n.kind){case"accessor":return r(b.identifier(e),n.method);case"credential":return r(r(b.identifier(e),O.CREDENTIALS),O.IMPORT,[$(n.credentialKey,t)]);case"literal":return $(n.value,t)}}p(pe,"wiringValueNode");function ue(n,e,t,r,o){if(n.connectionsArray!==void 0){const c=fe(n.connectionsArray,t,o);n.connectionsArray.elements.splice(c,0,b.identifier(e))}else N(n.service,"connections",b.arrayExpression([b.identifier(e)]),r);const i=n.container;if(i===void 0)return;const a=de(t,e,n.suffix,r),s=[{key:"environment",state:n.environment},{key:"secretsImport",state:n.secretsImport}];for(const{key:c,state:u}of s){const l=a.filter(m=>m.target===c);l.length!==0&&be(i,c,u,l,r)}}p(ue,"applyServiceWiring");function fe(n,e,t){const r=j.get(C[e])??0;for(let o=0;o<n.elements.length;o++){const i=n.elements[o];if(!S(i)||i.type!=="Identifier")continue;const a=i.name;if(typeof a!="string")continue;const s=t.get(a);if(s!==void 0&&s>r)return o}return n.elements.length}p(fe,"connectionInsertIndex");function le(n){const e=new Map;for(const t of n){const r=oe(t);if(r===void 0||r.type!=="VariableDeclaration")continue;const o=r.declarations;if(Array.isArray(o))for(const i of o){if(!S(i))continue;const a=i.id,s=i.init;if(!S(a)||a.type!=="Identifier"||!S(s))continue;const c=a.name;if(typeof c!="string")continue;const u=te(s);if(u===void 0)continue;const l=j.get(u);l!==void 0&&e.set(c,l)}}return e}p(le,"collectConnectionRanks");const he=Object.freeze([...Object.values(w),...Object.values(T),...Object.values(B)]);function me(n){let e=-1;for(let t=0;t<n.properties.length;t++){const r=n.properties[t];if(r===void 0||r.type!=="Property"&&r.type!=="ObjectProperty"||r.computed===!0)continue;const o=P(r.key);if(o===void 0)continue;he.some(a=>R(o,a)!==void 0)&&(e=t)}return e===-1?n.properties.length:e+1}p(me,"connectionEntryInsertIndex");function be(n,e,t,r,o){const i=r.map(c=>x(c.key,c.value,o)),a=t?.obj;if(a===void 0){N(n,e,b.objectExpression(i),o);return}const s=me(a);a.properties.splice(s,0,...i)}p(be,"insertObjectEntries");function N(n,e,t,r){const o=x(e,t,r);ee(n,o)}p(N,"appendProperty");export{Ie as connectResourceToCompute};
@@ -1,7 +1,21 @@
1
1
  import type * as recast from "recast";
2
2
  import { type Result } from "../../types/Result.js";
3
+ import { type QuoteStyle } from "../fileRewriter/index.js";
3
4
  import type { SemanticQueryError } from "../types.js";
4
5
  type ParsedFile = ReturnType<typeof recast.parse>;
6
+ /** The components barrel every emitted factory/value import comes from. */
7
+ export declare const FACTORY_MODULE_SOURCE = "@fjall/components-infrastructure";
8
+ /**
9
+ * Ensure `specifiers` are named imports from the components barrel
10
+ * (`FACTORY_MODULE_SOURCE`) in a program body. Appends to the existing
11
+ * barrel import line when one exists (deduped by imported name via
12
+ * `appendSpecifier`); otherwise unshifts a new declaration at body[0] — the
13
+ * add path's historical placement, preserved byte-for-byte from its private
14
+ * `ensureFactoryImport`. This is the ONLY import-management path the emitted
15
+ * statements use; structured-expression `imports` are barrel specifiers by
16
+ * contract, never other modules.
17
+ */
18
+ export declare function ensureBarrelSpecifiers(body: StatementNode[], specifiers: readonly string[], quoteStyle: QuoteStyle): void;
5
19
  export interface EnsureImportsAddition {
6
20
  module: string;
7
21
  specifiers: string[];
@@ -23,4 +37,8 @@ export type EnsureImportsError = SemanticQueryError;
23
37
  * Never throws — every failure path returns `failure(EnsureImportsError)`.
24
38
  */
25
39
  export declare function ensureImports(file: ParsedFile, additions: EnsureImportsAddition[]): Result<EnsureImportsSuccess, EnsureImportsError>;
40
+ interface StatementNode {
41
+ type: string;
42
+ [key: string]: unknown;
43
+ }
26
44
  export {};
@@ -1 +1 @@
1
- var l=Object.defineProperty;var s=(t,r)=>l(t,"name",{value:r,configurable:!0});import{failure as d,success as c}from"../../types/Result.js";import{extractProgramBody as y,isRecord as I}from"../_internal.js";import{appendSpecifier as g,buildImportDeclaration as S,detectQuoteStyle as x}from"../fileRewriter/index.js";function k(t,r){const e=y(t);if(e===void 0)return d({kind:"SemanticQueryError",reason:"recast File is missing program.body"});if(r.length===0)return c({mutated:!1});const n=x(t);let o=!1;for(const i of r){const f=A(e,i.module);if(f!==void 0){for(const a of i.specifiers){const m=u(f);g(f,a),u(f)>m&&(o=!0)}continue}if(i.specifiers.length===0)continue;const p=S(i.specifiers,i.module,n);D(e,p),o=!0}return c({mutated:o})}s(k,"ensureImports");function A(t,r){for(const e of t){if(e.type!=="ImportDeclaration")continue;const n=e.source;if(I(n)&&!(n.type!=="StringLiteral"&&n.type!=="Literal")&&n.value===r)return e}}s(A,"findImportDeclaration");function D(t,r){let e=-1;for(let o=0;o<t.length;o+=1){const i=t[o];i!==void 0&&i.type==="ImportDeclaration"&&(e=o)}const n=e===-1?0:e+1;t.splice(n,0,r)}s(D,"insertAfterLastImport");function u(t){if(!Array.isArray(t.specifiers))return 0;let r=0;for(const e of t.specifiers)e!==null&&typeof e=="object"&&"type"in e&&e.type==="ImportSpecifier"&&(r+=1);return r}s(u,"countImportedNames");export{k as ensureImports};
1
+ var g=Object.defineProperty;var f=(e,r)=>g(e,"name",{value:r,configurable:!0});import{failure as S,success as c}from"../../types/Result.js";import{extractProgramBody as x,isRecord as h}from"../_internal.js";import{appendSpecifier as u,buildImportDeclaration as p,detectQuoteStyle as A}from"../fileRewriter/index.js";const a="@fjall/components-infrastructure";function j(e,r,t){if(r.length===0)return;const n=m(e,a);if(n!==void 0){for(const i of r)u(n,i);return}const o=p([...r],a,t);e.unshift(o)}f(j,"ensureBarrelSpecifiers");function w(e,r){const t=x(e);if(t===void 0)return S({kind:"SemanticQueryError",reason:"recast File is missing program.body"});if(r.length===0)return c({mutated:!1});const n=A(e);let o=!1;for(const i of r){const s=m(t,i.module);if(s!==void 0){for(const y of i.specifiers){const I=l(s);u(s,y),l(s)>I&&(o=!0)}continue}if(i.specifiers.length===0)continue;const d=p(i.specifiers,i.module,n);D(t,d),o=!0}return c({mutated:o})}f(w,"ensureImports");function m(e,r){for(const t of e){if(t.type!=="ImportDeclaration")continue;const n=t.source;if(h(n)&&!(n.type!=="StringLiteral"&&n.type!=="Literal")&&n.value===r)return t}}f(m,"findImportDeclaration");function D(e,r){let t=-1;for(let o=0;o<e.length;o+=1){const i=e[o];i!==void 0&&i.type==="ImportDeclaration"&&(t=o)}const n=t===-1?0:t+1;e.splice(n,0,r)}f(D,"insertAfterLastImport");function l(e){if(!Array.isArray(e.specifiers))return 0;let r=0;for(const t of e.specifiers)t!==null&&typeof t=="object"&&"type"in t&&t.type==="ImportSpecifier"&&(r+=1);return r}f(l,"countImportedNames");export{a as FACTORY_MODULE_SOURCE,j as ensureBarrelSpecifiers,w as ensureImports};
@@ -1 +1 @@
1
- var Q=Object.defineProperty;var d=(r,e)=>Q(r,"name",{value:e,configurable:!0});import{failure as o,success as E}from"../../types/Result.js";import{DEFAULT_FILE_PATH as U,computeLinesDelta as I,extractProgramBody as V}from"../_internal.js";import{buildObjectProperty as D,detectQuoteStyle as O,parse as K,printFile as _}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as M}from"../registry.js";import{locateAllShapes as W,locateByShape as H}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as Y}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as $}from"./controlFlowPolicy.js";import{driftGate as q,runPipeline as z,schemaGate as J}from"../validationGate/index.js";import{buildEmittedValue as X}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as C,collectPropertyKeys as Z,isNodeShape as v}from"./modifyResource/literalConversion.js";import{findPropertyByKey as ee,visit as re}from"./objectGraph.js";import{evaluateEmitGuard as N,UNRESOLVED as te}from"../emitGuard.js";import{projectEmittedProperties as ne,projectionRefusals as R}from"../emitProjection.js";import{applyBinding as ie}from"./resourceStatementLocator.js";import{createSiblingBindingResolution as ae}from"./siblingBindingResolution.js";function Ne(r,e,s={}){const n=e.filePath??U,i=K(r,n);if(!i.success)return o(i.error);const t=H(r,{type:e.type,name:e.name},n);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)return o({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:ce(r,e.type,n)});if(t.data.managed===!1)return o(Y(e.type,"modify"));const a=$({ast:i.data,target:t.data,resource:{type:e.type,name:e.name},op:"modify"});if(a.refusal!==void 0)return o(a.refusal);const u=z([q],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:s.baseline,policy:e.driftPolicy});if(!u.success)return o(G(u.error));if(u.data.action==="skip")return E({content:r,linesChanged:{added:0,removed:0},skipped:!0});const c=V(i.data);if(c===void 0)return o({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const f=se(c,t.data);if(f===void 0)return o({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const L=O(i.data),B=C(f,e.properties),h=M[e.type].emitGuard,l=ae(e.type,()=>c,{mustPrecedeStatementIndex:oe(c,t.data)??0}),m={editingExisting:!0,resourceName:e.name,resolveBinding:l.resolveBinding},P=T(f,C(f,{})),b=T(f,B),F=N(h,P),y=N(h,b);if(y!==void 0&&y.property!==F?.property)return o(y);const j=new Set(R(e.type,P,m).map(p=>p.property)),k=R(e.type,b,m).find(p=>!j.has(p.property));if(k!==void 0)return o(k);const S=J.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"}});if(!S.success)return o(G(S.error));l.takePendingWraps();const g=ne(e.type,e.properties,m);if("refusal"in g)return o(g.refusal);const w=ue(f,g.props,L);if(!w.success)return o(w.error);for(const p of l.takePendingWraps())ie(c,p);const x=_(i.data,r),A=a.warning!==void 0?[a.warning.message]:void 0;return E({content:x,linesChanged:I(r,x),warnings:A})}d(Ne,"modifyResource");function oe(r,e){const s=e.start+e.length;for(let n=0;n<r.length;n++){const i=r[n];if(i===void 0)continue;const{start:t,end:a}=i;if(!(typeof t!="number"||typeof a!="number")&&t<=e.start&&s<=a)return n}}d(oe,"findStatementIndexContaining");function T(r,e){const s={...e};for(const n of Z(r))n in s||(s[n]=te);return s}d(T,"buildGuardView");function G(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(G,"narrowGateError");function se(r,e){const s=e.start+e.length;let n;const i=d(t=>{if(n!==void 0||t.type!=="CallExpression")return;const a=t.arguments;if(!Array.isArray(a)||a.length<2)return;const u=a[0];if(!v(u)||u.type!=="StringLiteral"||u.start!==e.start||u.end!==s)return;const c=a[1];v(c)&&c.type==="ObjectExpression"&&(n=c)},"visitor");for(const t of r)if(re(t,i),n!==void 0)break;return n}d(se,"findConfigObject");function ue(r,e,s){const n=de(r);for(const i of e){const t=X(i,s);if(!t.success)return o(t.error);const a=ee(r,i.key);if(a!==void 0){a.value=t.data;continue}const u=D(i.key,t.data,s);n&&(u.extra={...u.extra??{},trailingComma:!0}),r.properties.push(u)}return E(void 0)}d(ue,"applyPropertyEdits");function de(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}d(de,"detectTrailingCommaStyle");function ce(r,e,s){const n=W(r,s);return n.success?n.data.filter(i=>i.type===e).map(i=>i.symbolName):[]}d(ce,"collectKnownNames");export{Ne as modifyResource};
1
+ var U=Object.defineProperty;var p=(r,e)=>U(r,"name",{value:e,configurable:!0});import{failure as s,success as x}from"../../types/Result.js";import{DEFAULT_FILE_PATH as V,computeLinesDelta as j,extractProgramBody as D}from"../_internal.js";import{buildObjectProperty as B,detectQuoteStyle as M,parse as _,printFile as W}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as H}from"../registry.js";import{locateAllShapes as Y,locateByShape as z}from"../semanticIndex/index.js";import{buildUnmanagedEditRefusal as J}from"./unmanagedShapeErrors.js";import{checkControlFlowPolicy as O}from"./controlFlowPolicy.js";import{driftGate as X,runPipeline as Z,schemaGate as q}from"../validationGate/index.js";import{buildEmittedValue as ee}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as R,collectPropertyKeys as re,isNodeShape as I,readKeyName as te}from"./modifyResource/literalConversion.js";import{findPropertyByKey as T,visit as ne}from"./objectGraph.js";import{evaluateEmitGuard as F,UNRESOLVED as ie}from"../emitGuard.js";import{collectImportSpecifiers as ae,projectEmittedProperties as oe,projectionRefusals as G}from"../emitProjection.js";import{constructKeyAliasesFor as se}from"../../projection/index.js";import{ensureBarrelSpecifiers as de}from"./ensureImports.js";import{applyBinding as ue}from"./resourceStatementLocator.js";import{createSiblingBindingResolution as pe}from"./siblingBindingResolution.js";function $e(r,e,i={}){const t=e.filePath??V,a=_(r,t);if(!a.success)return s(a.error);const n=z(r,{type:e.type,name:e.name},t);if(!n.success)return n.error.kind==="TemplateLiteralNameError"?s(n.error):s({kind:"SemanticQueryError",reason:n.error.reason,cause:n.error.cause});if(n.data===void 0)return s({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:Ee(r,e.type,t)});if(n.data.managed===!1)return s(J(e.type,"modify"));const o=O({ast:a.data,target:n.data,resource:{type:e.type,name:e.name},op:"modify"});if(o.refusal!==void 0)return s(o.refusal);const d=Z([X],{content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"},baseline:i.baseline,policy:e.driftPolicy});if(!d.success)return s(L(d.error));if(d.data.action==="skip")return x({content:r,linesChanged:{added:0,removed:0},skipped:!0});const u=D(a.data);if(u===void 0)return s({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const c=fe(u,n.data);if(c===void 0)return s({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const l=M(a.data),m=R(c,e.properties),k=H[e.type].emitGuard,h=pe(e.type,()=>u,{mustPrecedeStatementIndex:ce(u,n.data)??0}),E={editingExisting:!0,resourceName:e.name,resolveBinding:h.resolveBinding,resolveBindings:h.resolveBindings},w=K(c,R(c,{})),S=K(c,m),A=F(k,w),P=F(k,S);if(P!==void 0&&P.property!==A?.property)return s(P);const $=new Set(G(e.type,w,E).map(g=>g.property)),b=G(e.type,S,E).find(g=>!$.has(g.property));if(b!==void 0)return s(b);const v=q.run({content:r,plan:{type:e.type,name:e.name,properties:e.properties,op:"modify"}});if(!v.success)return s(L(v.error));h.takePendingWraps();const y=oe(e.type,e.properties,E);if("refusal"in y)return s(y.refusal);const f=y.siblings?.[0];if(f!==void 0)return s({kind:"InvalidPropertyError",property:f.planKey,reason:`\`${f.planKey}\` expands into its own \`app.${f.appMethod}("${f.constructId}", \u2026)\` statement, and \`fjall modify\` edits exactly one statement. Nothing has been written \u2014 this resource already exists, so \`fjall add\` would refuse it as a duplicate: author the \`app.${f.appMethod}("${f.constructId}", \u2026)\` statement in infrastructure.ts by hand, or remove the resource and re-add it with \`${f.planKey}\`.`});const C=le(c,e.type,y.props,l);if(!C.success)return s(C.error);for(const g of h.takePendingWraps())ue(u,g);de(u,ae(y.props),l);const N=W(a.data,r),Q=o.warning!==void 0?[o.warning.message]:void 0;return x({content:N,linesChanged:j(r,N),warnings:Q})}p($e,"modifyResource");function ce(r,e){const i=e.start+e.length;for(let t=0;t<r.length;t++){const a=r[t];if(a===void 0)continue;const{start:n,end:o}=a;if(!(typeof n!="number"||typeof o!="number")&&n<=e.start&&i<=o)return t}}p(ce,"findStatementIndexContaining");function K(r,e){const i={...e};for(const t of re(r))t in i||(i[t]=ie);return i}p(K,"buildGuardView");function L(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}`}}}p(L,"narrowGateError");function fe(r,e){const i=e.start+e.length;let t;const a=p(n=>{if(t!==void 0||n.type!=="CallExpression")return;const o=n.arguments;if(!Array.isArray(o)||o.length<2)return;const d=o[0];if(!I(d)||d.type!=="StringLiteral"||d.start!==e.start||d.end!==i)return;const u=o[1];I(u)&&u.type==="ObjectExpression"&&(t=u)},"visitor");for(const n of r)if(ne(n,a),t!==void 0)break;return t}p(fe,"findConfigObject");function le(r,e,i,t){const a=he(r),n=se(e);for(const o of i){const d=ee(o,t);if(!d.success)return s(d.error);const u=n[o.key]??[],c=T(r,o.key);if(c!==void 0){c.value=d.data,ye(r,u);continue}const l=me(r,u);if(l!==void 0){ge(r,l,o.key,d.data,t);continue}const m=B(o.key,d.data,t);a&&(m.extra={...m.extra??{},trailingComma:!0}),r.properties.push(m)}return x(void 0)}p(le,"applyPropertyEdits");function me(r,e){for(const i of e){const t=T(r,i);if(t!==void 0)return t}}p(me,"findAliasProperty");function ye(r,e){if(e.length!==0)for(let i=r.properties.length-1;i>=0;i--){const t=r.properties[i];if(t===void 0||t.type!=="Property"&&t.type!=="ObjectProperty"||t.shorthand===!0||t.computed===!0)continue;const a=te(t.key);a!==void 0&&e.includes(a)&&r.properties.splice(i,1)}}p(ye,"removePropertiesByKey");function ge(r,e,i,t,a){const n=r.properties.indexOf(e);if(n<0)return;const o=B(i,t,a);e.extra?.trailingComma===!0&&(o.extra={...o.extra??{},trailingComma:!0}),r.properties.splice(n,1,o)}p(ge,"replacePropertyInPlace");function he(r){return r.properties[r.properties.length-1]?.extra?.trailingComma===!0}p(he,"detectTrailingCommaStyle");function Ee(r,e,i){const t=Y(r,i);return t.success?t.data.filter(a=>a.type===e).map(a=>a.symbolName):[]}p(Ee,"collectKnownNames");export{$e as modifyResource};
@@ -9,6 +9,9 @@ export interface LocatorTarget {
9
9
  }
10
10
  export interface BindingPlan {
11
11
  variableName: string;
12
+ /** The resource name the plan binds — collision refusals name it so the
13
+ * operator sees which two resources derive the same variable. */
14
+ resourceName: string;
12
15
  /** Index of the matched statement in the module body — callers that emit a
13
16
  * reference to the binding need it to judge declaration order. */
14
17
  statementIndex: number;
@@ -1 +1 @@
1
- var w=Object.defineProperty;var d=(r,n)=>w(r,"name",{value:n,configurable:!0});import{builders as b}from"ast-types";import{toVariableName as A}from"../../generation/common.js";import{failure as o,success as E}from"../../types/Result.js";import{RESERVED_IDENTIFIER_NAMES as v}from"./addResource/propertyBuilder.js";import{isNodeShape as s}from"./modifyResource/literalConversion.js";import{unwrapTsWrappers as I}from"./moduleConstResolver.js";import{visit as k}from"./objectGraph.js";function j(r,n,a){const e=[];for(let p=0;p<r.length;p++){const l=r[p];if(l===void 0)continue;let y=!1;k(l,x=>{x.type==="CallExpression"&&D(x,n.factory,a)&&(y=!0)}),y&&e.push({statementIndex:p})}if(e.length===0)return o({kind:"statement-not-found"});if(e.length>1)return o({kind:"ambiguous",count:e.length});const t=e[0];if(t===void 0)return o({kind:"statement-not-found"});const i=r[t.statementIndex];if(i===void 0)return o({kind:"statement-not-found"});const c=i.type==="ExportNamedDeclaration"||i.type==="ExportDefaultDeclaration",f=h(i);if(f===void 0)return o({kind:"unbindable-statement",statementType:i.type});if(f.type==="VariableDeclaration"){const p=f.declarations;if(!Array.isArray(p)||p.length!==1)return o({kind:"multiple-declarators"});const l=p[0].id;if(!s(l)||l.type!=="Identifier")return o({kind:"pattern-binding"});const y=l.name;if(typeof y!="string")return o({kind:"unreadable-name"});const x=p[0].init;return!s(x)||!g(x,n,a)?o({kind:"init-not-app-method-wrap"}):E({variableName:y,statementIndex:t.statementIndex})}if(c)return o({kind:"unbindable-statement",statementType:i.type});if(f.type!=="ExpressionStatement")return o({kind:"unbindable-statement",statementType:f.type});const u=f.expression;if(!s(u)||u.type!=="CallExpression")return o({kind:"not-app-method-call"});if(D(u,n.factory,a))return o({kind:"bare-factory-call"});if(!g(u,n,a))return o({kind:"foreign-wrapper"});const m=A(a);return v.has(m)?o({kind:"reserved-word",variableName:m}):N(r,m)?o({kind:"name-conflict",variableName:m}):E({variableName:m,statementIndex:t.statementIndex,wrap:{statementIndex:t.statementIndex,expression:u}})}d(j,"planBinding");function L(r,n){if(n.wrap===void 0)return;const{statementIndex:a,expression:e}=n.wrap,t=r[a],i=b.variableDeclaration("const",[b.variableDeclarator(b.identifier(n.variableName),e)]),c=t?.comments;c!==void 0&&(i.comments=c),r[a]=i}d(L,"applyBinding");function D(r,n,a){const e=r.callee;if(!s(e)||e.type!=="MemberExpression"||e.computed===!0)return!1;const t=e.object,i=e.property;if(!s(t)||t.type!=="Identifier"||t.name!==n||!s(i)||i.type!=="Identifier"||i.name!=="build")return!1;const c=r.arguments;if(!Array.isArray(c))return!1;const f=c[0];return!s(f)||f.type!=="StringLiteral"&&f.type!=="Literal"?!1:f.value===a}d(D,"isFactoryBuildOf");function h(r){if(r.type!=="ExportNamedDeclaration"&&r.type!=="ExportDefaultDeclaration")return r;const n=r.declaration;return s(n)?n:void 0}d(h,"unwrapExportDeclaration");function M(r){const n=I(r);if(n.type!=="CallExpression")return;const a=n.callee;if(!s(a)||a.type!=="MemberExpression"||a.computed===!0)return;const e=a.property;if(!s(e)||e.type!=="Identifier")return;const t=e.name;return typeof t=="string"?t:void 0}d(M,"appMethodNameOf");function g(r,n,a){const e=I(r);if(M(e)!==n.appMethod)return!1;const t=e.arguments;if(!Array.isArray(t))return!1;const i=t[0];return s(i)?D(I(i),n.factory,a):!1}d(g,"isAppMethodWrap");function N(r,n){for(const a of r){const e=h(a);if(e!==void 0){if(e.type==="ImportDeclaration"){const t=e.specifiers;if(!Array.isArray(t))continue;for(const i of t){const c=i.local;if(s(c)&&c.name===n)return!0}continue}if(e.type==="VariableDeclaration"){const t=e.declarations;if(!Array.isArray(t))continue;for(const i of t){if(!s(i))continue;const c=i.id;if(!s(c))continue;let f=!1;if(k(c,u=>{u.type==="Identifier"&&u.name===n&&(f=!0)}),f)return!0}continue}if(e.type==="FunctionDeclaration"||e.type==="ClassDeclaration"){const t=e.id;if(s(t)&&t.name===n)return!0}}}return!1}d(N,"moduleScopeDeclares");export{M as appMethodNameOf,L as applyBinding,D as isFactoryBuildOf,N as moduleScopeDeclares,j as planBinding,h as unwrapExportDeclaration};
1
+ var w=Object.defineProperty;var d=(r,n)=>w(r,"name",{value:n,configurable:!0});import{builders as b}from"ast-types";import{toVariableName as A}from"../../generation/common.js";import{failure as o,success as E}from"../../types/Result.js";import{RESERVED_IDENTIFIER_NAMES as v}from"./addResource/propertyBuilder.js";import{isNodeShape as s}from"./modifyResource/literalConversion.js";import{unwrapTsWrappers as I}from"./moduleConstResolver.js";import{visit as k}from"./objectGraph.js";function j(r,n,i){const e=[];for(let c=0;c<r.length;c++){const l=r[c];if(l===void 0)continue;let y=!1;k(l,x=>{x.type==="CallExpression"&&D(x,n.factory,i)&&(y=!0)}),y&&e.push({statementIndex:c})}if(e.length===0)return o({kind:"statement-not-found"});if(e.length>1)return o({kind:"ambiguous",count:e.length});const t=e[0];if(t===void 0)return o({kind:"statement-not-found"});const a=r[t.statementIndex];if(a===void 0)return o({kind:"statement-not-found"});const p=a.type==="ExportNamedDeclaration"||a.type==="ExportDefaultDeclaration",f=h(a);if(f===void 0)return o({kind:"unbindable-statement",statementType:a.type});if(f.type==="VariableDeclaration"){const c=f.declarations;if(!Array.isArray(c)||c.length!==1)return o({kind:"multiple-declarators"});const l=c[0].id;if(!s(l)||l.type!=="Identifier")return o({kind:"pattern-binding"});const y=l.name;if(typeof y!="string")return o({kind:"unreadable-name"});const x=c[0].init;return!s(x)||!g(x,n,i)?o({kind:"init-not-app-method-wrap"}):E({variableName:y,resourceName:i,statementIndex:t.statementIndex})}if(p)return o({kind:"unbindable-statement",statementType:a.type});if(f.type!=="ExpressionStatement")return o({kind:"unbindable-statement",statementType:f.type});const u=f.expression;if(!s(u)||u.type!=="CallExpression")return o({kind:"not-app-method-call"});if(D(u,n.factory,i))return o({kind:"bare-factory-call"});if(!g(u,n,i))return o({kind:"foreign-wrapper"});const m=A(i);return v.has(m)?o({kind:"reserved-word",variableName:m}):S(r,m)?o({kind:"name-conflict",variableName:m}):E({variableName:m,resourceName:i,statementIndex:t.statementIndex,wrap:{statementIndex:t.statementIndex,expression:u}})}d(j,"planBinding");function L(r,n){if(n.wrap===void 0)return;const{statementIndex:i,expression:e}=n.wrap,t=r[i],a=b.variableDeclaration("const",[b.variableDeclarator(b.identifier(n.variableName),e)]),p=t?.comments;p!==void 0&&(a.comments=p),r[i]=a}d(L,"applyBinding");function D(r,n,i){const e=r.callee;if(!s(e)||e.type!=="MemberExpression"||e.computed===!0)return!1;const t=e.object,a=e.property;if(!s(t)||t.type!=="Identifier"||t.name!==n||!s(a)||a.type!=="Identifier"||a.name!=="build")return!1;const p=r.arguments;if(!Array.isArray(p))return!1;const f=p[0];return!s(f)||f.type!=="StringLiteral"&&f.type!=="Literal"?!1:f.value===i}d(D,"isFactoryBuildOf");function h(r){if(r.type!=="ExportNamedDeclaration"&&r.type!=="ExportDefaultDeclaration")return r;const n=r.declaration;return s(n)?n:void 0}d(h,"unwrapExportDeclaration");function M(r){const n=I(r);if(n.type!=="CallExpression")return;const i=n.callee;if(!s(i)||i.type!=="MemberExpression"||i.computed===!0)return;const e=i.property;if(!s(e)||e.type!=="Identifier")return;const t=e.name;return typeof t=="string"?t:void 0}d(M,"appMethodNameOf");function g(r,n,i){const e=I(r);if(M(e)!==n.appMethod)return!1;const t=e.arguments;if(!Array.isArray(t))return!1;const a=t[0];return s(a)?D(I(a),n.factory,i):!1}d(g,"isAppMethodWrap");function S(r,n){for(const i of r){const e=h(i);if(e!==void 0){if(e.type==="ImportDeclaration"){const t=e.specifiers;if(!Array.isArray(t))continue;for(const a of t){const p=a.local;if(s(p)&&p.name===n)return!0}continue}if(e.type==="VariableDeclaration"){const t=e.declarations;if(!Array.isArray(t))continue;for(const a of t){if(!s(a))continue;const p=a.id;if(!s(p))continue;let f=!1;if(k(p,u=>{u.type==="Identifier"&&u.name===n&&(f=!0)}),f)return!0}continue}if(e.type==="FunctionDeclaration"||e.type==="ClassDeclaration"){const t=e.id;if(s(t)&&t.name===n)return!0}}}return!1}d(S,"moduleScopeDeclares");export{M as appMethodNameOf,L as applyBinding,D as isFactoryBuildOf,S as moduleScopeDeclares,j as planBinding,h as unwrapExportDeclaration};
@@ -1,10 +1,48 @@
1
1
  import type { StatementType } from "../types.js";
2
2
  import type { NodeShapeLike } from "./modifyResource/literalConversion.js";
3
3
  import { type BindingPlan } from "./resourceStatementLocator.js";
4
+ /**
5
+ * Which sibling types may satisfy a live binding for one edited type.
6
+ * `default` applies to every plan key without its own entry; `perKey` narrows
7
+ * a specific plan key to the types it may bind — compute's connection keys
8
+ * each name exactly one resource type, so `connectedDatabase: "Uploads"`
9
+ * must never resolve against a storage statement even though a same-named
10
+ * one exists.
11
+ */
12
+ export interface BindingCandidates {
13
+ default?: ReadonlyArray<StatementType>;
14
+ perKey?: Readonly<Partial<Record<string, ReadonlyArray<StatementType>>>>;
15
+ }
16
+ /**
17
+ * One module-scope `const` a pending wrap plan will declare when applied.
18
+ * `planBinding` checks each wrap name against the PRE-mutation body only, so
19
+ * the caller must judge the pending declarations against EACH OTHER and
20
+ * against any primary binding it derives later — two resources whose names
21
+ * collapse to the same variable (`"Uploads"` and `"uploads"` both derive
22
+ * `uploads`) would otherwise emit two `const` declarations and write a file
23
+ * that does not parse.
24
+ */
25
+ export interface PendingDeclaration {
26
+ variableName: string;
27
+ resourceName: string;
28
+ statementIndex: number;
29
+ /** The plan key whose resolution recorded the wrap, when the caller
30
+ * supplied one — collision refusals attribute themselves to it. */
31
+ planKey?: string;
32
+ }
4
33
  export interface SiblingBindingResolution {
5
- resolveBinding: (planResourceName: string) => string | undefined;
34
+ resolveBinding: (planResourceName: string, planKey?: string) => string | undefined;
35
+ /**
36
+ * All-or-nothing array form: every name resolves or the whole call answers
37
+ * `undefined` — and any wrap plans recorded by the partial resolution are
38
+ * rolled back, so a refused array never leaves a half-bound file.
39
+ */
40
+ resolveBindings: (planResourceNames: ReadonlyArray<string>, planKey?: string) => ReadonlyArray<string> | undefined;
6
41
  /** Wrap plans recorded by successful resolutions since the last drain. */
7
42
  takePendingWraps: () => BindingPlan[];
43
+ /** The `const` names those pending wraps will declare — consulted before
44
+ * any mutation so no two planned declarations share a name. */
45
+ pendingDeclarations: () => ReadonlyArray<PendingDeclaration>;
8
46
  }
9
47
  export interface SiblingBindingConstraints {
10
48
  /**
@@ -20,3 +58,18 @@ export interface SiblingBindingConstraints {
20
58
  mustPrecedeStatementIndex?: number;
21
59
  }
22
60
  export declare function createSiblingBindingResolution(type: StatementType, getBody: () => NodeShapeLike[] | undefined, constraints?: SiblingBindingConstraints): SiblingBindingResolution;
61
+ /**
62
+ * The first pair of pending declarations that would declare the same
63
+ * module-scope `const` for two DIFFERENT statements. Each wrap passed
64
+ * `planBinding`'s body-conflict check individually, but none of the planned
65
+ * names is in the body yet, so two resources collapsing to one variable
66
+ * (`"Uploads"` and `"uploads"`) sail through separately and collide only in
67
+ * the written file — `Identifier 'uploads' has already been declared`, from
68
+ * an edit that reported success. The caller refuses pre-mutation instead.
69
+ * Same-statement duplicates are NOT a collision: re-resolving one resource
70
+ * plans the identical wrap twice, and applying it twice is idempotent.
71
+ */
72
+ export declare function findPendingWrapCollision(declarations: ReadonlyArray<PendingDeclaration>): {
73
+ first: PendingDeclaration;
74
+ second: PendingDeclaration;
75
+ } | undefined;
@@ -1 +1 @@
1
- var l=Object.defineProperty;var e=(t,i)=>l(t,"name",{value:i,configurable:!0});import{FACTORY_IDENTIFIERS as g,STATEMENT_REGISTRY as I}from"../registry.js";import{planBinding as T}from"./resourceStatementLocator.js";const E={cdn:["storage","compute"]};function A(t,i,p={}){const m=E[t]??[];let d=[];return{resolveBinding:e(r=>{const u=i();if(u===void 0)return;const o=[];for(const c of m){const f=I[c].emitWrapper?.appMethod;if(f===void 0)continue;const s=T(u,{factory:g[c],appMethod:f},r);if(s.success){o.push(s.data);continue}if(s.error.kind!=="statement-not-found")return}if(o.length!==1)return;const n=o[0];if(n===void 0)return;const a=p.mustPrecedeStatementIndex;if(!(a!==void 0&&n.statementIndex>=a))return n.wrap!==void 0&&d.push(n),n.variableName},"resolveBinding"),takePendingWraps:e(()=>{const r=d;return d=[],r},"takePendingWraps")}}e(A,"createSiblingBindingResolution");export{A as createSiblingBindingResolution};
1
+ var I=Object.defineProperty;var d=(a,o)=>I(a,"name",{value:o,configurable:!0});import{FACTORY_IDENTIFIERS as b,STATEMENT_REGISTRY as h}from"../registry.js";import{planBinding as v}from"./resourceStatementLocator.js";const x={cdn:{default:["storage","compute"]},compute:{perKey:{connectedDatabase:["database"],connectedStorage:["storage"],connectedMessaging:["messaging"]}}};function M(a,o,i={}){const r=x[a];let s=[];const p=d((n,e)=>{const u=o();if(u===void 0)return;const f=(e!==void 0?r?.perKey?.[e]:void 0)??r?.default??[],c=[];for(const l of f){const N=h[l].emitWrapper?.appMethod;if(N===void 0)continue;const m=v(u,{factory:b[l],appMethod:N},n);if(m.success){c.push(m.data);continue}if(m.error.kind!=="statement-not-found")return}if(c.length!==1)return;const t=c[0];if(t===void 0)return;const g=i.mustPrecedeStatementIndex;if(!(g!==void 0&&t.statementIndex>=g))return t.wrap!==void 0&&s.push({plan:t,...e!==void 0&&{planKey:e}}),t.variableName},"resolveBinding");return{resolveBinding:p,resolveBindings:d((n,e)=>{const u=s.length,f=[];for(const c of n){const t=p(c,e);if(t===void 0){s.length=u;return}f.push(t)}return f},"resolveBindings"),takePendingWraps:d(()=>{const n=s;return s=[],n.map(e=>e.plan)},"takePendingWraps"),pendingDeclarations:d(()=>s.map(({plan:n,planKey:e})=>({variableName:n.variableName,resourceName:n.resourceName,statementIndex:n.statementIndex,...e!==void 0&&{planKey:e}})),"pendingDeclarations")}}d(M,"createSiblingBindingResolution");function P(a){const o=new Map;for(const i of a){const r=o.get(i.variableName);if(r===void 0){o.set(i.variableName,i);continue}if(r.statementIndex!==i.statementIndex)return{first:r,second:i}}}d(P,"findPendingWrapCollision");export{M as createSiblingBindingResolution,P as findPendingWrapCollision};
@@ -1,17 +1,6 @@
1
+ import { UNRESOLVED } from "../projection/unresolved.js";
1
2
  import type { InvalidPropertyError } from "./types.js";
2
- /**
3
- * A value the codemod could not have written: the property is present in
4
- * the target statement but holds a non-literal expression (`Code.fromAsset(
5
- * "./src")`, `Runtime.NODEJS_20_X`, `assetsBucket`).
6
- *
7
- * Its presence is PROOF the statement was authored by a human or by the
8
- * generator scaffold, both of which speak construct vocabulary. Rules that
9
- * refuse a key because the construct needs a live object must therefore
10
- * treat `UNRESOLVED` as satisfying the construct — otherwise `fjall modify`
11
- * would refuse to touch perfectly good scaffold output. The ADD path never
12
- * produces it: every value there comes from a flag.
13
- */
14
- export declare const UNRESOLVED: unique symbol;
3
+ export { UNRESOLVED };
15
4
  /**
16
5
  * The property record the emitted statement WOULD carry. `add` passes the
17
6
  * requested properties; `modify` passes the merge of the existing statement
@@ -43,23 +32,6 @@ export interface EmitGuardRule {
43
32
  * always correct.
44
33
  */
45
34
  export declare const AUTHOR_BY_HAND: string;
46
- /** True when the key holds a value the codemod itself could have written. */
47
- export declare function isWrittenValue(value: unknown): boolean;
48
- /**
49
- * A rule for a plan key NO construct reads, in any shape — proven by zero
50
- * `props.<key>` reads across @fjall/components-infrastructure. Presence
51
- * alone is the refusal; the value cannot rescue it.
52
- *
53
- * Phrased as a statement of consequence, because the operator's mental model
54
- * is "I set it, so it took effect" and the whole point is that it did not.
55
- */
56
- export declare function silentlyDropped(property: string, detail: string): EmitGuardRule;
57
- /**
58
- * A rule for a key the construct DOES read but only as a live object — a
59
- * CDK enum member, an asset, another construct. A flag value is a string,
60
- * so any value the codemod can write is wrong; only `UNRESOLVED` passes.
61
- */
62
- export declare function requiresLiveValue(property: string, detail: string): EmitGuardRule;
63
35
  /** Refuse whenever the key is missing (the missing-discriminator shape). */
64
36
  export declare function whenAbsent(property: string): (properties: EmitGuardProperties) => boolean;
65
37
  /**
@@ -1 +1 @@
1
- var u=Object.defineProperty;var r=(e,n)=>u(e,"name",{value:n,configurable:!0});const i=Symbol("unresolved-expression"),o="Write this resource in infrastructure.ts by hand \u2014 the construct props it needs cannot be expressed as `fjall add` flags.";function d(e){return e!==void 0&&e!==i}r(d,"isWrittenValue");function f(e,n){return{property:e,refuseWhen:r(t=>t[e]!==void 0,"refuseWhen"),reason:`${n} \`fjall add\` would write it into the factory call and the resource would deploy without it. ${o}`}}r(f,"silentlyDropped");function a(e,n){return{property:e,refuseWhen:r(t=>d(t[e]),"refuseWhen"),reason:`${n} ${o}`}}r(a,"requiresLiveValue");function l(e){return n=>n[e]===void 0}r(l,"whenAbsent");function c(e,n){if(e!==void 0){for(const t of e)if(t.refuseWhen(n))return{kind:"InvalidPropertyError",property:t.property,reason:t.reason}}}r(c,"evaluateEmitGuard");export{o as AUTHOR_BY_HAND,i as UNRESOLVED,c as evaluateEmitGuard,d as isWrittenValue,a as requiresLiveValue,f as silentlyDropped,l as whenAbsent};
1
+ var o=Object.defineProperty;var t=(e,r)=>o(e,"name",{value:r,configurable:!0});import{UNRESOLVED as i}from"../projection/unresolved.js";const s="Write this resource in infrastructure.ts by hand \u2014 the construct props it needs cannot be expressed as `fjall add` flags.";function f(e){return r=>r[e]===void 0}t(f,"whenAbsent");function a(e,r){if(e!==void 0){for(const n of e)if(n.refuseWhen(r))return{kind:"InvalidPropertyError",property:n.property,reason:n.reason}}}t(a,"evaluateEmitGuard");export{s as AUTHOR_BY_HAND,i as UNRESOLVED,a as evaluateEmitGuard,f as whenAbsent};
@@ -1,10 +1,13 @@
1
- import { type ProjectionContext } from "../projection/index.js";
1
+ import { type ProjectionContext, type StructuredValue } from "../projection/index.js";
2
2
  import { type EmitGuardProperties } from "./emitGuard.js";
3
3
  import type { InvalidPropertyError, StatementType } from "./types.js";
4
4
  /**
5
5
  * One emitted construct prop. `literal` is a serialisable value; `expression`
6
6
  * carries the source text of a live binding a projection rule resolved — the
7
- * emitters splice it as an identifier rather than serialising it.
7
+ * emitters splice it as an identifier rather than serialising it;
8
+ * `structured` carries a validated expression tree plus the components-barrel
9
+ * specifiers it needs (`collectImportSpecifiers` gathers those for the
10
+ * emitters to apply once).
8
11
  */
9
12
  export type EmittedProp = {
10
13
  key: string;
@@ -14,7 +17,32 @@ export type EmittedProp = {
14
17
  key: string;
15
18
  kind: "expression";
16
19
  source: string;
20
+ } | {
21
+ key: string;
22
+ kind: "structured";
23
+ expression: StructuredValue;
24
+ imports?: readonly string[];
17
25
  };
26
+ /**
27
+ * One sibling statement in emission vocabulary — the projection's
28
+ * {@link SiblingStatement} with its props mapped to {@link EmittedProp}s. The
29
+ * add path emits each as `app.<appMethod>("<constructId>", { …props })`
30
+ * directly after the primary statement; modify refuses the whole edit when
31
+ * any arrive, because it edits exactly one statement.
32
+ */
33
+ export interface EmittedSibling {
34
+ planKey: string;
35
+ constructId: string;
36
+ appMethod: string;
37
+ props: EmittedProp[];
38
+ }
39
+ /**
40
+ * Every components-barrel specifier the emitted props need, deduplicated in
41
+ * first-appearance order. The emitters apply these once per write — a
42
+ * specifier requested by several props (or by a prop and a sibling) lands as
43
+ * one named import.
44
+ */
45
+ export declare function collectImportSpecifiers(props: ReadonlyArray<EmittedProp>): string[];
18
46
  /**
19
47
  * EVERY plan key in `properties` this type cannot turn into a construct
20
48
  * prop, one refusal per key, as the codebase's actionable error shape.
@@ -45,6 +73,7 @@ export declare function projectionRefusals(type: StatementType, properties: Emit
45
73
  */
46
74
  export declare function projectEmittedProperties(type: StatementType, properties: Readonly<Record<string, unknown>>, context?: ProjectionContext): {
47
75
  props: EmittedProp[];
76
+ siblings?: EmittedSibling[];
48
77
  } | {
49
78
  refusal: InvalidPropertyError;
50
79
  };
@@ -1 +1 @@
1
- var p=Object.defineProperty;var a=(e,n)=>p(e,"name",{value:n,configurable:!0});import{isProjectableType as s,projectPlanToConstructProps as u}from"../projection/index.js";import{AUTHOR_BY_HAND as f}from"./emitGuard.js";const m={"plan-only":`\`fjall add\` would write it into the factory call and the resource would deploy without it. ${f}`,"unresolved-binding":"Nothing has been written: the engine refuses rather than guessing a construct. Add or bind a sibling resource with that name (or fix the name) and run the same command again \u2014 it succeeds once a unique binding exists.","missing-context":"Nothing has been written: the command context supplied no resource name to derive it from."};function l(e,n,r="plan-only"){return{kind:"InvalidPropertyError",property:e,reason:`${n} ${m[r]}`}}a(l,"unprojectableRefusal");function g(e,n,r={}){return s(e)?u(e,n,r).unprojectable.map(o=>l(o.key,o.reason,o.kind)):[]}a(g,"projectionRefusals");function j(e,n,r={}){if(!s(e))return{props:Object.entries(n).map(([t,d])=>({key:t,kind:"literal",value:d}))};const{props:o,unprojectable:c}=u(e,n,r),[i]=c;return i!==void 0?{refusal:l(i.key,i.reason,i.kind)}:{props:o.map(t=>t.value.kind==="expression"?{key:t.key,kind:"expression",source:t.value.source}:{key:t.key,kind:"literal",value:t.value.value})}}a(j,"projectEmittedProperties");export{j as projectEmittedProperties,g as projectionRefusals};
1
+ var m=Object.defineProperty;var r=(e,t)=>m(e,"name",{value:t,configurable:!0});import{crossKeyUnprojectables as h,isProjectableType as u,projectPlanToConstructProps as c}from"../projection/index.js";import{AUTHOR_BY_HAND as k}from"./emitGuard.js";function x(e){const t=new Set;for(const n of e)if(!(n.kind!=="structured"||n.imports===void 0))for(const i of n.imports)t.add(i);return[...t]}r(x,"collectImportSpecifiers");const y={"plan-only":`\`fjall add\` would write it into the factory call and the resource would deploy without it. ${k}`,"unresolved-binding":"Nothing has been written: the engine refuses rather than guessing a construct. Add or bind a sibling resource with that name (or fix the name) and run the same command again \u2014 it succeeds once a unique binding exists.","missing-context":"Nothing has been written: the command context supplied no resource name to derive it from.","cross-key":"Nothing has been written: the refusal follows from the statement's properties taken together, not from this key alone. Change the named property (or the counterpart it conflicts with) and run the same command again."};function d(e,t,n="plan-only"){return{kind:"InvalidPropertyError",property:e,reason:`${t} ${y[n]}`}}r(d,"unprojectableRefusal");function j(e,t,n={}){return u(e)?[...n.editingExisting===!0?h(e,t):[],...c(e,t,n).unprojectable].map(o=>d(o.key,o.reason,o.kind)):[]}r(j,"projectionRefusals");function E(e,t,n={}){if(!u(e))return{props:Object.entries(t).map(([p,f])=>({key:p,kind:"literal",value:f}))};const{props:i,unprojectable:o,siblings:a}=c(e,t,n),[s]=o;return s!==void 0?{refusal:d(s.key,s.reason,s.kind)}:{props:i.map(l),...a!==void 0&&{siblings:a.map(g)}}}r(E,"projectEmittedProperties");function g(e){return{planKey:e.planKey,constructId:e.constructId,appMethod:e.appMethod,props:e.props.map(l)}}r(g,"toEmittedSibling");function l(e){switch(e.value.kind){case"expression":return{key:e.key,kind:"expression",source:e.value.source};case"structured":return{key:e.key,kind:"structured",expression:e.value.expression,...e.value.imports!==void 0&&{imports:e.value.imports}};case"literal":return{key:e.key,kind:"literal",value:e.value.value}}}r(l,"toEmittedProp");export{x as collectImportSpecifiers,E as projectEmittedProperties,j as projectionRefusals};
@@ -41,6 +41,24 @@ export declare function buildFactoryStatement(params: BuildFactoryStatementParam
41
41
  * only materialised by an App method.
42
42
  */
43
43
  export declare function buildAppMethodWrappedStatement(params: BuildAppMethodWrappedStatementParams): n.ExpressionStatement;
44
+ export interface BuildAppMethodStatementParams {
45
+ /** App binding identifier, e.g. `"app"` — resolved, never assumed. */
46
+ appIdentifier: string;
47
+ /** App method called directly, e.g. `"addConnection"`. */
48
+ appMethod: string;
49
+ /** Construct id, used as the first argument literal. */
50
+ name: string;
51
+ /** Configuration object properties. */
52
+ properties: ObjectPropertyInput[];
53
+ /** Quote style for NEW string literals the builder synthesises. */
54
+ quoteStyle: QuoteStyle;
55
+ }
56
+ /**
57
+ * Build an `ExpressionStatement` wrapping `app.<method>("Name", { … })` — a
58
+ * direct app-method call with NO factory layer, the shape sibling statements
59
+ * take (a connection is materialised by the App method itself).
60
+ */
61
+ export declare function buildAppMethodStatement(params: BuildAppMethodStatementParams): n.ExpressionStatement;
44
62
  /**
45
63
  * Build an object `Property` with a bare-identifier key. If `key` is
46
64
  * not a valid JS identifier (e.g. contains a hyphen), the key is
@@ -1 +1 @@
1
- var f=Object.defineProperty;var n=(e,t)=>f(e,"name",{value:t,configurable:!0});import{builders as i}from"ast-types";function y(e){return i.expressionStatement(s(e))}n(y,"buildFactoryStatement");function g(e){const t=i.callExpression(l(e.appIdentifier,e.appMethod),[s(e)]);return i.expressionStatement(t)}n(g,"buildAppMethodWrappedStatement");function s(e){const t=i.memberExpression(i.identifier(e.factory),i.identifier("build"),!1),r=p(e.name,e.quoteStyle),o=i.objectExpression(e.properties.map(c=>a(c.key,c.value,e.quoteStyle)));return i.callExpression(t,[r,o])}n(s,"buildFactoryCall");function a(e,t,r){const o=b(e)?i.identifier(e):p(e,r);return i.property("init",o,t)}n(a,"buildObjectProperty");function E(e,t,r="double"){const o=e.map(u=>i.importSpecifier(i.identifier(u))),c=p(t,r);return i.importDeclaration(o,c)}n(E,"buildImportDeclaration");function l(e,t){return i.memberExpression(i.identifier(e),i.identifier(t),!1)}n(l,"buildMemberExpression");function I(e,t){Array.isArray(e.specifiers)||(e.specifiers=[]);for(const r of e.specifiers)if(m(r)&&r.imported.name===t)return;e.specifiers.push(i.importSpecifier(i.identifier(t)))}n(I,"appendSpecifier");function p(e,t){const r=t==="single"?"'":'"',o=`${r}${d(e,t)}${r}`;return i.stringLiteral.from({value:e,extra:{rawValue:e,raw:o}})}n(p,"makeStringLiteral");function d(e,t){const r=e.replace(/\\/g,"\\\\");return t==="single"?r.replace(/'/g,"\\'"):r.replace(/"/g,'\\"')}n(d,"escapeForQuote");function b(e){return/^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u.test(e)}n(b,"isValidIdentifier");function m(e){return e!==null&&typeof e=="object"&&"type"in e&&e.type==="ImportSpecifier"}n(m,"isNamedImportSpecifier");export{I as appendSpecifier,g as buildAppMethodWrappedStatement,y as buildFactoryStatement,E as buildImportDeclaration,l as buildMemberExpression,a as buildObjectProperty};
1
+ var a=Object.defineProperty;var n=(e,i)=>a(e,"name",{value:i,configurable:!0});import{builders as t}from"ast-types";function y(e){return t.expressionStatement(s(e))}n(y,"buildFactoryStatement");function E(e){const i=t.callExpression(f(e.appIdentifier,e.appMethod),[s(e)]);return t.expressionStatement(i)}n(E,"buildAppMethodWrappedStatement");function g(e){const i=t.callExpression(f(e.appIdentifier,e.appMethod),[p(e.name,e.quoteStyle),t.objectExpression(e.properties.map(r=>u(r.key,r.value,e.quoteStyle)))]);return t.expressionStatement(i)}n(g,"buildAppMethodStatement");function s(e){const i=t.memberExpression(t.identifier(e.factory),t.identifier("build"),!1),r=p(e.name,e.quoteStyle),o=t.objectExpression(e.properties.map(c=>u(c.key,c.value,e.quoteStyle)));return t.callExpression(i,[r,o])}n(s,"buildFactoryCall");function u(e,i,r){const o=b(e)?t.identifier(e):p(e,r);return t.property("init",o,i)}n(u,"buildObjectProperty");function I(e,i,r="double"){const o=e.map(l=>t.importSpecifier(t.identifier(l))),c=p(i,r);return t.importDeclaration(o,c)}n(I,"buildImportDeclaration");function f(e,i){return t.memberExpression(t.identifier(e),t.identifier(i),!1)}n(f,"buildMemberExpression");function h(e,i){Array.isArray(e.specifiers)||(e.specifiers=[]);for(const r of e.specifiers)if(x(r)&&r.imported.name===i)return;e.specifiers.push(t.importSpecifier(t.identifier(i)))}n(h,"appendSpecifier");function p(e,i){const r=i==="single"?"'":'"',o=`${r}${d(e,i)}${r}`;return t.stringLiteral.from({value:e,extra:{rawValue:e,raw:o}})}n(p,"makeStringLiteral");function d(e,i){const r=e.replace(/\\/g,"\\\\");return i==="single"?r.replace(/'/g,"\\'"):r.replace(/"/g,'\\"')}n(d,"escapeForQuote");function b(e){return/^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u.test(e)}n(b,"isValidIdentifier");function x(e){return e!==null&&typeof e=="object"&&"type"in e&&e.type==="ImportSpecifier"}n(x,"isNamedImportSpecifier");export{h as appendSpecifier,g as buildAppMethodStatement,E as buildAppMethodWrappedStatement,y as buildFactoryStatement,I as buildImportDeclaration,f as buildMemberExpression,u as buildObjectProperty};
@@ -1,4 +1,4 @@
1
1
  export { parse, type ParsedFile, type ParseError } from "./parse.js";
2
2
  export { detectLineTerminator, detectQuoteStyle, printFile } from "./print.js";
3
- export { appendSpecifier, buildAppMethodWrappedStatement, buildFactoryStatement, buildImportDeclaration, buildMemberExpression, buildObjectProperty, type BuildAppMethodWrappedStatementParams, type BuildFactoryStatementParams, type ObjectPropertyInput, type QuoteStyle, } from "./builders.js";
3
+ export { appendSpecifier, buildAppMethodStatement, buildAppMethodWrappedStatement, buildFactoryStatement, buildImportDeclaration, buildMemberExpression, buildObjectProperty, type BuildAppMethodStatementParams, type BuildAppMethodWrappedStatementParams, type BuildFactoryStatementParams, type ObjectPropertyInput, type QuoteStyle, } from "./builders.js";
4
4
  export { locateByLineColumn, locateByRange, type LineColumnHint, type NodeLocation, } from "./locateByRange.js";
@@ -1 +1 @@
1
- import{parse as r}from"./parse.js";import{detectLineTerminator as p,detectQuoteStyle as i,printFile as a}from"./print.js";import{appendSpecifier as n,buildAppMethodWrappedStatement as d,buildFactoryStatement as m,buildImportDeclaration as c,buildMemberExpression as b,buildObjectProperty as u}from"./builders.js";import{locateByLineColumn as x,locateByRange as y}from"./locateByRange.js";export{n as appendSpecifier,d as buildAppMethodWrappedStatement,m as buildFactoryStatement,c as buildImportDeclaration,b as buildMemberExpression,u as buildObjectProperty,p as detectLineTerminator,i as detectQuoteStyle,x as locateByLineColumn,y as locateByRange,r as parse,a as printFile};
1
+ import{parse as r}from"./parse.js";import{detectLineTerminator as p,detectQuoteStyle as i,printFile as a}from"./print.js";import{appendSpecifier as l,buildAppMethodStatement as n,buildAppMethodWrappedStatement as m,buildFactoryStatement as b,buildImportDeclaration as c,buildMemberExpression as u,buildObjectProperty as f}from"./builders.js";import{locateByLineColumn as y,locateByRange as S}from"./locateByRange.js";export{l as appendSpecifier,n as buildAppMethodStatement,m as buildAppMethodWrappedStatement,b as buildFactoryStatement,c as buildImportDeclaration,u as buildMemberExpression,f as buildObjectProperty,p as detectLineTerminator,i as detectQuoteStyle,y as locateByLineColumn,S as locateByRange,r as parse,a as printFile};
@@ -13,13 +13,14 @@ export { resolveConstructByLiteralProperty, type ConstructResolution, type Const
13
13
  export { parse } from "./fileRewriter/parse.js";
14
14
  export { CrossPlanConnectionResourcePlanSchema, VpcPeerAccepterResourcePlanSchema, VpcPeerResourcePlanSchema, } from "../schemas/index.js";
15
15
  export type { CrossPlanConnectionResourcePlan, VpcPeerAccepterResourcePlan, VpcPeerResourcePlan, } from "../schemas/index.js";
16
- export { detectDrift, mergeProperties, snapshotProperties, type DriftOp, type DriftPlan, type DriftPolicy, type DriftState, type MergeResult, type PropertyDelta, type ResourceSnapshot, } from "./drift/index.js";
16
+ export { detectDrift, mergeProperties, RESOURCE_SNAPSHOT_SCHEMA_VERSION, ResourceSnapshotSchema, snapshotProperties, type DriftOp, type DriftPlan, type DriftPolicy, type DriftState, type MergeResult, type PropertyDelta, type ResourceSnapshot, } from "./drift/index.js";
17
17
  export { computeLinesDelta } from "./_internal.js";
18
18
  export { ResourceNameSchema, StatementTypeSchema } from "./types.js";
19
19
  export { REGISTERED_STATEMENT_TYPES, STATEMENT_REGISTRY, type StatementTypeEntry, } from "./registry.js";
20
20
  export { evaluateEmitGuard, UNRESOLVED, type EmitGuardProperties, type EmitGuardRule, } from "./emitGuard.js";
21
+ export { projectionRefusals } from "./emitProjection.js";
21
22
  export { CODEMOD_ERROR_KINDS } from "./telemetry/errorKinds.js";
22
23
  export type { CodemodErrorKind } from "./telemetry/errorKinds.js";
23
24
  export type { GateId } from "./validationGate/index.js";
24
- export { buildEgressBlockedEvent, buildFiredEvent, buildGateFailedEvent, buildGatePassedEvent, buildRejectedEvent, buildSucceededEvent, buildTimeoutEvent, estimateCostUsd, FALLBACK_EVENTS, GATE_EVENTS, gateFallbackOutput, PARSE_GATE, RUNTIME_GATE, runFallback, shouldTryFallback, UNATTRIBUTED_ORGANISATION, type AnthropicClientProvider, type AnthropicContentBlock, type AnthropicResponse, type EgressStage, type FallbackClients, type FallbackDecision, type FallbackEgressBlockedEvent, type FallbackGuardConfig, type FallbackInput, type FallbackIntent, type FallbackOp, type FallbackOutput, type FallbackTelemetry, type FallbackTelemetryEvent, type GateEventAction, type GateFallbackParams, type MorphClientProvider, type RunFallbackInput, type TelemetrySource, type TriggerReason, } from "./llmFallback/index.js";
25
+ export { buildEgressBlockedEvent, buildFiredEvent, buildGateFailedEvent, buildGatePassedEvent, buildRejectedEvent, buildSucceededEvent, buildTimeoutEvent, estimateCostUsd, FALLBACK_EVENTS, GATE_EVENTS, gateFallbackOutput, matchFallbackTrigger, PARSE_GATE, RUNTIME_GATE, runFallback, shouldTryFallback, UNATTRIBUTED_ORGANISATION, type AnthropicClientProvider, type AnthropicContentBlock, type AnthropicResponse, type EgressStage, type FallbackClients, type FallbackDecision, type FallbackEgressBlockedEvent, type FallbackGuardConfig, type FallbackInput, type FallbackIntent, type FallbackOp, type FallbackOutput, type FallbackTelemetry, type FallbackTelemetryEvent, type GateEventAction, type GateFallbackParams, type MorphClientProvider, type RunFallbackInput, type TelemetrySource, type TriggerReason, } from "./llmFallback/index.js";
25
26
  export type { AddOptions, CodemodError, CodemodSuccess, ControlFlowClassifierError, DriftConflictError, DriftUnmergeableError, DuplicateResourceError, EditOrchestratorSuccess, InvalidPropertyError, LinesChanged, LlmFallbackRejectedError, LlmFallbackTimeoutError, LlmFallbackTier, LlmFallbackUnsafeInputError, MissingAppInitError, ModifyOptions, NodeLocation, ParseError, PermissionError, ReferenceLocation, ReferencesRemainError, RemoveOptions, ResourceListing, ResourceListingEntry, ResourceName, ResourceNotFoundError, SemanticQueryError, StatementType, TemplateLiteralNameError, } from "./types.js";