@fjall/generator 0.89.6 → 0.94.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.
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 93 files minified at 2026-04-20T23:47:43.752Z
1
+ 93 files minified at 2026-04-21T02:11:58.926Z
@@ -18,7 +18,7 @@ export interface IndexedBody {
18
18
  appInitLocations: ResourceLocation[];
19
19
  programEnd: number;
20
20
  }
21
- export declare function indexBody(body: StatementNodeLike[], source: string, factoryIdentifierByType: Record<StatementType, string>): IndexedBody;
21
+ export declare function indexBody(body: StatementNodeLike[], source: string): IndexedBody;
22
22
  export declare function buildResourceLocations(anchors: BodyAnchor[], shapes: Array<{
23
23
  start: number;
24
24
  length: number;
@@ -1 +1 @@
1
- import{isRecord as u}from"../../_internal.js";function x(n,r,t){const e=[],o=[],i=[];let s=r.length;for(let c=0;c<n.length;c+=1){const f=n[c];if(f===void 0)continue;const a=typeof f.start=="number"?f.start:0,p=typeof f.end=="number"?f.end:a;p>s&&(s=p);const d=y(f,t);e.push({index:c,start:a,end:p,type:d}),d==="import"?o.push({endPos:p}):(d==="app-init"||d==="tags")&&i.push({endPos:p,type:d})}return{anchors:e,importInfos:o,appInitLocations:i,programEnd:s}}function y(n,r){if(n.type==="ImportDeclaration")return"import";if(n.type!=="ExpressionStatement")return;const t=n.expression;if(!u(t)||t.type!=="CallExpression")return;const e=t.callee;if(!u(e)||e.type!=="MemberExpression")return;const o=e.object,i=e.property;if(!u(o)||o.type!=="Identifier"||!u(i)||i.type!=="Identifier"||i.name!=="build")return;const s=o.name;if(typeof s=="string")return s==="AppFactory"?"app-init":l(s,r)}function l(n,r){for(const[t,e]of Object.entries(r))if(e===n)return t}function h(n,r){const t=[];for(const e of r){const o=n.find(i=>i.start<=e.start&&i.end>=e.start+e.length);o!==void 0&&t.push({endPos:o.end,type:e.type})}return t}function I(n){return[...n].sort((r,t)=>r.endPos-t.endPos)}function b(n,r){const t=n.find(e=>e.end===r);return t!==void 0?t.index+1:n.length}export{h as buildResourceLocations,x as indexBody,I as orderByEndPos,b as resolveInsertIndex};
1
+ import{isRecord as c}from"../../_internal.js";import{findTypeByIdentifier as a}from"../../registry.js";function x(n,r){const e=[],t=[],i=[];let o=r.length;for(let f=0;f<n.length;f+=1){const s=n[f];if(s===void 0)continue;const u=typeof s.start=="number"?s.start:0,p=typeof s.end=="number"?s.end:u;p>o&&(o=p);const d=l(s);e.push({index:f,start:u,end:p,type:d}),d==="import"?t.push({endPos:p}):(d==="app-init"||d==="tags")&&i.push({endPos:p,type:d})}return{anchors:e,importInfos:t,appInitLocations:i,programEnd:o}}function l(n){if(n.type==="ImportDeclaration")return"import";if(n.type!=="ExpressionStatement")return;const r=n.expression;if(!c(r)||r.type!=="CallExpression")return;const e=r.callee;if(!c(e)||e.type!=="MemberExpression")return;const t=e.object,i=e.property;if(!c(t)||t.type!=="Identifier"||!c(i)||i.type!=="Identifier"||i.name!=="build")return;const o=t.name;if(typeof o=="string")return o==="AppFactory"?"app-init":a(o)}function h(n,r){const e=[];for(const t of r){const i=n.find(o=>o.start<=t.start&&o.end>=t.start+t.length);i!==void 0&&e.push({endPos:i.end,type:t.type})}return e}function I(n){return[...n].sort((r,e)=>r.endPos-e.endPos)}function g(n,r){const e=n.find(t=>t.end===r);return e!==void 0?e.index+1:n.length}export{h as buildResourceLocations,x as indexBody,I as orderByEndPos,g as resolveInsertIndex};
@@ -1 +1 @@
1
- import{failure as o,success as L}from"../../types/Result.js";import{DEFAULT_FILE_PATH as h,computeLinesDelta as P,extractProgramBody as k,isRecord as D}from"../_internal.js";import{appendSpecifier as R,buildFactoryStatement as T,buildImportDeclaration as b,detectQuoteStyle as _,parse as x,printFile as C}from"../fileRewriter/index.js";import{locateAllShapes as A,locateByShape as B}from"../semanticIndex/index.js";import{buildResourceLocations as O,indexBody as w,orderByEndPos as N,resolveInsertIndex as Q}from"./addResource/bodyIndex.js";import{buildPropertyInputs as Y}from"./addResource/propertyBuilder.js";import{findInsertionPosition as U}from"./findInsertionPosition.js";const f="@fjall/components-infrastructure",l={database:"DatabaseFactory",storage:"StorageFactory",compute:"ComputeFactory",messaging:"MessagingFactory",cdn:"CdnFactory",network:"NetworkFactory",pattern:"PatternFactory"};function K(t,r){const c=r.filePath??h,a=x(t,c);if(!a.success)return o(a.error);const e=B(t,{type:r.type,name:r.name},c);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?o(e.error):o({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data!==void 0)return o({kind:"DuplicateResourceError",type:r.type,name:r.name});const n=_(a.data),d=Y(r.properties,n);if(!d.success)return o(d.error);const m=l[r.type],y=T({factory:m,name:r.name,properties:d.data,quoteStyle:n}),u=k(a.data);if(u===void 0)return o({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const i=w(u,t,l),s=A(t,c);if(!s.success)return s.error.kind==="TemplateLiteralNameError"?o(s.error):o({kind:"SemanticQueryError",reason:s.error.reason,cause:s.error.cause});const F=O(i.anchors,s.data),E=N([...i.appInitLocations,...F]),I=U(i.importInfos,E,r.type,i.programEnd),S=Q(i.anchors,I);u.splice(S,0,y),v(u,m,n);const p=C(a.data,t),g=P(t,p);return L({content:p,linesChanged:g})}function v(t,r,c){for(const e of t){if(e.type!=="ImportDeclaration")continue;const n=e.source;if(!(!D(n)||n.type!=="StringLiteral")&&n.value===f){R(e,r);return}}const a=b([r],f,c);t.unshift(a)}export{K as addResource};
1
+ import{failure as o,success as h}from"../../types/Result.js";import{DEFAULT_FILE_PATH as T,computeLinesDelta as R,extractProgramBody as F,isRecord as P}from"../_internal.js";import{appendSpecifier as g,buildFactoryStatement as k,buildImportDeclaration as x,detectQuoteStyle as D,parse as b,printFile as A}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as _}from"../registry.js";import{locateAllShapes as B,locateByShape as O}from"../semanticIndex/index.js";import{buildResourceLocations as Q,indexBody as C,orderByEndPos as N,resolveInsertIndex as U}from"./addResource/bodyIndex.js";import{buildPropertyInputs as v}from"./addResource/propertyBuilder.js";import{findInsertionPosition as w}from"./findInsertionPosition.js";const f="@fjall/components-infrastructure";function V(t,r){const i=r.filePath??T,n=b(t,i);if(!n.success)return o(n.error);const e=O(t,{type:r.type,name:r.name},i);if(!e.success)return e.error.kind==="TemplateLiteralNameError"?o(e.error):o({kind:"SemanticQueryError",reason:e.error.reason,cause:e.error.cause});if(e.data!==void 0)return o({kind:"DuplicateResourceError",type:r.type,name:r.name});const a=D(n.data),m=v(r.properties,a);if(!m.success)return o(m.error);const d=_[r.type].factoryIdentifier,l=k({factory:d,name:r.name,properties:m.data,quoteStyle:a}),u=F(n.data);if(u===void 0)return o({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const c=C(u,t),s=B(t,i);if(!s.success)return s.error.kind==="TemplateLiteralNameError"?o(s.error):o({kind:"SemanticQueryError",reason:s.error.reason,cause:s.error.cause});const y=Q(c.anchors,s.data),E=N([...c.appInitLocations,...y]),S=w(c.importInfos,E,r.type,c.programEnd),I=U(c.anchors,S);u.splice(I,0,l),M(u,d,a);const p=A(n.data,t),L=R(t,p);return h({content:p,linesChanged:L})}function M(t,r,i){for(const e of t){if(e.type!=="ImportDeclaration")continue;const a=e.source;if(!(!P(a)||a.type!=="StringLiteral")&&a.value===f){g(e,r);return}}const n=x([r],f,i);t.unshift(n)}export{V as addResource};
@@ -1,4 +1,3 @@
1
- export { SCHEMA_FRAGMENTS } from "./schemaFragments.js";
2
1
  export { addResource, type AddOptions, type AddResourceError, type AddResourceSuccess, } from "./addResource.js";
3
2
  export { findInsertionPosition, type ImportInfo, type InsertionStatementType, type ResourceLocation, } from "./findInsertionPosition.js";
4
3
  export { removeResource, type LinesChanged, type RemoveOptions, type RemoveResourceError, type RemoveResourceSuccess, } from "./removeResource.js";
@@ -1 +1 @@
1
- import{SCHEMA_FRAGMENTS as e}from"./schemaFragments.js";import{addResource as t}from"./addResource.js";import{findInsertionPosition as p}from"./findInsertionPosition.js";import{removeResource as x}from"./removeResource.js";import{modifyResource as n}from"./modifyResource.js";import{ensureImports as u}from"./ensureImports.js";export{e as SCHEMA_FRAGMENTS,t as addResource,u as ensureImports,p as findInsertionPosition,n as modifyResource,x as removeResource};
1
+ import{addResource as e}from"./addResource.js";import{findInsertionPosition as t}from"./findInsertionPosition.js";import{removeResource as s}from"./removeResource.js";import{modifyResource as i}from"./modifyResource.js";import{ensureImports as x}from"./ensureImports.js";export{e as addResource,x as ensureImports,t as findInsertionPosition,i as modifyResource,s as removeResource};
@@ -1 +1 @@
1
- import{failure as c,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as g,computeLinesDelta as k,extractProgramBody as E,isRecord as d}from"../_internal.js";import{buildObjectProperty as b,detectQuoteStyle as P,parse as S,printFile as v}from"../fileRewriter/index.js";import{locateAllShapes as A,locateByShape as x}from"../semanticIndex/index.js";import{toAstValue as N}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as C,isNodeShape as h,readKeyName as L}from"./modifyResource/literalConversion.js";import{SCHEMA_FRAGMENTS as j}from"./schemaFragments.js";function H(o,e){const t=e.filePath??g,n=S(o,t);if(!n.success)return c(n.error);const r=x(o,{type:e.type,name:e.name},t);if(!r.success)return r.error.kind==="TemplateLiteralNameError"?c(r.error):c({kind:"SemanticQueryError",reason:r.error.reason,cause:r.error.cause});if(r.data===void 0)return c({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:R(o,e.type,t)});const s=E(n.data);if(s===void 0)return c({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const i=w(s,r.data);if(i===void 0)return c({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const a=P(n.data),u=C(i,e.properties),l=j[e.type].safeParse(u);if(!l.success){const f=l.error.issues[0];return c({kind:"InvalidPropertyError",property:f!==void 0&&f.path.length>0?String(f.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:f?.message??"Schema validation failed"})}const p=F(i,e.properties,a);if(!p.success)return c(p.error);const m=v(n.data,o);return y({content:m,linesChanged:k(o,m)})}function w(o,e){const t=e.start+e.length;let n;const r=s=>{if(n!==void 0||s.type!=="CallExpression")return;const i=s.arguments;if(!Array.isArray(i)||i.length<2)return;const a=i[0];if(!h(a)||a.type!=="StringLiteral"||a.start!==e.start||a.end!==t)return;const u=i[1];h(u)&&u.type==="ObjectExpression"&&(n=u)};for(const s of o)if(Q(s,r),n!==void 0)break;return n}function F(o,e,t){const n=T(o);for(const[r,s]of Object.entries(e)){const i=N(s,t);if(i===void 0)return c({kind:"InvalidPropertyError",property:r,reason:`Unsupported property value for "${r}" (Phase 1 accepts string/number/boolean/null only).`});const a=O(o,r);if(a!==void 0){a.value=i;continue}const u=b(r,i,t);n&&(u.extra={...u.extra??{},trailingComma:!0}),o.properties.push(u)}return y(void 0)}function O(o,e){return o.properties.find(t=>(t.type==="Property"||t.type==="ObjectProperty")&&t.shorthand!==!0&&t.computed!==!0&&L(t.key)===e)}function T(o){return o.properties[o.properties.length-1]?.extra?.trailingComma===!0}function R(o,e,t){const n=A(o,t);return n.success?n.data.filter(r=>r.type===e).map(r=>r.symbolName):[]}function Q(o,e){const t=[o];for(;t.length>0;){const n=t.pop();if(d(n)){typeof n.type=="string"&&e(n);for(const r of Object.keys(n)){if(r==="loc"||r==="comments"||r==="tokens")continue;const s=n[r];if(Array.isArray(s))for(const i of s)d(i)&&t.push(i);else d(s)&&t.push(s)}}}}export{H as modifyResource};
1
+ import{failure as u,success as y}from"../../types/Result.js";import{DEFAULT_FILE_PATH as g,computeLinesDelta as k,extractProgramBody as E,isRecord as d}from"../_internal.js";import{buildObjectProperty as b,detectQuoteStyle as P,parse as S,printFile as v}from"../fileRewriter/index.js";import{STATEMENT_REGISTRY as x}from"../registry.js";import{locateAllShapes as A,locateByShape as N}from"../semanticIndex/index.js";import{toAstValue as T}from"./addResource/propertyBuilder.js";import{buildMergedLiteral as C,isNodeShape as h,readKeyName as L}from"./modifyResource/literalConversion.js";function V(o,e){const t=e.filePath??g,n=S(o,t);if(!n.success)return u(n.error);const r=N(o,{type:e.type,name:e.name},t);if(!r.success)return r.error.kind==="TemplateLiteralNameError"?u(r.error):u({kind:"SemanticQueryError",reason:r.error.reason,cause:r.error.cause});if(r.data===void 0)return u({kind:"ResourceNotFoundError",type:e.type,name:e.name,knownNames:R(o,e.type,t)});const i=E(n.data);if(i===void 0)return u({kind:"SemanticQueryError",reason:"recast File is missing program.body"});const s=j(i,r.data);if(s===void 0)return u({kind:"SemanticQueryError",reason:"Unable to resolve config ObjectExpression for the located resource."});const a=P(n.data),c=C(s,e.properties),l=x[e.type].schemaFragment.safeParse(c);if(!l.success){const f=l.error.issues[0];return u({kind:"InvalidPropertyError",property:f!==void 0&&f.path.length>0?String(f.path[0]):Object.keys(e.properties)[0]??"<unknown>",reason:f?.message??"Schema validation failed"})}const p=w(s,e.properties,a);if(!p.success)return u(p.error);const m=v(n.data,o);return y({content:m,linesChanged:k(o,m)})}function j(o,e){const t=e.start+e.length;let n;const r=i=>{if(n!==void 0||i.type!=="CallExpression")return;const s=i.arguments;if(!Array.isArray(s)||s.length<2)return;const a=s[0];if(!h(a)||a.type!=="StringLiteral"||a.start!==e.start||a.end!==t)return;const c=s[1];h(c)&&c.type==="ObjectExpression"&&(n=c)};for(const i of o)if(I(i,r),n!==void 0)break;return n}function w(o,e,t){const n=O(o);for(const[r,i]of Object.entries(e)){const s=T(i,t);if(s===void 0)return u({kind:"InvalidPropertyError",property:r,reason:`Unsupported property value for "${r}" (Phase 1 accepts string/number/boolean/null only).`});const a=F(o,r);if(a!==void 0){a.value=s;continue}const c=b(r,s,t);n&&(c.extra={...c.extra??{},trailingComma:!0}),o.properties.push(c)}return y(void 0)}function F(o,e){return o.properties.find(t=>(t.type==="Property"||t.type==="ObjectProperty")&&t.shorthand!==!0&&t.computed!==!0&&L(t.key)===e)}function O(o){return o.properties[o.properties.length-1]?.extra?.trailingComma===!0}function R(o,e,t){const n=A(o,t);return n.success?n.data.filter(r=>r.type===e).map(r=>r.symbolName):[]}function I(o,e){const t=[o];for(;t.length>0;){const n=t.pop();if(d(n)){typeof n.type=="string"&&e(n);for(const r of Object.keys(n)){if(r==="loc"||r==="comments"||r==="tokens")continue;const i=n[r];if(Array.isArray(i))for(const s of i)d(s)&&t.push(s);else d(i)&&t.push(i)}}}}export{V as modifyResource};
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { type Result } from "../types/Result.js";
3
+ import type { NodeLocation, SemanticQueryError, StatementType, TemplateLiteralNameError } from "./types.js";
4
+ export type LocatorError = TemplateLiteralNameError | SemanticQueryError;
5
+ export interface StatementLocator {
6
+ factoryIdentifier: string;
7
+ findByShape(content: string, query: {
8
+ type: StatementType;
9
+ name: string;
10
+ }, filePath?: string): Result<NodeLocation | undefined, LocatorError>;
11
+ validateContext(content: string, filePath?: string): Result<void, LocatorError>;
12
+ }
13
+ export interface StatementGeneratorInput {
14
+ name: string;
15
+ properties: ReadonlyArray<{
16
+ key: string;
17
+ value: unknown;
18
+ }>;
19
+ quoteStyle: "single" | "double";
20
+ }
21
+ export interface StatementGenerator {
22
+ build(input: StatementGeneratorInput): unknown;
23
+ }
24
+ export interface StatementTypeEntry {
25
+ factoryIdentifier: FactoryIdentifier;
26
+ locator: StatementLocator;
27
+ generator: StatementGenerator;
28
+ schemaFragment: z.ZodObject;
29
+ }
30
+ declare const FACTORY_IDENTIFIERS: {
31
+ readonly database: "DatabaseFactory";
32
+ readonly storage: "StorageFactory";
33
+ readonly compute: "ComputeFactory";
34
+ readonly messaging: "MessagingFactory";
35
+ readonly cdn: "CdnFactory";
36
+ readonly network: "NetworkFactory";
37
+ readonly pattern: "PatternFactory";
38
+ };
39
+ export type FactoryIdentifier = (typeof FACTORY_IDENTIFIERS)[StatementType];
40
+ export declare const STATEMENT_REGISTRY: Record<StatementType, StatementTypeEntry>;
41
+ export declare function findTypeByIdentifier(identifier: string): StatementType | undefined;
42
+ export {};
@@ -0,0 +1 @@
1
+ import{z as c}from"zod";import{CDNResourcePlanSchema as m,ComputeResourcePlanSchema as u,DatabaseResourcePlanSchema as p,NetworkResourcePlanSchema as g,NextJSPatternConfigSchema as d,PayloadPatternConfigSchema as h,S3ResourcePlanSchema as S,SQSResourcePlanSchema as l}from"../schemas/index.js";import{failure as y}from"../types/Result.js";const r={database:"DatabaseFactory",storage:"StorageFactory",compute:"ComputeFactory",messaging:"MessagingFactory",cdn:"CdnFactory",network:"NetworkFactory",pattern:"PatternFactory"};function n(t){const{name:e,...o}=t.shape;return c.object(o).partial().strict()}const f=n(p),F=n(S),b=(()=>{const{name:t,...e}=u.shape;return c.object(e).partial().strict()})(),E=n(l),w=n(m),P=n(g),R=(()=>{const{name:t,...e}=h.shape,{name:o,...i}=d.shape;return c.object({...e,...i}).partial().strict()})();function s(t,e){return y({kind:"SemanticQueryError",reason:`StatementTypeEntry.${t} for ${e} is not wired; existing types dispatch through the shared locator/generator.`})}function C(t){return{factoryIdentifier:t,findByShape:()=>s("locator.findByShape",t),validateContext:()=>s("locator.validateContext",t)}}function T(t){return{build:()=>{throw new Error(`StatementTypeEntry.generator.build for ${t} is not wired; existing types dispatch through the shared buildFactoryStatement.`)}}}function a(t,e){return{factoryIdentifier:t,locator:C(t),generator:T(t),schemaFragment:e}}const x={database:a(r.database,f),storage:a(r.storage,F),compute:a(r.compute,b),messaging:a(r.messaging,E),cdn:a(r.cdn,w),network:a(r.network,P),pattern:a(r.pattern,R)};function j(t){for(const[e,o]of Object.entries(x))if(o.factoryIdentifier===t)return e}export{x as STATEMENT_REGISTRY,j as findTypeByIdentifier};
@@ -1 +1 @@
1
- import{Node as s,SyntaxKind as a}from"ts-morph";import{failure as c,success as l}from"../../types/Result.js";import{DEFAULT_FILE_PATH as u}from"../_internal.js";import{getProject as m}from"./projectCache.js";const f={DatabaseFactory:"database",StorageFactory:"storage",ComputeFactory:"compute",MessagingFactory:"messaging",CdnFactory:"cdn",NetworkFactory:"network",PatternFactory:"pattern"};function g(n){return Object.prototype.hasOwnProperty.call(f,n)}function b(n,t,e=u){const o=y(n,e);if(!o.success)return o;const r=o.data.find(i=>i.type===t.type&&i.symbolName===t.name);return l(r)}function y(n,t=u){let e;try{e=m().createSourceFile(t,n,{overwrite:!0})}catch(r){return c({kind:"SemanticQueryError",reason:"Failed to create source file",cause:r})}const o=[];try{e.forEachDescendant(r=>{if(!s.isCallExpression(r))return;const i=h(r);if(i!=="not-factory-call"&&i.kind!=="binding-pattern-declared"){if(i.kind==="template-literal-name")throw new d(r,i.type);o.push({filePath:t,start:i.nameStart,length:i.nameLength,symbolName:i.name,type:i.type})}})}catch(r){return r instanceof d?c(r.toError(t)):c({kind:"SemanticQueryError",reason:"forEachDescendant traversal failed",cause:r})}return l(o)}function h(n){const t=n.getExpression();if(!s.isPropertyAccessExpression(t))return"not-factory-call";const e=E(t);if(e===void 0||F(n))return"not-factory-call";if(S(n))return{kind:"binding-pattern-declared"};const r=n.getArguments()[0];return r===void 0?"not-factory-call":s.isTemplateExpression(r)||s.isNoSubstitutionTemplateLiteral(r)?{kind:"template-literal-name",type:e}:s.isStringLiteral(r)?{kind:"match",type:e,name:r.getLiteralValue(),nameStart:r.getStart(),nameLength:r.getWidth()}:"not-factory-call"}function E(n){const t=n.getExpression();if(!s.isIdentifier(t)||n.getName()!=="build")return;const e=t.getText();if(g(e))return f[e]}function F(n){let t=n.getParent();for(;t!==void 0;){const e=t.getKind();if(e===a.TypeReference||e===a.TypeQuery||e===a.TypeLiteral||e===a.TypeAliasDeclaration||e===a.InterfaceDeclaration||e===a.TypeParameter||e===a.PropertySignature||e===a.MethodSignature||e===a.JsxOpeningElement||e===a.JsxClosingElement||e===a.JsxSelfClosingElement||e===a.JsxAttribute)return!0;t=t.getParent()}return!1}function S(n){const t=n.getFirstAncestorByKind(a.VariableDeclaration);if(t===void 0)return!1;const o=t.getNameNode().getKind();return o===a.ObjectBindingPattern||o===a.ArrayBindingPattern}class d extends Error{call;type;constructor(t,e){super("Template-literal factory name detected"),this.call=t,this.type=e,this.name="TemplateLiteralMarker"}toError(t){const o=this.call.getArguments()[0]?.getStart()??this.call.getStart(),r=this.call.getSourceFile(),{line:i,column:p}=r.getLineAndColumnAtPos(o);return{kind:"TemplateLiteralNameError",file:t,line:i,column:p,suggestion:"Replace the template literal with a plain string literal so the resource name can be resolved statically."}}}export{y as locateAllShapes,b as locateByShape};
1
+ import{Node as s,SyntaxKind as a}from"ts-morph";import{failure as c,success as l}from"../../types/Result.js";import{DEFAULT_FILE_PATH as u}from"../_internal.js";import{findTypeByIdentifier as p}from"../registry.js";import{getProject as m}from"./projectCache.js";function b(n,t,e=u){const o=g(n,e);if(!o.success)return o;const r=o.data.find(i=>i.type===t.type&&i.symbolName===t.name);return l(r)}function g(n,t=u){let e;try{e=m().createSourceFile(t,n,{overwrite:!0})}catch(r){return c({kind:"SemanticQueryError",reason:"Failed to create source file",cause:r})}const o=[];try{e.forEachDescendant(r=>{if(!s.isCallExpression(r))return;const i=y(r);if(i!=="not-factory-call"&&i.kind!=="binding-pattern-declared"){if(i.kind==="template-literal-name")throw new f(r,i.type);o.push({filePath:t,start:i.nameStart,length:i.nameLength,symbolName:i.name,type:i.type})}})}catch(r){return r instanceof f?c(r.toError(t)):c({kind:"SemanticQueryError",reason:"forEachDescendant traversal failed",cause:r})}return l(o)}function y(n){const t=n.getExpression();if(!s.isPropertyAccessExpression(t))return"not-factory-call";const e=h(t);if(e===void 0||E(n))return"not-factory-call";if(S(n))return{kind:"binding-pattern-declared"};const r=n.getArguments()[0];return r===void 0?"not-factory-call":s.isTemplateExpression(r)||s.isNoSubstitutionTemplateLiteral(r)?{kind:"template-literal-name",type:e}:s.isStringLiteral(r)?{kind:"match",type:e,name:r.getLiteralValue(),nameStart:r.getStart(),nameLength:r.getWidth()}:"not-factory-call"}function h(n){const t=n.getExpression();if(s.isIdentifier(t)&&n.getName()==="build")return p(t.getText())}function E(n){let t=n.getParent();for(;t!==void 0;){const e=t.getKind();if(e===a.TypeReference||e===a.TypeQuery||e===a.TypeLiteral||e===a.TypeAliasDeclaration||e===a.InterfaceDeclaration||e===a.TypeParameter||e===a.PropertySignature||e===a.MethodSignature||e===a.JsxOpeningElement||e===a.JsxClosingElement||e===a.JsxSelfClosingElement||e===a.JsxAttribute)return!0;t=t.getParent()}return!1}function S(n){const t=n.getFirstAncestorByKind(a.VariableDeclaration);if(t===void 0)return!1;const o=t.getNameNode().getKind();return o===a.ObjectBindingPattern||o===a.ArrayBindingPattern}class f extends Error{call;type;constructor(t,e){super("Template-literal factory name detected"),this.call=t,this.type=e,this.name="TemplateLiteralMarker"}toError(t){const o=this.call.getArguments()[0]?.getStart()??this.call.getStart(),r=this.call.getSourceFile(),{line:i,column:d}=r.getLineAndColumnAtPos(o);return{kind:"TemplateLiteralNameError",file:t,line:i,column:d,suggestion:"Replace the template literal with a plain string literal so the resource name can be resolved statically."}}}export{g as locateAllShapes,b as locateByShape};
@@ -1 +1 @@
1
- export declare const GENERATOR_VERSION = "0.89.6";
1
+ export declare const GENERATOR_VERSION = "0.94.0";
@@ -1 +1 @@
1
- export const GENERATOR_VERSION = "0.89.6";
1
+ export const GENERATOR_VERSION = "0.94.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/generator",
3
- "version": "0.89.6",
3
+ "version": "0.94.0",
4
4
  "description": "Pure infrastructure generation logic for Fjall",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "license": "SEE LICENSE IN LICENSE",
37
37
  "dependencies": {
38
- "@fjall/util": "^0.89.6",
38
+ "@fjall/util": "^0.94.0",
39
39
  "ast-types": "^0.16.1",
40
40
  "recast": "^0.23.11",
41
41
  "ts-morph": "^28.0.0",
@@ -50,5 +50,5 @@
50
50
  "typescript-eslint": "^8.19.0",
51
51
  "vitest": "^4.1.0"
52
52
  },
53
- "gitHead": "fb309fa904991ac4f23c49b3bed1be146f738900"
53
+ "gitHead": "97f6b382405bb3068e841d30866222fd76bc3b15"
54
54
  }
@@ -1,9 +0,0 @@
1
- import { z } from "zod";
2
- import { type StatementType } from "../semanticIndex/index.js";
3
- /**
4
- * Map from `StatementType` → Zod fragment validating the config-object
5
- * portion of an `XFactory.build("Name", { ... })` call. Every fragment
6
- * is `.strict()` (Pitfall 3) so unknown property names fail loudly
7
- * instead of being silently stripped.
8
- */
9
- export declare const SCHEMA_FRAGMENTS: Record<StatementType, z.ZodObject>;
@@ -1 +0,0 @@
1
- import{z as n}from"zod";import{CDNResourcePlanSchema as c,ComputeResourcePlanSchema as s,DatabaseResourcePlanSchema as m,NetworkResourcePlanSchema as p,NextJSPatternConfigSchema as g,PayloadPatternConfigSchema as S,S3ResourcePlanSchema as i,SQSResourcePlanSchema as u}from"../../schemas/index.js";function e(a){const{name:t,...r}=a.shape;return n.object(r).partial().strict()}const h=e(m),l=e(i),P=(()=>{const{name:a,...t}=s.shape;return n.object(t).partial().strict()})(),F=e(u),f=e(c),R=e(p),b=(()=>{const{name:a,...t}=S.shape,{name:r,...o}=g.shape;return n.object({...t,...o}).partial().strict()})(),_={database:h,storage:l,compute:P,messaging:F,cdn:f,network:R,pattern:b};export{_ as SCHEMA_FRAGMENTS};