@lunora/codegen 1.0.0-alpha.14 → 1.0.0-alpha.140
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/LICENSE.md +6 -0
- package/dist/index.d.mts +3010 -1005
- package/dist/index.d.ts +3010 -1005
- package/dist/index.mjs +1 -31
- package/dist/packem_shared/AGENTS_FILENAME-D1qA0h5m.mjs +1 -0
- package/dist/packem_shared/CONTAINERS_FILENAME-oKaARMoA.mjs +1 -0
- package/dist/packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs +1 -0
- package/dist/packem_shared/DEFAULT_TARGET-CrhWLUK7.mjs +1 -0
- package/dist/packem_shared/FLAGS_FILENAME-BasxlnVS.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-BgmuZY9e.mjs +1 -0
- package/dist/packem_shared/LUNORA_ERROR_CODES-BYg8Lpgb.mjs +1 -0
- package/dist/packem_shared/MUTATORS_FILENAME-DJvAhDlD.mjs +1 -0
- package/dist/packem_shared/NOTIFY_FILENAME-B-eIjru_.mjs +1 -0
- package/dist/packem_shared/OPENRPC_VERSION-B9ZC0SrC.mjs +3 -0
- package/dist/packem_shared/QUEUES_FILENAME-D229WtRm.mjs +1 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BqXGGcOj.mjs +9 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-DLXXalg2.mjs +2 -0
- package/dist/packem_shared/SDK_LANGUAGES-CFyux-74.mjs +371 -0
- package/dist/packem_shared/SHAPES_FILENAME-BTdasTq2.mjs +1 -0
- package/dist/packem_shared/SchemaSnapshotParseError-CvPTjDrT.mjs +16 -0
- package/dist/packem_shared/WORKFLOWS_FILENAME-DRaiCNa6.mjs +1 -0
- package/dist/packem_shared/ast-CjWtsS6S.mjs +1 -0
- package/dist/packem_shared/buildOpenApiDocument-DLEWgA5Y.mjs +3 -0
- package/dist/packem_shared/chain-CtC3-wwZ.mjs +1 -0
- package/dist/packem_shared/classify-procedure-call-AKeIK05y.mjs +1 -0
- package/dist/packem_shared/describeErrorLevelFindings-D23VSkFP.mjs +1 -0
- package/dist/packem_shared/discoverAuthApiCalls-C35kkayg.mjs +1 -0
- package/dist/packem_shared/discoverCrons-wXBfQcfn.mjs +1 -0
- package/dist/packem_shared/discoverFunctions-BBDziFXy.mjs +1 -0
- package/dist/packem_shared/discoverHttpRoutes-Dmow2gql.mjs +1 -0
- package/dist/packem_shared/discoverInserts-C5l2INmE.mjs +1 -0
- package/dist/packem_shared/discoverMaskProcedures-Df4JQp_2.mjs +1 -0
- package/dist/packem_shared/discoverMigrations-CWH7T6qz.mjs +1 -0
- package/dist/packem_shared/discoverNondeterministicCalls-JsO91i57.mjs +1 -0
- package/dist/packem_shared/discoverQueries-iypfwfdZ.mjs +1 -0
- package/dist/packem_shared/discoverR2sqlCalls-BbfOpwE4.mjs +1 -0
- package/dist/packem_shared/discoverRlsMetadata-DGUGYgWs.mjs +1 -0
- package/dist/packem_shared/discoverRlsProcedures-CRshfYZE.mjs +1 -0
- package/dist/packem_shared/discoverSandboxUsage-DdewAOuj.mjs +1 -0
- package/dist/packem_shared/discoverSchema-Bp8DcNq7.mjs +1 -0
- package/dist/packem_shared/discoverStorageRulesMetadata-gyO60A5S.mjs +1 -0
- package/dist/packem_shared/emit-s6mHBmXu.mjs +2268 -0
- package/dist/packem_shared/emitApp-1QfYpsq0.mjs +646 -0
- package/dist/packem_shared/exported-procedure-chains-MlZRKqSD.mjs +1 -0
- package/dist/packem_shared/formatAdvisories-CkEu1eye.mjs +2 -0
- package/dist/packem_shared/index-CCDlo9L7.mjs +1 -0
- package/dist/packem_shared/isTypedSchema-B_qlBbE-.mjs +2 -0
- package/dist/packem_shared/module-specifiers-WF8iAydP.mjs +1 -0
- package/dist/packem_shared/parse-validator-BFTp87yz.mjs +1 -0
- package/dist/packem_shared/paths-C-9fwEgQ.mjs +1 -0
- package/dist/packem_shared/queries-B_xEHIeL.mjs +1 -0
- package/dist/packem_shared/readPackageDependencies-C6h6FZuP.mjs +1 -0
- package/dist/packem_shared/redact-Cy14LEnc.mjs +1 -0
- package/dist/packem_shared/schemaFromIr-BWFnvCVg.mjs +1 -0
- package/dist/packem_shared/unwrap-handler-return-CmIWbykC.mjs +1 -0
- package/package.json +16 -7
- package/dist/packem_shared/CONTAINERS_FILENAME-DlP6YM_Q.mjs +0 -224
- package/dist/packem_shared/CodegenDiagnosticError-DeblMkzO.mjs +0 -23
- package/dist/packem_shared/GENERATED_HEADER-BEA7oWGC.mjs +0 -2841
- package/dist/packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs +0 -61
- package/dist/packem_shared/LUNORA_SOLUTION_RULES-BTejmZp-.mjs +0 -131
- package/dist/packem_shared/OPENRPC_VERSION-CQ3f8YQ-.mjs +0 -60
- package/dist/packem_shared/QUEUES_FILENAME-B5_eWCRe.mjs +0 -119
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BXtduJFE.mjs +0 -954
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs +0 -245
- package/dist/packem_shared/WORKFLOWS_FILENAME-D62dcBGg.mjs +0 -84
- package/dist/packem_shared/buildOpenApiDocument-699G4RP4.mjs +0 -183
- package/dist/packem_shared/discover-ast-CT6BgBr4.mjs +0 -13
- package/dist/packem_shared/discoverAuthApiCalls-CoirYbg6.mjs +0 -62
- package/dist/packem_shared/discoverCrons-Cev7RRAf.mjs +0 -257
- package/dist/packem_shared/discoverFunctions-BWMczzBx.mjs +0 -465
- package/dist/packem_shared/discoverHttpRoutes-CfP6cMzt.mjs +0 -131
- package/dist/packem_shared/discoverInserts-C7zxXkUf.mjs +0 -61
- package/dist/packem_shared/discoverMaskProcedures-Cm81kwrb.mjs +0 -217
- package/dist/packem_shared/discoverMigrations-Bi5nJ0mJ.mjs +0 -97
- package/dist/packem_shared/discoverNondeterministicCalls-C4M8AXmQ.mjs +0 -122
- package/dist/packem_shared/discoverQueries-B0wGT-xe.mjs +0 -62
- package/dist/packem_shared/discoverR2sqlCalls-BVNMd428.mjs +0 -80
- package/dist/packem_shared/discoverRlsMetadata-BS9GOGC5.mjs +0 -280
- package/dist/packem_shared/discoverSchema-BnWHHJ4T.mjs +0 -822
- package/dist/packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs +0 -97
- package/dist/packem_shared/emitApp-DiK0QSBn.mjs +0 -617
- package/dist/packem_shared/formatAdvisories-8NIv1k0I.mjs +0 -69
- package/dist/packem_shared/parse-validator-Cabb60UV.mjs +0 -133
- package/dist/packem_shared/paths-BRd6JHuF.mjs +0 -11
- package/dist/packem_shared/schemaFromIr-DTYsLBaA.mjs +0 -57
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Node as a}from"ts-morph";import{c as n}from"./classify-procedure-call-AKeIK05y.mjs";const f=s=>{const i=[];for(const r of s.getVariableStatements())if(r.isExported())for(const t of r.getDeclarations()){const e=t.getInitializer(),o=e&&a.isCallExpression(e)?n(e):void 0;o?.receiver&&i.push({name:t.getName(),receiver:o.receiver})}return i};export{f as e};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{runAdvisor as t}from"@lunora/advisor";const i=n=>[...n.indexes.map(e=>({fields:e.fields,kind:"index",name:e.name,unique:e.unique})),...n.searchIndexes.map(e=>({fields:[e.field,...e.filterFields??[]],kind:"search",name:e.name})),...n.rankIndexes.map(e=>({fields:[...e.sortBy.map(r=>r.field),...e.partitionBy??[]],kind:"rank",name:e.name})),...n.vectorIndexes.filter(e=>e.field!==void 0).map(e=>({fields:[e.field],kind:"vector",name:e.name})),...(n.geoIndexes??[]).map(e=>({fields:[e.field],kind:"geo",name:e.name}))],d=n=>{const e={};for(const[r,s]of Object.entries(n.shape))e[r]=s.kind==="optional"?s.inner?.kind??"optional":s.kind;return e},l=n=>({rlsMode:n.rlsMode,tables:n.tables.map(e=>({externallyManaged:e.externallyManaged??!1,externalSource:e.externalSource?{hasReconcile:e.externalSource.hasReconcile??!1,hasSoftDelete:e.externalSource.hasSoftDelete??!1,hasTenantBy:e.externalSource.hasTenantBy,mode:e.externalSource.mode,unanalyzable:e.externalSource.unanalyzable}:void 0,columnKinds:d(e),fields:Object.keys(e.shape),indexes:i(e),isPublic:e.isPublic??!1,name:e.name,relations:e.relations.map(r=>({field:r.field,kind:r.kind,name:r.name,onDelete:r.onDelete,references:r.references,table:r.table})),commitOrdered:e.commitOrdered,shardKind:typeof e.shardMode=="string"?e.shardMode:"shardBy",softDelete:e.softDelete,ttl:e.ttl}))}),c=n=>n.map(e=>({exportName:e.exportName,file:`lunora/${e.filePath}.ts`,table:e.table})),m=n=>{const{argumentValidators:e,queries:r,schema:s,shapes:a,...o}=n;return{...o,argValidators:e,queries:r??[],schema:l(s),shapes:a===void 0?void 0:c(a)}},f=n=>t(m(n),{source:"static"}),h=n=>{if(n.length===0)return"";const e=`@lunora/codegen: ${String(n.length)} schema advisor finding${n.length===1?"":"s"}`,r=n.map(s=>` [${s.level}] ${s.name}: ${s.detail}`);return[e,...r].join(`
|
|
2
|
+
`)};export{h as formatAdvisories,f as lintSchema,m as toAdvisorContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Node as r}from"ts-morph";import{l as f,a as m,t as d}from"./ast-CjWtsS6S.mjs";import{w as g,c as p}from"./classify-procedure-call-AKeIK05y.mjs";const u=e=>{if(!r.isPropertyAssignment(e)&&!r.isShorthandPropertyAssignment(e)&&!r.isMethodDeclaration(e)&&!r.isGetAccessorDeclaration(e))return;const t=e.getNameNode();return r.isStringLiteral(t)?t.getLiteralValue():e.getName()},h=e=>g(e,"use","mask"),x=e=>{if(r.isPropertyAssignment(e)){const t=e.getInitializer();if(t&&r.isStringLiteral(t)){const s=t.getLiteralText();if(s==="redact"||s==="hash")return s}}return"custom"},k=e=>{const t=e.getArguments()[0];if(!t||!r.isObjectLiteralExpression(t))return[];const s=[];for(const i of t.getProperties()){const n=u(i);if(n===void 0||!r.isPropertyAssignment(i))continue;const o=i.getInitializer();if(!(!o||!r.isObjectLiteralExpression(o)))for(const a of o.getProperties()){const c=u(a);c!==void 0&&s.push({column:c,table:n})}}return s},v=e=>{const t=h(e);return{maskColumns:t.flatMap(s=>k(s)),usesMask:t.length>0}},P=new Set(["findFirst","findFirstOrThrow","findMany","get","query"]),C=new Set(["delete","insert","patch","replace"]),M=(e,t)=>{if(!r.isVariableDeclaration(e))return;const s=e.getInitializer();if(!s||!r.isCallExpression(s))return;const i=p(s);if(!i)return;const n=i.receiver?v(i.receiver):{maskColumns:[],usesMask:!1},{tablesRead:o,tablesWritten:a}=d(e,P,C);return{exportName:e.getName(),file:t,maskColumns:n.maskColumns,tablesRead:o,tablesWritten:a,usesMask:n.usesMask,visibility:i.visibility}},E=(e,t)=>{const s=[];for(const i of f(t)){const n=e.getSourceFile(i)??e.addSourceFileAtPath(i),o=m(t,i);for(const a of n.getVariableStatements())if(a.isExported())for(const c of a.getDeclarations()){const l=M(c,o);l&&s.push(l)}}return s};export{u as a,E as d,h as m,x as s};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const b=/[^a-zA-Z0-9]+/gu,M=/([a-z0-9])([A-Z])/gu,p=t=>t.split(b).filter(e=>e.length>0).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),L=t=>t.replaceAll(M,"$1_$2").replaceAll(b,"_").toLowerCase(),d=t=>t===void 0?!1:["$ref","allOf","anyOf","enum","items","oneOf","properties","type"].some(e=>e in t),O=t=>t==="query"?"query":t==="action"?"action":"mutation",i=(t,e=0)=>{if(e>32||t===null||typeof t!="object")return!1;if(Array.isArray(t))return t.some(o=>i(o,e+1));const r=t;if(r.type==="integer"&&r.format==="int64"||r.type==="string"&&r.contentEncoding==="base64")return!0;const{properties:n}=r;return n!==null&&typeof n=="object"&&Object.values(n).some(o=>i(o,e+1))?!0:["additionalProperties","allOf","anyOf","items","oneOf"].some(o=>i(r[o],e+1))},R=t=>t.replaceAll(/[\n\r\u2028\u2029]+/gu," ").replaceAll("*/","* /").replaceAll('"""','" ""'),T=t=>t.replaceAll("\\","\\\\").replaceAll('"','\\"').replaceAll(`
|
|
2
|
+
`,"\\n").replaceAll("\r","\\r"),j=["$","{","'","$","'","}"].join(""),D=t=>T(t).split("$").join(j),_=(t,e)=>t.argsType!==void 0?e.typed(t.argsType):t.takesArgs?e.untyped:e.none,f=32,h=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return!1;const r=t;return r.type==="null"||Array.isArray(r.type)&&r.type.includes("null")?!0:["anyOf","oneOf"].some(n=>{const o=r[n];return Array.isArray(o)&&o.some(s=>h(s,e+1))})},E=(t,e,r)=>e.length===0?r===0?[]:[t]:e.map(n=>({properties:{...t.properties,...n.properties},required:new Set([...t.required,...n.required])})),C=t=>{const{properties:e}=t;if(e===null||typeof e!="object")return[];const r=t.required;return[{properties:e,required:new Set(Array.isArray(r)?r.filter(n=>typeof n=="string"):[])}]},m=(t,e,r)=>{const n=t[e];return Array.isArray(n)?n.flatMap(o=>A(o,r+1)):[]},A=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return[];const r=t,n=[...C(r),...m(r,"allOf",e)],o={properties:Object.assign({},...n.map(a=>a.properties)),required:new Set(n.flatMap(a=>[...a.required]))},s=[...m(r,"anyOf",e),...m(r,"oneOf",e)];return E(o,s,n.length)},S=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return[];const r=t,n=[r];for(const o of["anyOf","oneOf","allOf"]){const s=r[o];if(Array.isArray(s))for(const a of s)n.push(...S(a,e+1))}return n},y=(t,e,r,n=0)=>{if(n>f||t===null||typeof t!="object")return;const o=A(t),s=[...new Set(o.flatMap(a=>Object.keys(a.properties)))].toSorted((a,l)=>a.localeCompare(l));for(const a of s){const l=[...e,a],u=o.every(c=>c.required.has(a)),g=o.map(c=>c.properties[a]).filter(c=>c!==void 0);u?g.some(c=>h(c))&&r.nullable.push(l):r.optional.push(l);for(const c of g)y(c,l,r,n+1)}for(const a of S(t))for(const l of["additionalProperties","items"]){const u=a[l];u!==null&&typeof u=="object"&&y(u,[...e,"*"],r,n+1)}},N=(t,e)=>t.join("\0").localeCompare(e.join("\0")),k=t=>{const e={nullable:[],optional:[]};y(t,[],e);const r=n=>[...new Map(n.map(o=>[o.join("\0"),o])).values()].toSorted(N);return{nullable:r(e.nullable),optional:r(e.optional)}},w=t=>{const[e="",r=""]=t.name.split(":"),n=`${p(e)}${p(r)}`,o=t.params?.[0]?.schema,s=t.result?.schema;return{argsNullPaths:k(o),argsType:d(o)&&!i(o)?`${n}Args`:void 0,takesArgs:d(o),functionName:r,functionPath:t.name,namespace:e,resultType:d(s)&&!i(s)?`${n}Result`:void 0,summary:t.summary??t.name,verb:O(t["x-lunora-function-kind"])}},x=t=>{const e=new Map;for(const r of t.methods){const n=w(r),o=e.get(n.namespace);o===void 0?e.set(n.namespace,[n]):o.push(n)}return[...e.entries()].toSorted(([r],[n])=>r.localeCompare(n)).map(([r,n])=>({methods:n.toSorted((o,s)=>o.functionName.localeCompare(s.functionName)),name:r}))},I=t=>t.methods.flatMap(e=>{const r=w(e);return[{name:r.argsType,schema:e.params?.[0]?.schema},{name:r.resultType,schema:e.result?.schema}]}).filter(e=>e.name!==void 0&&e.schema!==void 0).toSorted((e,r)=>e.name.localeCompare(r.name)),P=/^[A-Za-z][A-Za-z0-9]*$/u,$=t=>P.test(t),q=t=>{const e=new Map;for(const r of t.methods){const n=p(r.functionName);if(!$(n))throw new Error(`sdk: function "${r.functionPath}" produces the invalid identifier "${n}" — rename the export so it starts with a letter.`);const o=r.verb==="query"?[n,`Subscribe${n}`,`Watch${n}`]:[n];for(const s of o){const a=e.get(s);if(a!==void 0){const l=s.startsWith("Watch")?' (the Dart target emits a "watch" Stream member for every query)':"";throw new Error(`sdk: functions "${a}" and "${r.functionPath}" both generate "${s}"${l} — rename one so the generated methods stay distinct.`)}e.set(s,r.functionPath)}}},z=t=>{const e=new Map;for(const r of t){const n=p(r.name);if(!$(n))throw new Error(`sdk: namespace "${r.name}" produces the invalid identifier "${n}" — rename the file so it starts with a letter.`);const o=e.get(n);if(o!==void 0)throw new Error(`sdk: namespaces "${o}" and "${r.name}" both generate "${n}" — rename one so the generated types stay distinct.`);e.set(n,r.name),q(r)}},v=t=>t.flatMap(e=>e.methods),H=t=>[`GENERATED by \`lunora sdk generate --lang ${t}\` — do not edit.`,"Run the command again to regenerate."],U=(t,e)=>{const r=n=>n!==void 0&&new RegExp(String.raw`\b${n}\b`,"u").test(e)?n:void 0;return t.map(n=>({methods:n.methods.map(o=>({...o,argsType:r(o.argsType),resultType:r(o.resultType)})),name:n.name}))},W=t=>t.methods.filter(e=>i(e.params?.[0]?.schema)||i(e.result?.schema)).map(e=>e.name).toSorted((e,r)=>e.localeCompare(r)),Z=(t,e)=>[...new Set(v(t).flatMap(r=>[r.argsType,r.resultType]).filter(r=>r!==void 0&&!new RegExp(String.raw`\b${r}\b`,"u").test(e)))].toSorted((r,n)=>r.localeCompare(n)),F=t=>[...new Set(v(t).flatMap(e=>[e.argsType,e.resultType]).filter(e=>e!==void 0))].toSorted((e,r)=>e.localeCompare(r));export{v as allMethods,_ as argsChoice,z as assertGeneratable,R as commentText,H as generatedHeaderLines,i as hasUnrepresentableWireType,d as isTypedSchema,D as kotlinLiteral,I as modelSources,k as nullPathsOf,w as parseMethod,x as parseSpec,F as referencedModels,T as stringLiteral,p as toPascalCase,L as toSnakeCase,Z as undeclaredModels,W as unrepresentableFunctions,O as verbForKind,U as withDeclaredModels};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const r=/(?:^|\/)_generated\/server(?:\.js)?$/u,s=new Set(["@lunora/server","lunorash/server"]),o=e=>s.has(e),n=e=>r.test(e),t=e=>o(e)||n(e),a=new Set(["@lunora/scheduler",...s]),E=e=>a.has(e);export{t as a,o as b,E as i};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as p}from"@lunora/errors";import{Node as i}from"ts-morph";import{diagnosticAt as m}from"./CodegenDiagnosticError-BUXlG3P-.mjs";let d;const R=e=>{d=e},y=/^[A-Za-z_$][\w$]*$/u,f=new Set(["$defaultFn","$onUpdateFn","$type","default","defaultNow","nullable","serverDefault","unique"]),k=(e,r)=>{const t={notNull:!0,...e.column};switch(r){case"$defaultFn":case"default":case"defaultNow":case"serverDefault":{t.hasDefault=!0;break}case"$onUpdateFn":{t.hasOnUpdate=!0;break}case"$type":break;case"nullable":{t.notNull=!1;break}case"unique":{t.unique=!0;break}}return{...e,column:t}},b=new Set(["any","bigint","boolean","bytes","date","geoPoint","null","number","string","timestamp"]),g=new Set(["check","email","int","length","max","min","pattern","positive","url"]),N=new Set(["meta"]),c=new Set,S=e=>{const r=e.getSymbol();let t=(r?.getAliasedSymbol()??r)?.getValueDeclaration();if(t!==void 0&&i.isShorthandPropertyAssignment(t)){const n=t.getValueSymbol();t=(n?.getAliasedSymbol()??n)?.getValueDeclaration()}if(!(t===void 0||!i.isVariableDeclaration(t)))return t.getInitializer()},E="v",h=e=>{if(i.isIdentifier(e))return!0;let r=e;for(;i.isCallExpression(r);){const t=r.getExpression();if(!i.isPropertyAccessExpression(t))return!1;r=t.getExpression()}return i.isIdentifier(r)&&r.getText()===E},o=e=>{if(i.isIdentifier(e)&&!c.has(e)){const r=S(e);if(r!==void 0&&h(r)){c.add(e);try{return o(r)}finally{c.delete(e)}}}return i.isCallExpression(e)?w(e):{kind:"any",sourceText:e.getText()}},A=e=>{const r={};for(const t of e.getProperties()){const n=i.isShorthandPropertyAssignment(t);if(!n&&!i.isPropertyAssignment(t))continue;const s=t.getNameNode();if(i.isComputedPropertyName(s))continue;const a=n?t.getNameNode():t.getInitializer();if(!a)continue;const u=t.getName();if(!y.test(u))throw new p("INTERNAL",`@lunora/codegen: field name is not a valid JS identifier: ${JSON.stringify(u)}`);r[u]=o(a)}return r},l=(e,r)=>e&&i.isExpression(e)?o(e):r,v=e=>e===void 0?"undefined":i.isStringLiteral(e)||i.isNoSubstitutionTemplateLiteral(e)?JSON.stringify(e.getLiteralValue()):e.getText(),T=e=>{const r=e&&d?d(e):void 0;return r===void 0?{kind:"from"}:{kind:"from",tsType:r}},I=(e,r,t)=>{if(b.has(e))return{kind:e};const[n,s]=r;switch(e){case"array":return{inner:l(n,{kind:"any"}),kind:"array"};case"from":return T(n);case"id":{if(!n||!i.isStringLiteral(n))throw m(n??t,`v.id(...) target table must be a string literal — codegen resolves foreign-key targets statically. Got ${n?n.getText():"no argument"}.`);return{kind:"id",tableName:n.getLiteralText()}}case"literal":return{kind:"literal",literalValue:v(n)};case"object":return n&&i.isObjectLiteralExpression(n)?{kind:"object",shape:A(n)}:{kind:"object",shape:{}};case"optional":return{inner:l(n,{kind:"any"}),kind:"optional"};case"record":return{keyType:l(n,{kind:"string"}),kind:"record",valueType:l(s,{kind:"any"})};case"storage":return n&&i.isStringLiteral(n)?{bucket:n.getLiteralText(),kind:"storage"}:{kind:"storage"};case"union":return{kind:"union",members:r.filter(a=>i.isExpression(a)).map(a=>o(a))};default:throw new p("INTERNAL",`Unsupported validator kind: ${e}`)}},w=e=>{const r=e.getExpression();if(!i.isPropertyAccessExpression(r))return{kind:"any",sourceText:e.getText()};const t=r.getName(),n=e.getArguments();if(f.has(t)||g.has(t)||N.has(t)){const s=r.getExpression(),a=i.isExpression(s)?o(s):{kind:"any"};return f.has(t)?k(a,t):g.has(t)?{...a,hasRefinement:!0}:a}return I(t,n,e)};export{A as a,o as p,R as s};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a=/\/index$/u,s=/[^\dA-Za-z]/gu,c=e=>e.replace(a,"").replaceAll(s,"_");export{c as s};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Node as r,SyntaxKind as f}from"ts-morph";import{l as P,a as h,i as A}from"./ast-CjWtsS6S.mjs";const m=(t,e)=>{if(t.getText()!==e)return!1;const s=t.getParent();return r.isPropertyAccessExpression(s)&&s.getNameNode()===t?!1:!(r.isPropertyAssignment(s)&&s.getNameNode()===t)},x=(t,e)=>r.isIdentifier(t)?m(t,e):t.getDescendantsOfKind(f.Identifier).some(s=>m(s,e)),g=t=>x(t,"ctx"),I=t=>{let e=t;for(;r.isPropertyAccessExpression(e)||r.isElementAccessExpression(e)||r.isNonNullExpression(e);)e=e.getExpression();return r.isIdentifier(e)?e:void 0},E=t=>x(t,"args"),u=t=>{if(!r.isIdentifier(t))return;const e=t.getText(),s=t.getFirstAncestor(o=>r.isArrowFunction(o)||r.isFunctionExpression(o)||r.isFunctionDeclaration(o));if(s===void 0)return;const i=t.getStart();let n,a=-1;for(const o of s.getDescendantsOfKind(f.VariableDeclaration)){if(o.getName()!==e)continue;const c=o.getInitializer(),l=o.getStart();c!==void 0&&l<i&&l>a&&(n=c,a=l)}return n},C=t=>{if(E(t))return!0;const e=u(t);return e!==void 0&&E(e)},K=t=>{if(r.isCallExpression(t)||r.isNewExpression(t))return!1;const e=u(t);return e===void 0||!(r.isCallExpression(e)||r.isNewExpression(e))},O=t=>{if(g(t))return!0;const e=u(t);if(e!==void 0&&g(e))return!0;const s=e??t;return(r.isIdentifier(s)?[s]:s.getDescendantsOfKind(f.Identifier)).some(n=>{const a=u(n);return a!==void 0&&g(a)})},p=(t,e)=>x(t,e),T=(t,e)=>{if(p(t,e))return!0;const s=u(t);if(s!==void 0&&p(s,e))return!0;const i=I(t);if(i!==void 0){const n=u(i);return n!==void 0&&p(n,e)}return!1},v=t=>{for(const e of t.getAncestors())if(r.isVariableDeclaration(e)&&e.getVariableStatement()?.hasExportKeyword()===!0)return e.getName();return"<module>"},N=new Set(["withGeoIndex","withIndex","withSearchIndex"]),S=new Set(["collect","collectWithScores","first","paginate","take","unique"]),b=t=>{const e=t.getExpression();if(!r.isPropertyAccessExpression(e)||e.getName()!=="query")return!1;const s=e.getExpression();return A(s)},y=t=>{const e=[];let s=t;for(;;){const i=s.getParent();if(!i||!r.isPropertyAccessExpression(i))break;const n=i.getParent();if(!n||!r.isCallExpression(n))break;e.push(i.getName()),s=n}return e},D=/\b[A-Za-z_$][\w$]*\._id\s*===?[^=]/u,w=t=>{let e=t;for(;;){const s=e.getParent();if(!s||!r.isPropertyAccessExpression(s))return!1;const i=s.getParent();if(!i||!r.isCallExpression(i))return!1;if(s.getName()==="filter"){const n=i.getArguments()[0];if(n&&D.test(n.getText()))return!0}e=i}},R=t=>{const e=t.getArguments()[0];return e&&r.isStringLiteral(e)?e.getLiteralText():""},_=(t,e)=>{const s=[];for(const i of P(e)){const n=t.getSourceFile(i)??t.addSourceFileAtPath(i),a=h(e,i);for(const o of n.getDescendantsOfKind(f.CallExpression)){if(!b(o))continue;const c=y(o),l=c.includes("filter");s.push({exportName:v(o),file:a,filtersPrimaryKey:l&&w(o),hasFilter:l,hasIndex:c.some(d=>N.has(d)),line:o.getStartLineNumber(),table:R(o),terminal:c.findLast(d=>S.has(d))})}}return s};export{O as a,K as b,T as c,_ as d,v as e,p as f,C as i,E as r,u as s};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as r,readFileSync as a}from"node:fs";import{join as d}from"node:path";const m=o=>{const n=d(o,"package.json");if(r(n))try{const s=JSON.parse(a(n,"utf8")),t=new Set;for(const c of["dependencies","devDependencies","peerDependencies","optionalDependencies"]){const e=s[c];if(e!==null&&typeof e=="object")for(const i of Object.keys(e))t.add(i)}return t}catch{return}};export{m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s=/[\w+/=-]{40,}/u,n=/[a-z]/u,E=/[A-Z]/u,_=/\d/u,c=/\b(?:[\da-f]{32,}|[\dA-F]{32,})\b/u,o=t=>{const e=s.exec(t)?.[0];return e===void 0?!1:n.test(e)&&E.test(e)&&_.test(e)},i=t=>c.test(t),r=/\b(?:sk|rk)_live_[\dA-Za-z]{20,}/u,a=/\bAKIA[\dA-Z]{16}\b/u,R=/\bgh[posru]_[\dA-Za-z]{36,}/u,d=/\bsk-[\dA-Za-z]{32,}/u,A=/\bxox[abprs]-[\dA-Za-z-]{10,}/u,k=/-----BEGIN(?: [A-Z]+)? PRIVATE KEY-----/u,S=[{kind:"stripe_live_key",test:t=>r.test(t)},{kind:"aws_access_key",test:t=>a.test(t)},{kind:"github_token",test:t=>R.test(t)},{kind:"openai_key",test:t=>d.test(t)},{kind:"slack_token",test:t=>A.test(t)},{kind:"private_key",test:t=>k.test(t)},{kind:"high_entropy",test:o},{kind:"hex_secret",test:i}],u=new Set(["hex_secret","high_entropy"]),h=new Set(["auth","bearer","credential","credentials","hmac","key","keys","passphrase","password","private","secret","secrets","signature","signing","token"]),p=/([a-z\d])([A-Z])/gu,T=/[^A-Za-z\d]+/u,I=t=>t.replaceAll(p,"$1 $2").split(T).filter(Boolean).map(e=>e.toLowerCase()),l=t=>t!==void 0&&I(t).some(e=>h.has(e)),K=t=>S.find(e=>e.test(t))?.kind,b=t=>u.has(t),g=t=>`${t.slice(0,4)}…(${String(t.length)} chars)`;export{S as SECRET_RULES,b as isHeuristicSecretKind,l as isSecretishName,g as redact,K as secretKindOf};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s=e=>{try{return JSON.parse(e)}catch{const t=e.trim();return t.length>=2&&(t.startsWith("'")||t.startsWith('"'))&&t.at(-1)===t[0]?t.slice(1,-1):t}},n=e=>{const t={};return e.column!==void 0&&(t.column={defaultValue:e.column.hasDefault===!0?null:void 0,notNull:e.column.notNull,unique:e.column.unique}),e.inner!==void 0&&(t.inner=n(e.inner)),e.members!==void 0&&(t.members=e.members.map(a=>n(a))),e.shape!==void 0&&(t.shape=Object.fromEntries(Object.entries(e.shape).map(([a,l])=>[a,n(l)]))),e.tableName!==void 0&&(t.tableName=e.tableName),e.literalValue!==void 0&&(t.value=s(e.literalValue)),e.keyType!==void 0&&(t.keyValidator=n(e.keyType)),e.valueType!==void 0&&(t.valueValidator=n(e.valueType)),{_meta:t,kind:e.kind}},m=e=>({tables:Object.fromEntries(e.tables.map(a=>[a.name,{shape:Object.fromEntries(Object.entries(a.shape).map(([l,o])=>[l,n(o)]))}]))});export{m as schemaFromIr};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Node as l,SyntaxKind as f}from"ts-morph";import{posix as A}from"node:path";const j=/\bany\b(?!\s*(?:\?\s*)?:)/u,R=/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`/gu,k=e=>j.test(e.replaceAll(R,"")),w="/_generated/",U=e=>{const t=[e.getSymbol(),e.getAliasSymbol()].flatMap(n=>n?.getDeclarations()??[]);return t.length>0&&t.every(n=>n.getSourceFile().getSymbol()===void 0)},C=/^(?<quote>["'])(?<specifier>.*)\k<quote>$/su,D=e=>{for(const t of e.getAncestors())if(l.isModuleDeclaration(t)){const n=C.exec(t.getName());if(n?.groups?.specifier!==void 0)return n.groups.specifier}},y=new WeakMap,L=(e,t)=>{const n=e.getSymbol();if(n===void 0)return;let r=y.get(n.compilerSymbol);return r===void 0&&(r=new Map,y.set(n.compilerSymbol,r)),r.has(t)||r.set(t,n.getExport(t)??e.getExportSymbols().find(s=>s.getName()===t)),r.get(t)},N=(e,t)=>e.getNamespaceImport()!==void 0||e.getNamedImports().some(n=>n.getName()===t),O=(e,t,n)=>e.getModuleSpecifierValue()===t&&N(e,n)?n:void 0,$=(e,t)=>{const n=e.getDefaultImport();if(n===void 0)return;const r=n.getSymbol();return(r?.getAliasedSymbol()??r)?.getDeclarations().includes(t)===!0?"default":void 0},P=(e,t,n)=>{if(!N(e,n))return;const r=e.getModuleSpecifierSourceFile(),s=r===void 0?void 0:L(r,n);return(s?.getAliasedSymbol()??s)?.getDeclarations().includes(t)===!0?n:void 0},h=/^\.\.?(?:$|\/)/u,q=new Map([[".cjs",".cjs"],[".cts",".cjs"],[".d.ts",".js"],[".js",".js"],[".jsx",".jsx"],[".mjs",".mjs"],[".mts",".mjs"],[".ts",".js"],[".tsx",".js"]]),B=(e,t)=>{const n=t.getModuleSpecifierValue();if(!h.test(n))return;const r=t.getModuleSpecifierSourceFile(),s=r===void 0?void 0:q.get(r.getExtension());if(r===void 0||s===void 0)return;const o=`${A.join(r.getDirectoryPath(),r.getBaseNameWithoutExtension())}${s}`,i=A.relative(e.getDirectoryPath(),o);return i.startsWith(".")?i:`./${i}`},K=(e,t,n)=>{const r=D(t);for(const s of e.getImportDeclarations()){const o=r===void 0?$(s,t)??P(s,t,n):O(s,r,n);if(o!==void 0)return{exportName:o,specifier:B(e,s)??s.getModuleSpecifierValue()}}},V=(e,t)=>Object.keys(t.getProject().getCompilerOptions().paths??{}).some(n=>{const r=n.indexOf("*");return r===-1?e===n:e.startsWith(n.slice(0,r))&&e.endsWith(n.slice(r+1))}),g={kind:"verbatim"},d={kind:"expand"},F=new Set([f.ClassDeclaration,f.EnumDeclaration,f.EnumMember,f.InterfaceDeclaration,f.TypeAliasDeclaration]),x=(e,t,n)=>{const r=e.getSourceFile();if(r.getSymbol()===void 0&&D(e)===void 0||!F.has(e.getKind()))return g;const s=r.getFilePath();if(s.includes(w))return g;if(s===n)return d;const o=l.isEnumMember(e)?e.getParent():e;if(!l.hasName(o))return d;const i=K(t.getSourceFile(),o,o.getName());return i===void 0?g:V(i.specifier,t)?d:{kind:"qualify",qualified:i}},I=(e,t,n)=>{const r=e.getAliasSymbol(),s=e.getSymbol(),o=new Set((r??s)?.getDeclarations());let i=!1;for(const a of[s,r].flatMap(c=>c?.getDeclarations()??[])){const c=x(a,t,n);if(c.kind==="qualify"&&o.has(a))return c;i||=c.kind!=="verbatim"}return i?d:g},W=(e,t,n)=>{const r=l.isPropertySignature(e)||l.isPropertyDeclaration(e)?e.getTypeNode():void 0;if(r===void 0)return g;let s=!1;for(const o of[r,...r.getDescendantsOfKind(f.TypeReference)].filter(i=>l.isTypeReference(i))){const i=o.getTypeName().getSymbol();for(const a of(i?.getAliasedSymbol()??i)?.getDeclarations()??[]){const c=x(a,t,n);if(c.kind==="qualify")return c;s||=c.kind!=="verbatim"}}return s?d:g},G=/^[A-Za-z_$][\w$]*$/u,X=e=>G.test(e)?e:JSON.stringify(e),M=e=>{const t=[...e.getTypeArguments()];return e.isUnion()&&t.push(...e.getUnionTypes()),e.isIntersection()&&t.push(...e.getIntersectionTypes()),t},E=e=>!e.isObject()||e.isArray()||e.isTuple()||e.getCallSignatures().length>0||e.getConstructSignatures().length>0?!1:e.getStringIndexType()===void 0&&e.getNumberIndexType()===void 0,b=(e,t,n,r=new Set)=>r.has(e)?!1:(r.add(e),I(e,t,n).kind!=="verbatim"||M(e).some(s=>b(s,t,n,r))?!0:E(e)?e.getProperties().some(s=>s.getDeclarations().some(o=>W(o,t,n).kind!=="verbatim")?!0:b(s.getTypeAtLocation(t),t,n,r)):!1),H=(e,t)=>{const n=e.getValueDeclaration()??e.getDeclarations()[0];return n&&(l.isPropertySignature(n)||l.isPropertyDeclaration(n))&&n.hasQuestionToken()?!0:t.isUnion()&&t.getUnionTypes().some(r=>r.isUndefined())},Y=32,J=8,z=(e,t,n,r,s,o)=>{const i=e.getArrayElementType(),a=i?o(i,t,n,r,s):void 0;if(a!==void 0)return i?.isUnion()?`(${a})[]`:`${a}[]`},Q=(e,t,n,r,s,o)=>{const i=[];for(const a of e.getUnionTypes()){const c=o(a,t,n,r,s);if(c===void 0)return;i.push(c)}return i.join(" | ")},Z=(e,t,n,r,s,o)=>{if(!E(e))return;const i=[];for(const a of e.getProperties()){const c=a.getTypeAtLocation(t),u=H(a,c),_=u&&c.isUnion()?c.getUnionTypes().filter(v=>!v.isUndefined()):[c],T=[];for(const v of _){const p=o(v,t,n,r+1,s);if(p===void 0)return;T.push(p)}i.push(`${X(a.getName())}${u?"?":""}: ${T.join(" | ")}`)}return i.length>0?`{ ${i.join("; ")} }`:"{}"},ee=e=>{const t=e.getLiteralValue();return typeof t=="string"?JSON.stringify(t):typeof t=="number"?String(t):void 0},te=e=>[e.getSymbol(),e.getAliasSymbol()].flatMap(t=>t?.getDeclarations()??[]).some(t=>l.isClassDeclaration(t)||l.isClassExpression(t)),S=(e,t,n,r,s=new Set)=>{if(r.has(e)||s.has(e))return!1;if(n>Y)return!0;const o=new Set(r).add(e);if(M(e).some(u=>S(u,t,n+1,o,s)))return!0;const i=e.getArrayElementType();if(i!==void 0)return S(i,t,n+1,o,s);if(U(e))return s.add(e),!1;if(e.getCallSignatures().length>0||e.getConstructSignatures().length>0||[e.getSymbol(),e.getAliasSymbol()].flatMap(u=>u?.getDeclarations()??[]).some(u=>l.isClassDeclaration(u)||l.isClassExpression(u)))return!0;const c=E(e)&&e.getProperties().some(u=>S(u.getTypeAtLocation(t),t,n+1,o,s));return c||s.add(e),c},ne=(e,t,n,r,s,o,i)=>{const a=[];for(const c of t.getAliasSymbol()===void 0?t.getTypeArguments():t.getAliasTypeArguments()){const u=i(c,n,r,s+1,o);if(u===void 0)return;a.push(u)}return`import("${e.specifier}").${e.exportName}${a.length>0?`<${a.join(", ")}>`:""}`},re=e=>[e.getSymbol(),e.getAliasSymbol()].flatMap(t=>t?.getDeclarations()??[]).some(t=>l.isEnumDeclaration(t)||l.isEnumMember(t)),m=(e,t,n,r,s)=>{if(r>J||s.has(e))return;const o=I(e,t,n);if(o.kind==="verbatim"&&!b(e,t,n))return e.getText(t);const i=new Set(s).add(e);if(!te(e)){if(e.isEnumLiteral())return ee(e);if(o.kind==="qualify"&&!re(e)){const a=ne(o.qualified,e,t,n,r,i,m);if(a!==void 0)return a}return e.isArray()?z(e,t,n,r,i,m):e.isUnion()?Q(e,t,n,r,i,m):Z(e,t,n,r,i,m)}},oe=e=>{const t=e.getType().getCallSignatures()[0];if(!t)return"unknown";let n=t.getReturnType();const s=(n.getSymbol()??n.getAliasSymbol())?.getName();if(s==="Promise"||s==="AsyncIterable"||s==="AsyncIterableIterator"||s==="AsyncGenerator"){const a=n.getTypeArguments()[0];a&&(n=a)}const o=n.getText(e);if(!o||o==="any"||o==="never"||k(o)||S(n,e,0,new Set))return"unknown";const i=e.getSourceFile().getFilePath();return b(n,e,i)?m(n,e,i,0,new Set)??"unknown":o};export{m as e,k as i,b as r,oe as u};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/codegen",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.140",
|
|
4
4
|
"description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -46,14 +46,23 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/advisor": "1.0.0-alpha.
|
|
50
|
-
"@lunora/
|
|
51
|
-
"@lunora/
|
|
52
|
-
"@lunora/
|
|
53
|
-
"@lunora/
|
|
54
|
-
"@lunora/
|
|
49
|
+
"@lunora/advisor": "1.0.0-alpha.99",
|
|
50
|
+
"@lunora/agent": "1.0.0-alpha.74",
|
|
51
|
+
"@lunora/container": "1.0.0-alpha.37",
|
|
52
|
+
"@lunora/errors": "1.0.0-alpha.26",
|
|
53
|
+
"@lunora/platform": "1.0.0-alpha.21",
|
|
54
|
+
"@lunora/queue": "1.0.0-alpha.38",
|
|
55
|
+
"@lunora/scheduler": "1.0.0-alpha.44",
|
|
56
|
+
"@lunora/values": "1.0.0-alpha.33",
|
|
57
|
+
"@lunora/workflow": "1.0.0-alpha.37",
|
|
58
|
+
"jsonc-parser": "^3.3.1",
|
|
59
|
+
"quicktype-core": "^26.0.0",
|
|
55
60
|
"ts-morph": "^28.0.0"
|
|
56
61
|
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"@lunora/server": ">=1.0.0-alpha.91 <2.0.0-0",
|
|
64
|
+
"@lunora/shard-engine": ">=1.0.0-alpha.45 <2.0.0-0"
|
|
65
|
+
},
|
|
57
66
|
"engines": {
|
|
58
67
|
"node": "^22.15.0 || >=24.11.0"
|
|
59
68
|
}
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { containerClassName, containerBindingName, normalizeContainerImage } from '@lunora/container';
|
|
4
|
-
import { SyntaxKind, Node } from 'ts-morph';
|
|
5
|
-
import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
|
|
6
|
-
|
|
7
|
-
const CONTAINERS_FILENAME = "containers.ts";
|
|
8
|
-
const isDefineContainer = (identifier) => {
|
|
9
|
-
const symbol = identifier.getSymbol();
|
|
10
|
-
if (!symbol) {
|
|
11
|
-
return identifier.getText() === "defineContainer";
|
|
12
|
-
}
|
|
13
|
-
for (const declaration of symbol.getDeclarations()) {
|
|
14
|
-
if (!Node.isImportSpecifier(declaration)) {
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
if (declaration.getImportDeclaration().getModuleSpecifierValue() !== "@lunora/container") {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
return declaration.getNameNode().getText() === "defineContainer";
|
|
21
|
-
}
|
|
22
|
-
return false;
|
|
23
|
-
};
|
|
24
|
-
const stringProperty = (expression, exportName, property) => {
|
|
25
|
-
if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
|
|
26
|
-
return expression.getLiteralValue();
|
|
27
|
-
}
|
|
28
|
-
throw diagnosticAt(
|
|
29
|
-
expression,
|
|
30
|
-
`container "${exportName}": \`${property}\` must be a static string literal — it is deploy configuration codegen writes into wrangler.jsonc`
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
const numberProperty = (expression, exportName, property) => {
|
|
34
|
-
if (Node.isNumericLiteral(expression)) {
|
|
35
|
-
return expression.getLiteralValue();
|
|
36
|
-
}
|
|
37
|
-
throw diagnosticAt(
|
|
38
|
-
expression,
|
|
39
|
-
`container "${exportName}": \`${property}\` must be a static number literal — it is deploy configuration codegen writes into wrangler.jsonc`
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
const imageFromExpression = (expression, exportName) => {
|
|
43
|
-
if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
|
|
44
|
-
return normalizeContainerImage(expression.getLiteralValue());
|
|
45
|
-
}
|
|
46
|
-
if (Node.isObjectLiteralExpression(expression)) {
|
|
47
|
-
const registry = expression.getProperty("registry");
|
|
48
|
-
if (registry && Node.isPropertyAssignment(registry)) {
|
|
49
|
-
const initializer = registry.getInitializerOrThrow();
|
|
50
|
-
return normalizeContainerImage({ registry: stringProperty(initializer, exportName, "image.registry") });
|
|
51
|
-
}
|
|
52
|
-
const build = expression.getProperty("build");
|
|
53
|
-
if (build && Node.isPropertyAssignment(build)) {
|
|
54
|
-
const initializer = build.getInitializerOrThrow();
|
|
55
|
-
return normalizeContainerImage({ build: stringProperty(initializer, exportName, "image.build") });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
throw diagnosticAt(expression, `container "${exportName}": \`image\` must be a static string path, { registry: "…" }, or { build: "…" } literal`);
|
|
59
|
-
};
|
|
60
|
-
const stringRecordLiteral = (expression) => {
|
|
61
|
-
if (!Node.isObjectLiteralExpression(expression)) {
|
|
62
|
-
return void 0;
|
|
63
|
-
}
|
|
64
|
-
const record = {};
|
|
65
|
-
for (const property of expression.getProperties()) {
|
|
66
|
-
if (!Node.isPropertyAssignment(property)) {
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
const value = property.getInitializerOrThrow();
|
|
70
|
-
if (Node.isStringLiteral(value) || Node.isNoSubstitutionTemplateLiteral(value)) {
|
|
71
|
-
record[property.getName()] = value.getLiteralValue();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return Object.keys(record).length > 0 ? record : void 0;
|
|
75
|
-
};
|
|
76
|
-
const rolloutLiteral = (expression) => {
|
|
77
|
-
if (!Node.isObjectLiteralExpression(expression)) {
|
|
78
|
-
return void 0;
|
|
79
|
-
}
|
|
80
|
-
const rollout = {};
|
|
81
|
-
for (const property of expression.getProperties()) {
|
|
82
|
-
if (!Node.isPropertyAssignment(property)) {
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
const key = property.getName();
|
|
86
|
-
const value = property.getInitializerOrThrow();
|
|
87
|
-
if (Node.isNumericLiteral(value) && (key === "gracePeriodSeconds" || key === "stepPercentage")) {
|
|
88
|
-
rollout[key] = value.getLiteralValue();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return rollout.gracePeriodSeconds === void 0 && rollout.stepPercentage === void 0 ? void 0 : rollout;
|
|
92
|
-
};
|
|
93
|
-
const booleanLiteral = (expression) => {
|
|
94
|
-
if (Node.isTrueLiteral(expression)) {
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
if (Node.isFalseLiteral(expression)) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
return void 0;
|
|
101
|
-
};
|
|
102
|
-
const stringOrNumberLiteral = (expression) => {
|
|
103
|
-
if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
|
|
104
|
-
return expression.getLiteralValue();
|
|
105
|
-
}
|
|
106
|
-
if (Node.isNumericLiteral(expression)) {
|
|
107
|
-
return expression.getLiteralValue();
|
|
108
|
-
}
|
|
109
|
-
return void 0;
|
|
110
|
-
};
|
|
111
|
-
const instanceTypeFromExpression = (expression, exportName) => {
|
|
112
|
-
if (Node.isStringLiteral(expression)) {
|
|
113
|
-
return expression.getLiteralValue();
|
|
114
|
-
}
|
|
115
|
-
if (Node.isObjectLiteralExpression(expression)) {
|
|
116
|
-
const custom = {};
|
|
117
|
-
for (const property of expression.getProperties()) {
|
|
118
|
-
if (!Node.isPropertyAssignment(property)) {
|
|
119
|
-
throw diagnosticAt(property, `container "${exportName}": \`instanceType\` must be an object of static number literals`);
|
|
120
|
-
}
|
|
121
|
-
const key = property.getName();
|
|
122
|
-
if (key !== "diskMb" && key !== "memoryMib" && key !== "vcpu") {
|
|
123
|
-
throw diagnosticAt(property, `container "${exportName}": unknown \`instanceType\` field "${key}" — expected vcpu, memoryMib, or diskMb`);
|
|
124
|
-
}
|
|
125
|
-
custom[key] = numberProperty(property.getInitializerOrThrow(), exportName, `instanceType.${key}`);
|
|
126
|
-
}
|
|
127
|
-
return custom;
|
|
128
|
-
}
|
|
129
|
-
throw diagnosticAt(expression, `container "${exportName}": \`instanceType\` must be a static string or { vcpu, memoryMib, diskMb } literal`);
|
|
130
|
-
};
|
|
131
|
-
const containerFromCall = (call, exportName) => {
|
|
132
|
-
const argument = call.getArguments()[0];
|
|
133
|
-
if (!argument || !Node.isObjectLiteralExpression(argument)) {
|
|
134
|
-
throw diagnosticAt(call, `container "${exportName}": defineContainer must be passed an inline object literal`);
|
|
135
|
-
}
|
|
136
|
-
const ir = {
|
|
137
|
-
bindingName: containerBindingName(exportName),
|
|
138
|
-
className: containerClassName(exportName),
|
|
139
|
-
exportName,
|
|
140
|
-
image: { buildContext: ".", dockerfilePath: "./Dockerfile", kind: "dockerfile" }
|
|
141
|
-
};
|
|
142
|
-
let sawImage = false;
|
|
143
|
-
for (const property of argument.getProperties()) {
|
|
144
|
-
if (!Node.isPropertyAssignment(property)) {
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
const key = property.getName();
|
|
148
|
-
const initializer = property.getInitializerOrThrow();
|
|
149
|
-
switch (key) {
|
|
150
|
-
case "buildArgs": {
|
|
151
|
-
ir.buildArgs = stringRecordLiteral(initializer);
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
case "enableInternet": {
|
|
155
|
-
ir.enableInternet = booleanLiteral(initializer);
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case "image": {
|
|
159
|
-
ir.image = imageFromExpression(initializer, exportName);
|
|
160
|
-
sawImage = true;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
case "instanceType": {
|
|
164
|
-
ir.instanceType = instanceTypeFromExpression(initializer, exportName);
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
case "maxInstances": {
|
|
168
|
-
ir.maxInstances = numberProperty(initializer, exportName, "maxInstances");
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
case "name": {
|
|
172
|
-
ir.name = stringProperty(initializer, exportName, "name");
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
case "rollout": {
|
|
176
|
-
ir.rollout = rolloutLiteral(initializer);
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
case "sleepAfter": {
|
|
180
|
-
ir.sleepAfter = stringOrNumberLiteral(initializer);
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (!sawImage) {
|
|
186
|
-
throw diagnosticAt(argument, `container "${exportName}": defineContainer requires a static \`image\` property`);
|
|
187
|
-
}
|
|
188
|
-
return ir;
|
|
189
|
-
};
|
|
190
|
-
const containersFromSource = (source) => {
|
|
191
|
-
const containers = [];
|
|
192
|
-
for (const declaration of source.getVariableDeclarations()) {
|
|
193
|
-
if (!declaration.isExported()) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
const initializer = declaration.getInitializer();
|
|
197
|
-
if (initializer?.getKind() !== SyntaxKind.CallExpression) {
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
const call = initializer;
|
|
201
|
-
const callee = call.getExpression();
|
|
202
|
-
if (!Node.isIdentifier(callee) || !isDefineContainer(callee)) {
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
const nameNode = declaration.getNameNode();
|
|
206
|
-
if (!Node.isIdentifier(nameNode)) {
|
|
207
|
-
throw diagnosticAt(nameNode, "defineContainer exports must be plain named exports (no destructuring)");
|
|
208
|
-
}
|
|
209
|
-
containers.push(containerFromCall(call, nameNode.getText()));
|
|
210
|
-
}
|
|
211
|
-
return containers;
|
|
212
|
-
};
|
|
213
|
-
const discoverContainers = (project, lunoraDirectory) => {
|
|
214
|
-
const containersPath = join(lunoraDirectory, CONTAINERS_FILENAME);
|
|
215
|
-
if (!existsSync(containersPath)) {
|
|
216
|
-
return [];
|
|
217
|
-
}
|
|
218
|
-
const source = project.getSourceFile(containersPath) ?? project.addSourceFileAtPath(containersPath);
|
|
219
|
-
const containers = containersFromSource(source);
|
|
220
|
-
containers.sort((a, b) => a.exportName.localeCompare(b.exportName));
|
|
221
|
-
return containers;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
export { CONTAINERS_FILENAME, discoverContainers };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
class CodegenDiagnosticError extends Error {
|
|
2
|
-
column;
|
|
3
|
-
file;
|
|
4
|
-
line;
|
|
5
|
-
constructor(message, file, line, column) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.name = "CodegenDiagnosticError";
|
|
8
|
-
this.file = file;
|
|
9
|
-
this.line = line;
|
|
10
|
-
this.column = column;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
const diagnosticAt = (node, detail, meta) => {
|
|
14
|
-
const sourceFile = node.getSourceFile();
|
|
15
|
-
const file = sourceFile.getFilePath();
|
|
16
|
-
const line = node.getStartLineNumber();
|
|
17
|
-
const { column } = sourceFile.getLineAndColumnAtPos(node.getStart());
|
|
18
|
-
const message = `@lunora/codegen: ${detail} (${file}:${line.toString()}:${column.toString()})`;
|
|
19
|
-
const error = new CodegenDiagnosticError(message, file, line, column);
|
|
20
|
-
return meta ? Object.assign(error, meta) : error;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export { CodegenDiagnosticError, diagnosticAt };
|