@lunora/codegen 1.0.0-alpha.23 → 1.0.0-alpha.230
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/README.md +1 -1
- package/dist/index.d.mts +3344 -1166
- package/dist/index.d.ts +3344 -1166
- package/dist/index.mjs +1 -34
- package/dist/packem_shared/AGENTS_FILENAME-DoPI92Wu.mjs +1 -0
- package/dist/packem_shared/CONTAINERS_FILENAME-B6TFs82W.mjs +1 -0
- package/dist/packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs +1 -0
- package/dist/packem_shared/DEFAULT_TARGET-kmm2i4Fw.mjs +1 -0
- package/dist/packem_shared/FLAGS_FILENAME-BedPDCsR.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-Cfw75xC4.mjs +1 -0
- package/dist/packem_shared/LUNORA_ERROR_CODES-C2s0xWQD.mjs +1 -0
- package/dist/packem_shared/MUTATORS_FILENAME-B6cKrN_m.mjs +1 -0
- package/dist/packem_shared/NOTIFY_FILENAME-Cri3NT5U.mjs +1 -0
- package/dist/packem_shared/OPENRPC_VERSION-DDd0VJyT.mjs +3 -0
- package/dist/packem_shared/PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs +1 -0
- package/dist/packem_shared/QUEUES_FILENAME-CxkPcMH1.mjs +1 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-Cssrg7G6.mjs +9 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs +2 -0
- package/dist/packem_shared/SDK_LANGUAGES-Df_CnJx5.mjs +372 -0
- package/dist/packem_shared/SHAPES_FILENAME-zJgzynXR.mjs +1 -0
- package/dist/packem_shared/SchemaSnapshotParseError-lUWe6lPo.mjs +18 -0
- package/dist/packem_shared/WORKFLOWS_FILENAME-B_ZJxRSx.mjs +1 -0
- package/dist/packem_shared/buildOpenApiDocument-D6SBl-tk.mjs +3 -0
- package/dist/packem_shared/chain-H2N_uKgj.mjs +1 -0
- package/dist/packem_shared/classify-procedure-call-BztLe76A.mjs +1 -0
- package/dist/packem_shared/context-property-calls-CjDzLU8p.mjs +1 -0
- package/dist/packem_shared/declared-output-Iaar469J.mjs +1 -0
- package/dist/packem_shared/describeErrorLevelFindings-D23VSkFP.mjs +1 -0
- package/dist/packem_shared/discoverAuthApiCalls-FxrdBeVt.mjs +1 -0
- package/dist/packem_shared/discoverCrons-MfKw7IFf.mjs +1 -0
- package/dist/packem_shared/discoverFunctions-BsmX-sEq.mjs +1 -0
- package/dist/packem_shared/discoverHttpRoutes-BcXI9CNt.mjs +1 -0
- package/dist/packem_shared/discoverHyperdriveCalls-D9qXqTq3.mjs +1 -0
- package/dist/packem_shared/discoverInserts-CFJ3IVeI.mjs +1 -0
- package/dist/packem_shared/discoverMaskProcedures-CV_Cc2_g.mjs +1 -0
- package/dist/packem_shared/discoverMigrations-DbrHwcGE.mjs +1 -0
- package/dist/packem_shared/discoverNondeterministicCalls-CSQ_GDcA.mjs +1 -0
- package/dist/packem_shared/discoverQueries-C7y8i_Ga.mjs +1 -0
- package/dist/packem_shared/discoverR2sqlCalls-fu7fC0i_.mjs +1 -0
- package/dist/packem_shared/discoverRlsMetadata-CPmAGL0W.mjs +1 -0
- package/dist/packem_shared/discoverRlsProcedures-BO4qC77y.mjs +1 -0
- package/dist/packem_shared/discoverSandboxUsage-CgmfgDTS.mjs +1 -0
- package/dist/packem_shared/discoverSchema-D8DBDHEg.mjs +1 -0
- package/dist/packem_shared/discoverStorageRulesMetadata-D8VYflWt.mjs +1 -0
- package/dist/packem_shared/emit-D_prE7y6.mjs +2691 -0
- package/dist/packem_shared/emitApp-rCWsXXGd.mjs +853 -0
- package/dist/packem_shared/exported-procedure-chains-CmCDiPBV.mjs +1 -0
- package/dist/packem_shared/formatAdvisories-DwmUKYuc.mjs +2 -0
- package/dist/packem_shared/index-BoaHhVtM.mjs +1 -0
- package/dist/packem_shared/isD1GlobalTable-udvHAAzD.mjs +1 -0
- package/dist/packem_shared/isTypedSchema-CKzc3ioR.mjs +4 -0
- package/dist/packem_shared/listLunoraSourceFiles-DP-5e-RE.mjs +1 -0
- package/dist/packem_shared/loadProjectConfig-CKsFNgn3.mjs +1 -0
- package/dist/packem_shared/module-specifiers-WF8iAydP.mjs +1 -0
- package/dist/packem_shared/parse-validator-C94Yiabo.mjs +1 -0
- package/dist/packem_shared/paths-C-9fwEgQ.mjs +1 -0
- package/dist/packem_shared/queries-B-f4jO-x.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-CoV_GK33.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/FLAGS_FILENAME-B1vE0LIo.mjs +0 -139
- package/dist/packem_shared/GENERATED_HEADER-DUkXYD5R.mjs +0 -3260
- 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/MUTATORS_FILENAME-BhqdPtKp.mjs +0 -81
- package/dist/packem_shared/OPENRPC_VERSION-CjBUaolx.mjs +0 -60
- package/dist/packem_shared/QUEUES_FILENAME-B5_eWCRe.mjs +0 -119
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BUcGCXi3.mjs +0 -1130
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs +0 -245
- package/dist/packem_shared/SHAPES_FILENAME-ChV7MqgE.mjs +0 -94
- package/dist/packem_shared/WORKFLOWS_FILENAME-CCisG0Vy.mjs +0 -124
- package/dist/packem_shared/buildOpenApiDocument-WxYTLh11.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-KYq55qu3.mjs +0 -864
- package/dist/packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs +0 -97
- package/dist/packem_shared/emitApp-DD0i1ks0.mjs +0 -666
- package/dist/packem_shared/formatAdvisories-DdjK7sgh.mjs +0 -81
- 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-BztLe76A.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 i}from"@lunora/advisor";const d=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}))],l=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},m=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:l(e),fields:Object.keys(e.shape),indexes:d(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})),u=n=>n.map(e=>({exportName:e.exportName,file:`lunora/${e.filePath}.ts`,line:e.line,owner:e.owner})),f=n=>{const{argumentValidators:e,mutators:r,queries:s,schema:t,shapes:o,...a}=n;return{...a,argValidators:e,mutators:r===void 0?void 0:u(r),queries:s??[],schema:m(t),shapes:o===void 0?void 0:c(o)}},p=n=>i(f(n),{source:"static"}),v=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{v as formatAdvisories,p as lintSchema,f as toAdvisorContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Node as r}from"ts-morph";import{propertyKeyName as f,listLunoraSourceFiles as m,lunoraRelativePath as p,tablesAccessedIn as d}from"./listLunoraSourceFiles-DP-5e-RE.mjs";import{w as g,c as h}from"./classify-procedure-call-BztLe76A.mjs";const u=e=>{if(!(!r.isPropertyAssignment(e)&&!r.isShorthandPropertyAssignment(e)&&!r.isMethodDeclaration(e)&&!r.isGetAccessorDeclaration(e)))return f(e)},k=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"},v=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},P=e=>{const t=k(e);return{maskColumns:t.flatMap(s=>v(s)),usesMask:t.length>0}},y=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=h(s);if(!i)return;const n=i.receiver?P(i.receiver):{maskColumns:[],usesMask:!1},{tablesRead:o,tablesWritten:a}=d(e,y,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 m(t)){const n=e.getSourceFile(i)??e.addSourceFileAtPath(i),o=p(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,k as m,x as s};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=l=>l.shardMode==="global"&&l.globalBackend!=="hyperdrive",o=l=>l.shardMode==="global"&&l.globalBackend==="hyperdrive";export{e as isD1GlobalTable,o as isHyperdriveGlobalTable};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const g=/[^a-zA-Z0-9]+/gu,T=/([a-z0-9])([A-Z])/gu,p=t=>t.split(g).filter(e=>e.length>0).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),R=t=>t.replaceAll(T,"$1_$2").replaceAll(g,"_").toLowerCase(),d=t=>t===void 0?!1:["$ref","allOf","anyOf","enum","items","oneOf","properties","type"].some(e=>e in t),j=t=>t==="query"?"query":t==="action"?"action":"mutation",l=(t,e=0)=>{if(e>32||t===null||typeof t!="object")return!1;if(Array.isArray(t))return t.some(o=>l(o,e+1));const n=t;if(n.format==="int64"&&(n.type===void 0||n.type==="string")||n.type==="string"&&n.contentEncoding==="base64")return!0;const{properties:r}=n;return r!==null&&typeof r=="object"&&Object.values(r).some(o=>l(o,e+1))?!0:["additionalProperties","allOf","anyOf","items","oneOf"].some(o=>l(n[o],e+1))},I=t=>t.replaceAll(/[\n\r\u2028\u2029]+/gu," ").replaceAll("*/","* /").replaceAll('"""','" ""'),E=t=>t.replaceAll("\\","\\\\").replaceAll('"','\\"').replaceAll(`
|
|
2
|
+
`,"\\n").replaceAll("\r","\\r"),C=["$","{","'","$","'","}"].join(""),x=t=>E(t).split("$").join(C),z=(t,e)=>t.argsType!==void 0?e.typed(t.argsType):t.takesArgs?e.untyped:e.none,f=32,b=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return!1;const n=t;return n.type==="null"||Array.isArray(n.type)&&n.type.includes("null")?!0:["anyOf","oneOf"].some(r=>{const o=n[r];return Array.isArray(o)&&o.some(s=>b(s,e+1))})},N=(t,e,n)=>e.length===0?n===0?[]:[t]:e.map(r=>({properties:{...t.properties,...r.properties},required:new Set([...t.required,...r.required])})),P=t=>{const{properties:e}=t;if(e===null||typeof e!="object")return[];const n=t.required;return[{properties:e,required:new Set(Array.isArray(n)?n.filter(r=>typeof r=="string"):[])}]},m=(t,e,n)=>{const r=t[e];return Array.isArray(r)?r.flatMap(o=>A(o,n+1)):[]},A=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return[];const n=t,r=[...P(n),...m(n,"allOf",e)],o={properties:Object.assign({},...r.map(a=>a.properties)),required:new Set(r.flatMap(a=>[...a.required]))},s=[...m(n,"anyOf",e),...m(n,"oneOf",e)];return N(o,s,r.length)},w=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return[];const n=t,r=[n];for(const o of["anyOf","oneOf","allOf"]){const s=n[o];if(Array.isArray(s))for(const a of s)r.push(...w(a,e+1))}return r},y=(t,e,n,r=0)=>{if(r>f||t===null||typeof t!="object")return;const o=A(t),s=[...new Set(o.flatMap(a=>Object.keys(a.properties)))].toSorted((a,c)=>a.localeCompare(c));for(const a of s){const c=[...e,a],u=o.every(i=>i.required.has(a)),h=o.map(i=>i.properties[a]).filter(i=>i!==void 0);u?h.some(i=>b(i))&&n.nullable.push(c):n.optional.push(c);for(const i of h)y(i,c,n,r+1)}for(const a of w(t))for(const c of["additionalProperties","items"]){const u=a[c];u!==null&&typeof u=="object"&&y(u,[...e,"*"],n,r+1)}},k=(t,e)=>t.join("\0").localeCompare(e.join("\0")),q=t=>{const e={nullable:[],optional:[]};y(t,[],e);const n=r=>[...new Map(r.map(o=>[o.join("\0"),o])).values()].toSorted(k);return{nullable:n(e.nullable),optional:n(e.optional)}},$=t=>{const[e="",n=""]=t.name.split(":"),r=`${p(e)}${p(n)}`,o=t.params?.[0]?.schema,s=t.result?.schema;return{argsNullPaths:q(o),argsType:d(o)&&!l(o)?`${r}Args`:void 0,takesArgs:d(o),functionName:n,functionPath:t.name,namespace:e,resultType:d(s)&&!l(s)?`${r}Result`:void 0,summary:t.summary??t.name,verb:j(t["x-lunora-function-kind"])}},H=t=>{const e=new Map;for(const n of t.methods){const r=$(n),o=e.get(r.namespace);o===void 0?e.set(r.namespace,[r]):o.push(r)}return[...e.entries()].toSorted(([n],[r])=>n.localeCompare(r)).map(([n,r])=>({methods:r.toSorted((o,s)=>o.functionName.localeCompare(s.functionName)),name:n}))},U=t=>t.methods.flatMap(e=>{const n=$(e);return[{name:n.argsType,schema:e.params?.[0]?.schema},{name:n.resultType,schema:e.result?.schema}]}).filter(e=>e.name!==void 0&&e.schema!==void 0).toSorted((e,n)=>e.name.localeCompare(n.name)),L=/^[A-Za-z][A-Za-z0-9]*$/u,S=t=>L.test(t),D=t=>{const e=new Map;for(const n of t.methods){const r=p(n.functionName);if(!S(r))throw new Error(`sdk: function "${n.functionPath}" produces the invalid identifier "${r}" — rename the export so it starts with a letter.`);const o=n.verb==="query"?[r,`Subscribe${r}`,`Watch${r}`]:[r];for(const s of o){const a=e.get(s);if(a!==void 0){const c=s.startsWith("Watch")?' (the Dart target emits a "watch" Stream member for every query)':"";throw new Error(`sdk: functions "${a}" and "${n.functionPath}" both generate "${s}"${c} — rename one so the generated methods stay distinct.`)}e.set(s,n.functionPath)}}},W=t=>{const e=new Map;for(const n of t){const r=p(n.name);if(!S(r))throw new Error(`sdk: namespace "${n.name}" produces the invalid identifier "${r}" — rename the file so it starts with a letter.`);const o=e.get(r);if(o!==void 0)throw new Error(`sdk: namespaces "${o}" and "${n.name}" both generate "${r}" — rename one so the generated types stay distinct.`);e.set(r,n.name),D(n)}},Z=(t,e,n)=>{for(const r of t){const o=new Map;for(const s of r.methods)for(const a of n(s)){const c=o.get(a);if(c!==void 0&&c!==s.functionPath)throw new Error(`sdk: functions "${c}" and "${s.functionPath}" both generate the ${e} member "${a}" — rename one so the generated methods stay distinct.`);o.set(a,s.functionPath)}}},M=t=>t.flatMap(e=>e.methods),F=t=>[`GENERATED by \`lunora sdk generate --lang ${t}\` — do not edit.`,"Run the command again to regenerate."],_=/^\s*(?:#|\/\/|\/\*|\*)/u,v=t=>t.split(`
|
|
3
|
+
`).filter(e=>!_.test(e)).join(`
|
|
4
|
+
`),O=(t,e)=>new RegExp(String.raw`\b${e}\b`,"u").test(t),G=(t,e)=>{const n=v(e),r=o=>o!==void 0&&O(n,o)?o:void 0;return t.map(o=>({methods:o.methods.map(s=>({...s,argsType:r(s.argsType),resultType:r(s.resultType)})),name:o.name}))},B=t=>t.methods.filter(e=>l(e.params?.[0]?.schema)||l(e.result?.schema)).map(e=>e.name).toSorted((e,n)=>e.localeCompare(n)),V=(t,e)=>{const n=v(e);return[...new Set(M(t).flatMap(r=>[r.argsType,r.resultType]).filter(r=>r!==void 0&&!O(n,r)))].toSorted((r,o)=>r.localeCompare(o))},K=t=>[...new Set(M(t).flatMap(e=>[e.argsType,e.resultType]).filter(e=>e!==void 0))].toSorted((e,n)=>e.localeCompare(n));export{M as allMethods,z as argsChoice,Z as assertDistinctMembers,W as assertGeneratable,I as commentText,F as generatedHeaderLines,l as hasUnrepresentableWireType,d as isTypedSchema,x as kotlinLiteral,U as modelSources,q as nullPathsOf,$ as parseMethod,H as parseSpec,K as referencedModels,E as stringLiteral,p as toPascalCase,R as toSnakeCase,V as undeclaredModels,B as unrepresentableFunctions,j as verbForKind,G as withDeclaredModels};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readdirSync as x,realpathSync as P,lstatSync as A,statSync as O}from"node:fs";import{dirname as w,join as f,relative as N,sep as F,extname as E}from"node:path";import{Node as s,VariableDeclarationKind as T,SyntaxKind as S}from"ts-morph";import{diagnosticAt as R}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{findProjectConfigFile as D}from"./PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs";const I=/\.ts$/u,u=(t,e)=>N(t,e).split(F).join("/").replace(I,""),C=new Set(["_generated","node_modules"]),j=(t,e,i)=>t==="schema.ts"&&e===i,z=t=>{try{return O(t)}catch{console.warn(`@lunora/codegen: skipping ${t} — it is a symlink that does not resolve (or vanished mid-scan).`);return}},b=(t,e,i,r)=>{let o,n;try{o=x(t),n=P(t)}catch{return e}if(r.has(n))return e;r.add(n);for(const a of o){const l=f(t,a),c=z(l);c!==void 0&&(c.isDirectory()?C.has(a)||b(l,e,i,r):c.isFile()&&E(a)===".ts"&&!j(a,t,i)&&e.push(l))}return e},y=t=>b(t,[],t,new Set),V=["src/server","src/index.ts","src/worker.ts"],_=new Set([".ts",".tsx"]),v=(t,e=[])=>{let i;try{i=A(t)}catch{return e}if(i.isFile())return _.has(E(t))&&e.push(t),e;if(!i.isDirectory())return e;for(const r of x(t))r==="_generated"||r==="node_modules"||v(f(t,r),e);return e},K=t=>{const e=w(t),i=y(t).map(n=>({displayPath:u(t,n),filePath:n})),r=new Set(i.map(n=>n.filePath)),o=D(e);for(const n of[...V.flatMap(a=>v(f(e,a))),...o===void 0?[]:[o]])r.has(n)||(r.add(n),i.push({displayPath:u(e,n),filePath:n}));return i},L=(t,e,i)=>{const r=[];for(const{displayPath:o,filePath:n}of e){const a=t.getSourceFile(n)??t.addSourceFileAtPath(n);for(const l of a.getDescendantsOfKind(S.CallExpression)){const c=i(l,o);c!==void 0&&r.push(c)}}return r},J=(t,e,i)=>L(t,y(e).map(r=>({displayPath:u(e,r),filePath:r})),i),Q=(t,e,i)=>L(t,K(e),i),Z=t=>{for(const e of t.getAncestors())if(s.isVariableDeclaration(e)&&e.getVariableStatement()?.hasExportKeyword()===!0)return e.getName();return""},h=t=>{if(s.isStringLiteral(t)||s.isNoSubstitutionTemplateLiteral(t)||s.isNumericLiteral(t))return t.getLiteralText();if(s.isComputedPropertyName(t)){const e=t.getExpression();if(s.isStringLiteral(e)||s.isNoSubstitutionTemplateLiteral(e))return e.getLiteralText()}return t.getText()},k=t=>h(t.getNameNode()),tt=t=>h(t.getPropertyNameNode()??t.getNameNode()),p=(t,e)=>t?.getProperties().find(i=>!s.isSpreadAssignment(i)&&k(i)===e),et=(t,e)=>{if(e){const n=t.getArguments()[0];return n&&(s.isArrowFunction(n)||s.isFunctionExpression(n))?n:void 0}const i=t.getArguments()[0];if(!i||!s.isObjectLiteralExpression(i))return;const r=p(i,"handler");if(!r||!s.isPropertyAssignment(r))return;const o=r.getInitializer();return o&&(s.isArrowFunction(o)||s.isFunctionExpression(o))?o:void 0},it=(t,e)=>{if(!t||!s.isObjectLiteralExpression(t))return;const i=p(t,e);return i&&s.isPropertyAssignment(i)?i.getInitializer():void 0},$=t=>{const e=t?.getDeclarations().find(o=>s.isVariableDeclaration(o));if(e===void 0||!s.isVariableDeclaration(e))return;const i=e.getParent();if(!s.isVariableDeclarationList(i)||i.getDeclarationKind()!==T.Const)return;const r=i.getParent();return s.isVariableStatement(r)&&s.isSourceFile(r.getParent())?e.getInitializer():void 0},B=t=>$(t.getSymbol()),st=t=>{if(!t)return;if(s.isObjectLiteralExpression(t))return t;if(!s.isIdentifier(t))return;const e=B(t);return e!==void 0&&s.isObjectLiteralExpression(e)?e:void 0},g=t=>s.isPropertyAccessExpression(t)&&t.getName()==="db"||s.isIdentifier(t)&&t.getText()==="db",M=new Set(["findFirst","findFirstOrThrow","findMany","findUnique"]),rt=t=>{const e=t.getExpression();if(!s.isPropertyAccessExpression(e)||!M.has(e.getName()))return;const i=e.getExpression();if(g(i)){const r=t.getArguments()[0];return{options:t.getArguments()[1],table:r&&s.isStringLiteral(r)?r.getLiteralText():""}}if(s.isPropertyAccessExpression(i)){const r=i.getExpression();if(g(r))return{options:t.getArguments()[0],table:i.getName()}}},d=(t,e)=>{const i=t.getExpression();return!s.isPropertyAccessExpression(i)||!e.has(i.getName())?!1:g(i.getExpression())},m=t=>{const e=t.getArguments()[0];return e&&s.isStringLiteral(e)?e.getLiteralText():""},nt=(t,e,i)=>{const r=new Set,o=new Set;for(const n of t.getDescendantsOfKind(S.CallExpression))if(d(n,e)){const a=m(n);a!==""&&r.add(a)}else if(d(n,i)){const a=m(n);a!==""&&o.add(a)}return{tablesRead:[...r],tablesWritten:[...o]}},W=t=>{let e=t;for(;e&&(s.isAsExpression(e)||s.isSatisfiesExpression(e)||s.isParenthesizedExpression(e)||s.isNonNullExpression(e));)e=e.getExpression();return e},ot=t=>{const e=W(t);return e&&s.isCallExpression(e)?e:void 0},at=t=>{const e=t.getExportAssignment(o=>!o.isExportEquals());if(!e)return;const i=e.getExpression();if(!s.isIdentifier(i))return i;const r=i.getSymbol()?.getValueDeclaration();return r&&s.isVariableDeclaration(r)?r.getInitializer():i},ct=t=>{const e=t.getArguments()[1];return e&&s.isStringLiteral(e)?e.getLiteralValue():""},lt=(t,e)=>{if(!s.isObjectLiteralExpression(t))return;const i=p(t,e);if(!i||!s.isPropertyAssignment(i))return;const r=i.getInitializer();return r&&s.isStringLiteral(r)?r.getLiteralText():void 0},q=t=>{const e=t.getStatements(),[i]=e;if(e.length!==1||i===void 0||!s.isReturnStatement(i))return;const r=i.getExpression();return r!==void 0&&s.isObjectLiteralExpression(r)?r:void 0},ut=t=>{if(s.isObjectLiteralExpression(t))return t;if(s.isParenthesizedExpression(t)){const e=t.getExpression();return s.isObjectLiteralExpression(e)?e:void 0}return s.isBlock(t)?q(t):void 0},gt=t=>s.isIdentifier(t)&&t.getText()==="ctx",ft=t=>(e,i,r)=>{if(s.isStringLiteral(e)||s.isNoSubstitutionTemplateLiteral(e))return e.getLiteralValue();throw R(e,`${t} "${i}": \`${r}\` must be a static string literal — it is deploy configuration codegen writes into wrangler.jsonc`)};export{I as TS_EXTENSION_RE,tt as bindingKeyName,J as collectCallRows,Q as collectSecurityCallRows,at as defaultExportExpression,Z as enclosingExportName,p as findObjectProperty,et as handlerOf,gt as isContextIdentifier,g as isDatabaseAccessor,ct as limitNameOf,y as listLunoraSourceFiles,K as listSecurityScanFiles,u as lunoraRelativePath,ut as objectLiteralFromCallbackBody,st as optionsObjectLiteral,it as propertyInitializer,k as propertyKeyName,h as propertyNameText,rt as readTargetOf,ft as stringPropertyFor,lt as stringPropertyOf,$ as symbolConstInitializer,m as tableArgumentOf,nt as tablesAccessedIn,W as unwrapExpression,ot as unwrapToCallExpression};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{statSync as p,readFileSync as m}from"node:fs";import{basename as v}from"node:path";import{createJiti as E}from"jiti";import{Project as b,Node as r}from"ts-morph";import{propertyKeyName as u}from"./listLunoraSourceFiles-DP-5e-RE.mjs";import{findProjectConfigFile as f}from"./PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs";import{PROJECT_CONFIG_FILENAMES as I}from"./PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs";const g=new Map,N=async t=>{const i=f(t);if(i===void 0)return{};let e;try{const n=p(i);e=`${String(n.mtimeMs)}:${String(n.size)}`}catch{return{}}const s=g.get(i);if(s?.key===e)return s.value;const l=(async()=>{try{const o=(await E(i,{interopDefault:!1,moduleCache:!1}).import(i))?.default;return{config:o!==null&&typeof o=="object"?o:void 0}}catch(n){return{error:n instanceof Error?n.message:String(n)}}})();return g.set(i,{key:e,value:l}),l},x=t=>{let e=t.getExportAssignments().find(s=>!s.isExportEquals())?.getExpression();for(;e!==void 0&&(r.isSatisfiesExpression(e)||r.isAsExpression(e)||r.isParenthesizedExpression(e));)e=e.getExpression();if(e!==void 0&&r.isIdentifier(e))for(e=t.getVariableDeclaration(e.getText())?.getInitializer();e!==void 0&&(r.isSatisfiesExpression(e)||r.isAsExpression(e));)e=e.getExpression();return e!==void 0&&r.isObjectLiteralExpression(e)?e:void 0},c=(t,i)=>r.isPropertyAssignment(t)?t.getInitializer():i.getVariableDeclaration(u(t))?.getInitializer(),S=(t,i)=>{let e=t;for(;e!==void 0&&(r.isSatisfiesExpression(e)||r.isAsExpression(e)||r.isParenthesizedExpression(e));)e=e.getExpression();if(e===void 0||!r.isObjectLiteralExpression(e))return{advisor:{unreadable:!0}};const s=e.getProperties(),l=s.filter(a=>r.isPropertyAssignment(a)&&!r.isComputedPropertyName(a.getNameNode())||r.isShorthandPropertyAssignment(a));if(l.length!==s.length)return{advisor:{unreadable:!0}};const n=l.find(a=>u(a)==="minSeverity");if(n===void 0)return{advisor:{}};const o=c(n,i);return o!==void 0&&r.isStringLiteral(o)?{advisor:{minSeverity:o.getLiteralValue()}}:{advisor:{unreadable:!0}}},h=new Map([["advisor",{advisor:{unreadable:!0}}],["remote",{unreadable:!0}],["target",{unreadable:!0}]]),P=(t,i)=>{if(r.isGetAccessorDeclaration(t)||r.isMethodDeclaration(t))return h.get(u(t))??{};if(!r.isPropertyAssignment(t)&&!r.isShorthandPropertyAssignment(t))return{};const e=u(t);if(e==="advisor")return S(c(t,i),i);if(e!=="target"&&e!=="remote")return{};const s=c(t,i);return s===void 0?{unreadable:!0}:e==="target"?r.isStringLiteral(s)?{target:s.getLiteralValue()}:{unreadable:!0}:r.isTrueLiteral(s)||r.isFalseLiteral(s)?{remote:s.getLiteralValue()}:r.isObjectLiteralExpression(s)?{remote:!0}:{unreadable:!0}},O=t=>{const i=f(t);if(i===void 0)return{};let e;try{e=m(i,"utf8")}catch{return{unreadable:!0}}const l=new b({compilerOptions:{allowJs:!0},skipFileDependencyResolution:!0,skipLoadingLibFiles:!0,useInMemoryFileSystem:!0}).createSourceFile(v(i),e,{overwrite:!0}),n=x(l);if(n===void 0)return{unreadable:!0};if(n.getProperties().some(a=>r.isSpreadAssignment(a)))return n.getProperties().some(d=>!r.isSpreadAssignment(d)&&u(d)==="advisor")?{advisor:{unreadable:!0},unreadable:!0}:{unreadable:!0};let o={};for(const a of n.getProperties())o={...o,...P(a,l)};return o};export{I as PROJECT_CONFIG_FILENAMES,f as findProjectConfigFile,N as loadProjectConfig,O as readProjectConfigLiterals};
|
|
@@ -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 y}from"@lunora/errors";import{Node as n,VariableDeclarationKind as h}from"ts-morph";import{diagnosticAt as v}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{propertyKeyName as E}from"./listLunoraSourceFiles-DP-5e-RE.mjs";let f;const j=e=>{f=e},A=/^[A-Za-z_$][\w$]*$/u,p=new Set(["$defaultFn","$onUpdateFn","$type","default","defaultNow","nullable","serverDefault","unique"]),k=(e,t)=>{const r={notNull:!0,...e.column};switch(t){case"$defaultFn":case"default":case"defaultNow":case"serverDefault":{r.hasDefault=!0;break}case"$onUpdateFn":{r.hasOnUpdate=!0;break}case"$type":break;case"nullable":{r.notNull=!1;break}case"unique":{r.unique=!0;break}}return{...e,column:r}},N=new Set(["any","bigint","boolean","bytes","date","geoPoint","null","number","string","timestamp"]),m=new Set(["check","email","int","length","max","min","pattern","positive","url"]),I=new Set(["meta"]),L=new Set(["strip"]),l=new Set,g=new Set,S=e=>{const t=e.getSymbol();let r=(t?.getAliasedSymbol()??t)?.getValueDeclaration();if(r!==void 0&&n.isShorthandPropertyAssignment(r)){const i=r.getValueSymbol();r=(i?.getAliasedSymbol()??i)?.getValueDeclaration()}if(!(r===void 0||!n.isVariableDeclaration(r)))return r.getInitializer()},T=e=>{const t=e.getParent();return!n.isVariableDeclaration(t)||t.getVariableStatement()?.getDeclarationKind()===h.Const},u=e=>{if(n.isParenthesizedExpression(e)||n.isAsExpression(e)||n.isSatisfiesExpression(e))return u(e.getExpression());if(n.isObjectLiteralExpression(e))return e;if(n.isPropertyAccessExpression(e)){const r=e.getSymbol()?.getValueDeclaration(),i=r!==void 0&&n.isPropertyAssignment(r)?r.getInitializer():void 0;return i===void 0?void 0:u(i)}if(!n.isIdentifier(e)||l.has(e))return;const t=S(e);if(!(t===void 0||!T(t))){l.add(e);try{return u(t)}finally{l.delete(e)}}},w="v",D=e=>{if(n.isIdentifier(e))return!0;let t=e;for(;n.isCallExpression(t);){const r=t.getExpression();if(!n.isPropertyAccessExpression(r))return!1;t=r.getExpression()}return n.isIdentifier(t)&&t.getText()===w},c=e=>{if(n.isIdentifier(e)&&!l.has(e)){const t=S(e);if(t!==void 0&&D(t)){l.add(e);try{return c(t)}finally{l.delete(e)}}}return n.isCallExpression(e)?P(e):{kind:"any",sourceText:e.getText()}},R=e=>{const t=u(e.getExpression());if(t===void 0||g.has(t))return{};g.add(t);try{return b(t)}finally{g.delete(t)}},b=e=>{const t={};for(const r of e.getProperties()){if(n.isSpreadAssignment(r)){Object.assign(t,R(r));continue}const i=n.isShorthandPropertyAssignment(r);if(!i&&!n.isPropertyAssignment(r))continue;const o=r.getNameNode();if(n.isComputedPropertyName(o))continue;const a=i?r.getNameNode():r.getInitializer();if(!a)continue;const s=E(r);if(!A.test(s))throw new y("INTERNAL",`@lunora/codegen: field name is not a valid JS identifier: ${JSON.stringify(s)}`);t[s]=c(a)}return t},d=(e,t)=>e&&n.isExpression(e)?c(e):t,V=e=>e===void 0?"undefined":n.isStringLiteral(e)||n.isNoSubstitutionTemplateLiteral(e)?JSON.stringify(e.getLiteralValue()):e.getText(),O=e=>{const t=e&&f?f(e):void 0;return t===void 0?{kind:"from"}:{kind:"from",tsType:t}},x=(e,t,r)=>{if(N.has(e))return{kind:e};const[i,o]=t;switch(e){case"array":return{inner:d(i,{kind:"any"}),kind:"array"};case"from":return O(i);case"id":{if(!i||!n.isStringLiteral(i))throw v(i??r,`v.id(...) target table must be a string literal — codegen resolves foreign-key targets statically. Got ${i?i.getText():"no argument"}.`);return{kind:"id",tableName:i.getLiteralText()}}case"literal":return{kind:"literal",literalValue:V(i)};case"object":return i&&n.isObjectLiteralExpression(i)?{kind:"object",shape:b(i)}:{kind:"object",shape:{}};case"optional":return{inner:d(i,{kind:"any"}),kind:"optional"};case"record":return{keyType:d(i,{kind:"string"}),kind:"record",valueType:d(o,{kind:"any"})};case"storage":return i&&n.isStringLiteral(i)?{bucket:i.getLiteralText(),kind:"storage"}:{kind:"storage"};case"union":return{kind:"union",members:t.filter(a=>n.isExpression(a)).map(a=>c(a))};default:throw new y("INTERNAL",`Unsupported validator kind: ${e}`)}},M=e=>{const[t]=e;if(e.length!==1||t===void 0||!n.isNumericLiteral(t))return;const r=Number(t.getText().replaceAll("_",""));return Number.isSafeInteger(r)&&r>=0?r:void 0},P=e=>{const t=e.getExpression();if(!n.isPropertyAccessExpression(t))return{kind:"any",sourceText:e.getText()};const r=t.getName(),i=e.getArguments();if(p.has(r)||m.has(r)||I.has(r)||L.has(r)){const o=t.getExpression(),a=n.isExpression(o)?c(o):{kind:"any"};if(p.has(r))return k(a,r);if(!m.has(r))return a;const s=r==="max"&&a.kind==="string"?M(i):void 0;return s!==void 0?{...a,hasRefinement:!0,stringMaxLength:Math.min(a.stringMaxLength??s,s)}:{...a,hasRefinement:!0,unmodelledRefinement:!0}}return x(r,i,e)};export{c as a,b as p,u as r,j 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 s,SyntaxKind as f}from"ts-morph";import{bindingKeyName as P,listLunoraSourceFiles as v,lunoraRelativePath as A,isDatabaseAccessor as h}from"./listLunoraSourceFiles-DP-5e-RE.mjs";const I=t=>{const e=t.getText(),n=r=>{const i=r.getNameNode();return s.isIdentifier(i)&&i.getText()===e};for(const r of t.getAncestors())if(!(!s.isArrowFunction(r)&&!s.isFunctionExpression(r)&&!s.isFunctionDeclaration(r)))for(const i of r.getParameters()){const a=i.getDescendantsOfKind(f.BindingElement).find(o=>n(o));if(a!==void 0)return a}},N=t=>{let e=t;for(;;){const n=e.getParent();if(!s.isObjectBindingPattern(n))return;const r=n.getParent();if(s.isBindingElement(r)){e=r;continue}return s.isParameterDeclaration(r)?P(e):void 0}},x=(t,e)=>{const n=t.getParent();if(s.isPropertyAccessExpression(n)&&n.getNameNode()===t||s.isPropertyAssignment(n)&&n.getNameNode()===t)return!1;if(t.getText()===e)return!0;const r=I(t);return r!==void 0&&N(r)===e},p=(t,e)=>s.isIdentifier(t)?x(t,e):t.getDescendantsOfKind(f.Identifier).some(n=>x(n,e)),g=t=>p(t,"ctx"),b=t=>{let e=t;for(;s.isPropertyAccessExpression(e)||s.isElementAccessExpression(e)||s.isNonNullExpression(e);)e=e.getExpression();return s.isIdentifier(e)?e:void 0},E=t=>p(t,"args"),u=t=>{if(!s.isIdentifier(t))return;const e=t.getText(),n=t.getFirstAncestor(o=>s.isArrowFunction(o)||s.isFunctionExpression(o)||s.isFunctionDeclaration(o));if(n===void 0)return;const r=t.getStart();let i,a=-1;for(const o of n.getDescendantsOfKind(f.VariableDeclaration)){if(o.getName()!==e)continue;const c=o.getInitializer(),l=o.getStart();c!==void 0&&l<r&&l>a&&(i=c,a=l)}return i},C=t=>{if(E(t))return!0;const e=u(t);return e!==void 0&&E(e)},_=t=>{if(s.isCallExpression(t)||s.isNewExpression(t))return!1;const e=u(t);return e===void 0||!(s.isCallExpression(e)||s.isNewExpression(e))},B=t=>{if(g(t))return!0;const e=u(t);if(e!==void 0&&g(e))return!0;const n=e??t;return(s.isIdentifier(n)?[n]:n.getDescendantsOfKind(f.Identifier)).some(i=>{const a=u(i);return a!==void 0&&g(a)})},m=(t,e)=>p(t,e),L=(t,e)=>{if(m(t,e))return!0;const n=u(t);if(n!==void 0&&m(n,e))return!0;const r=b(t);if(r!==void 0){const i=u(r);return i!==void 0&&m(i,e)}return!1},D=t=>{for(const e of t.getAncestors())if(s.isVariableDeclaration(e)&&e.getVariableStatement()?.hasExportKeyword()===!0)return e.getName();return"<module>"},y=new Set(["withGeoIndex","withIndex","withSearchIndex"]),S=new Set(["collect","collectWithScores","first","paginate","take","unique"]),F=t=>{const e=t.getExpression();if(!s.isPropertyAccessExpression(e)||e.getName()!=="query")return!1;const n=e.getExpression();return h(n)},w=t=>{const e=[];let n=t;for(;;){const r=n.getParent();if(!r||!s.isPropertyAccessExpression(r))break;const i=r.getParent();if(!i||!s.isCallExpression(i))break;e.push(r.getName()),n=i}return e},R=/\b[A-Za-z_$][\w$]*\._id\s*===?[^=]/u,K=t=>{let e=t;for(;;){const n=e.getParent();if(!n||!s.isPropertyAccessExpression(n))return!1;const r=n.getParent();if(!r||!s.isCallExpression(r))return!1;if(n.getName()==="filter"){const i=r.getArguments()[0];if(i&&R.test(i.getText()))return!0}e=r}},z=t=>{const e=t.getArguments()[0];return e&&s.isStringLiteral(e)?e.getLiteralText():""},M=(t,e)=>{const n=[];for(const r of v(e)){const i=t.getSourceFile(r)??t.addSourceFileAtPath(r),a=A(e,r);for(const o of i.getDescendantsOfKind(f.CallExpression)){if(!F(o))continue;const c=w(o),l=c.includes("filter");n.push({exportName:D(o),file:a,filtersPrimaryKey:l&&K(o),hasFilter:l,hasIndex:c.some(d=>y.has(d)),line:o.getStartLineNumber(),table:z(o),terminal:c.findLast(d=>S.has(d))})}}return n};export{B as a,_ as b,L as c,M as d,D as e,m 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 g}from"ts-morph";import{lunoraRelativePath as L}from"./listLunoraSourceFiles-DP-5e-RE.mjs";import{posix as D}from"node:path";let S,v;const Ae=e=>{const t=S,n=[];S=n;try{return{erased:n,value:e()}}finally{S=t}},Te=e=>{S?.push(...e)},j=e=>{for(const t of e.getAncestors())if(l.isVariableDeclaration(t))return t.getName()},w=(e,t)=>{S?.push({exportName:j(e),filePath:e.getSourceFile().getFilePath(),line:e.getStartLineNumber(),rendered:t})},Ne=e=>{v!==void 0&&w(v,e)},xe=(e,t)=>{const n=v;v=e;try{return t()}finally{v=n}},k=(e,t)=>{const n=e.exportName??`line ${e.line.toString()}`;return{cacheKey:`procedure_return_type_erased:${t}:${n}`,categories:["SCHEMA"],description:"Codegen renders a procedure's return type into `_generated/`, where only names that resolve from that directory may appear. A type it can neither name nor reproduce structurally — a class instance, a call or index signature, a recursive or very deeply nested shape — is emitted as `unknown` instead, so callers lose the shape while the runtime still returns it.",detail:`\`${n}\` in \`${t}\` (line ${e.line.toString()}) returns \`${e.rendered}\`, which codegen could not reproduce — its generated type is \`unknown\`.`,facing:"INTERNAL",level:"WARN",metadata:{exportName:e.exportName,filePath:t,line:e.line,rendered:e.rendered},name:"procedure_return_type_erased",remediation:"Declare the shape explicitly with `.output(...)`, or export the type from the module that declares it so codegen can name it. A class instance cannot cross the wire at all — return a plain object.",title:"Procedure return type is missing from the generated type"}},De=(e,t)=>{const n=new Map;for(const r of e){const s=k(r,L(t,r.filePath));n.set(s.cacheKey,s)}return[...n.values()].toSorted((r,s)=>r.cacheKey.localeCompare(s.cacheKey))},P=/\bany\b(?!\s*(?:\?\s*)?:)/u,U=/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`/gu,O=e=>P.test(e.replaceAll(U,"")),K="/_generated/",B=e=>{const t=[e.getSymbol(),e.getAliasSymbol()].flatMap(n=>n?.getDeclarations()??[]);return t.length>0&&t.every(n=>n.getSourceFile().getSymbol()===void 0)},F=/^(?<quote>["'])(?<specifier>.*)\k<quote>$/su,T=e=>{for(const t of e.getAncestors())if(l.isModuleDeclaration(t)){const n=F.exec(t.getName());if(n?.groups?.specifier!==void 0)return n.groups.specifier}},h=new WeakMap,V=(e,t)=>{const n=e.getSymbol();if(n===void 0)return;let r=h.get(n.compilerSymbol);return r===void 0&&(r=new Map,h.set(n.compilerSymbol,r)),r.has(t)||r.set(t,n.getExport(t)??e.getExportSymbols().find(s=>s.getName()===t)),r.get(t)},_=(e,t)=>e.getNamespaceImport()!==void 0||e.getNamedImports().some(n=>n.getName()===t),W=(e,t,n)=>e.getModuleSpecifierValue()===t&&_(e,n)?n:void 0,q=(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},G=(e,t,n)=>{if(!_(e,n))return;const r=e.getModuleSpecifierSourceFile(),s=r===void 0?void 0:V(r,n);return(s?.getAliasedSymbol()??s)?.getDeclarations().includes(t)===!0?n:void 0},X=/^\.\.?(?:$|\/)/u,H=new Map([[".cjs",".cjs"],[".cts",".cjs"],[".d.ts",".js"],[".js",".js"],[".jsx",".jsx"],[".mjs",".mjs"],[".mts",".mjs"],[".ts",".js"],[".tsx",".js"]]),Y=(e,t)=>{const n=t.getModuleSpecifierValue();if(!X.test(n))return;const r=t.getModuleSpecifierSourceFile(),s=r===void 0?void 0:H.get(r.getExtension());if(r===void 0||s===void 0)return;const i=`${D.join(r.getDirectoryPath(),r.getBaseNameWithoutExtension())}${s}`,o=D.relative(e.getDirectoryPath(),i);return o.startsWith(".")?o:`./${o}`},J=(e,t,n)=>{const r=T(t);for(const s of e.getImportDeclarations()){const i=r===void 0?q(s,t)??G(s,t,n):W(s,r,n);if(i!==void 0)return{exportName:i,specifier:Y(e,s)??s.getModuleSpecifierValue()}}},z=(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))}),m={kind:"verbatim"},p={kind:"expand"},Q=new Set([g.ClassDeclaration,g.EnumDeclaration,g.EnumMember,g.InterfaceDeclaration,g.TypeAliasDeclaration]),Z=e=>T(e)!==void 0||l.isExportable(e)&&e.isExported(),ee=(e,t)=>new RegExp(String.raw`(?<![$\w])${t.replaceAll(/[$()*+.?[\\\]^{|}]/gu,String.raw`\$&`)}(?![$\w])`,"u").test(e),M=(e,t,n,r)=>{const s=e.getSourceFile();if(s.getSymbol()===void 0&&T(e)===void 0||!Q.has(e.getKind()))return m;const i=s.getFilePath();if(i.includes(K))return m;if(i===n)return p;const o=l.isEnumMember(e)?e.getParent():e;if(!l.hasName(o))return p;const a=J(t.getSourceFile(),o,o.getName());return a===void 0?Z(o)||!ee(r(),o.getName())?m:p:z(a.specifier,t)?p:{kind:"qualify",qualified:a}},te=new Set([g.ClassDeclaration,g.EnumDeclaration,g.FunctionDeclaration,g.ModuleDeclaration]),I=e=>{const t=e?.getDeclarations()??[];return t.length>0&&t.every(n=>n.getSourceFile().getSymbol()===void 0)},ne=e=>{for(const t of e.getDeclarations()){const n=t.getFirstChildByKind(g.ComputedPropertyName);if(n!==void 0){let r=n.getExpression();for(;l.isPropertyAccessExpression(r);)r=r.getExpression();return r}}},re=(e,t)=>{if(e.getProperties().some(s=>{if(!s.getName().startsWith("__@"))return!1;const i=ne(s);return i===void 0||!I(i.getSymbol())}))return!0;const r=e.getSymbol();return r!==void 0&&r.getDeclarations().some(s=>te.has(s.getKind()))&&!I(r)&&t().startsWith("typeof ")},R=(e,t,n)=>{const r=e.getAliasSymbol(),s=e.getSymbol(),i=new Set((r??s)?.getDeclarations());let o=!1,a;const c=()=>(a??=e.getText(t),a);for(const u of[s,r].flatMap(d=>d?.getDeclarations()??[])){const d=M(u,t,n,c);if(d.kind==="qualify"&&i.has(u))return d;o||=d.kind!=="verbatim"}return o||re(e,c)?p:m},se=(e,t,n)=>{const r=l.isPropertySignature(e)||l.isPropertyDeclaration(e)?e.getTypeNode():void 0;if(r===void 0)return m;let s=!1;for(const i of[r,...r.getDescendantsOfKind(g.TypeReference)].filter(o=>l.isTypeReference(o))){const o=i.getTypeName().getSymbol();for(const a of(o?.getAliasedSymbol()??o)?.getDeclarations()??[]){const c=M(a,t,n,()=>i.getText());if(c.kind==="qualify")return c;s||=c.kind!=="verbatim"}}return s?p:m},oe=/^[A-Za-z_$][\w$]*$/u,ie=e=>oe.test(e)?e:JSON.stringify(e),$=e=>{const t=[...e.getTypeArguments()];return e.isUnion()&&t.push(...e.getUnionTypes()),e.isIntersection()&&t.push(...e.getIntersectionTypes()),t},y=e=>!e.isObject()||e.isArray()||e.isTuple()||e.getCallSignatures().length>0||e.getConstructSignatures().length>0?!1:e.getStringIndexType()===void 0&&e.getNumberIndexType()===void 0&&!e.getProperties().some(t=>t.getName().startsWith("__@")),E=(e,t,n,r=new Set)=>r.has(e)?!1:(r.add(e),R(e,t,n).kind!=="verbatim"||$(e).some(s=>E(s,t,n,r))?!0:y(e)?e.getProperties().some(s=>s.getDeclarations().some(i=>se(i,t,n).kind!=="verbatim")?!0:E(s.getTypeAtLocation(t),t,n,r)):!1),ae=(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())},C=(e,t)=>e!==void 0&&(y(e)||e.isString()||e.isNumber()||e.isBigInt()||e.isBoolean()||e.isLiteral()||e.isBooleanLiteral()||e.isEnumLiteral()||e.isTemplateLiteral()||e.isNull()||e.isUndefined()||e.isAny()||e.isUnknown()||e.isNever()||e.isVoid())?t:`(${t})`,ce=32,ue=8,le=(e,t,n,r,s,i)=>{const o=e.getArrayElementType(),a=o?i(o,t,n,r,s):void 0;if(a!==void 0)return`${C(o,a)}[]`},ge=(e,t,n,r,s,i)=>{const o=[];for(const a of e.getUnionTypes()){const c=i(a,t,n,r,s);if(c===void 0)return;o.push(c)}return o.join(" | ")},de=(e,t,n,r,s,i)=>{const o=[];for(const a of e.getIntersectionTypes()){const c=i(a,t,n,r,s);if(c===void 0)return;o.push(C(a,c))}return o.join(" & ")},me=(e,t,n,r,s,i)=>{if(!y(e))return;const o=[];for(const a of e.getProperties()){const c=a.getTypeAtLocation(t),u=ae(a,c),d=u&&c.isUnion()?c.getUnionTypes().filter(A=>!A.isUndefined()):[c],N=[];for(const A of d){const x=i(A,t,n,r+1,s);if(x===void 0)return;N.push(x)}o.push(`${ie(a.getName())}${u?"?":""}: ${N.join(" | ")}`)}return o.length>0?`{ ${o.join("; ")} }`:"{}"},fe=e=>{const t=e.getLiteralValue();return typeof t=="string"?JSON.stringify(t):typeof t=="number"?String(t):void 0},pe=e=>[e.getSymbol(),e.getAliasSymbol()].flatMap(t=>t?.getDeclarations()??[]).some(t=>l.isClassDeclaration(t)||l.isClassExpression(t)),b=(e,t,n,r,s=new Set)=>{if(r.has(e)||s.has(e))return!1;if(n>ce)return!0;const i=new Set(r).add(e);if($(e).some(u=>b(u,t,n+1,i,s)))return!0;const o=e.getArrayElementType();if(o!==void 0)return b(o,t,n+1,i,s);if(B(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=y(e)&&e.getProperties().some(u=>b(u.getTypeAtLocation(t),t,n+1,i,s));return c||s.add(e),c},Se=(e,t,n,r,s,i,o)=>{const a=[];for(const c of t.getAliasSymbol()===void 0?t.getTypeArguments():t.getAliasTypeArguments()){const u=o(c,n,r,s+1,i);if(u===void 0)return;a.push(u)}return`import("${e.specifier}").${e.exportName}${a.length>0?`<${a.join(", ")}>`:""}`},ve=e=>[e.getSymbol(),e.getAliasSymbol()].flatMap(t=>t?.getDeclarations()??[]).some(t=>l.isEnumDeclaration(t)||l.isEnumMember(t)),f=(e,t,n,r,s)=>{if(r>ue||s.has(e))return;const i=R(e,t,n);if(i.kind==="verbatim"&&!E(e,t,n))return e.getText(t);const o=new Set(s).add(e);if(!pe(e)){if(e.isEnumLiteral())return fe(e);if(i.kind==="qualify"&&!ve(e)){const a=Se(i.qualified,e,t,n,r,o,f);if(a!==void 0)return a}return e.isArray()?le(e,t,n,r,o,f):e.isUnion()?ge(e,t,n,r,o,f):e.isIntersection()?de(e,t,n,r,o,f):me(e,t,n,r,o,f)}},he=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 i=n.getText(e);if(!i||i==="any"||i==="never"||O(i)||b(n,e,0,new Set))return"unknown";const o=e.getSourceFile().getFilePath();if(E(n,e,o)){const a=f(n,e,o,0,new Set);return a===void 0&&w(e,i),a??"unknown"}return i};export{E as a,Ne as b,Ae as c,De as d,f as e,O as i,xe as p,Te as r,he 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.230",
|
|
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.165",
|
|
50
|
+
"@lunora/agent": "1.0.0-alpha.147",
|
|
51
|
+
"@lunora/container": "1.0.0-alpha.61",
|
|
52
|
+
"@lunora/errors": "1.0.0-alpha.45",
|
|
53
|
+
"@lunora/platform": "1.0.0-alpha.41",
|
|
54
|
+
"@lunora/queue": "1.0.0-alpha.74",
|
|
55
|
+
"@lunora/scheduler": "1.0.0-alpha.92",
|
|
56
|
+
"@lunora/values": "1.0.0-alpha.56",
|
|
57
|
+
"@lunora/workflow": "1.0.0-alpha.67",
|
|
58
|
+
"jiti": "^2.7.0",
|
|
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 };
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { SyntaxKind, Node } from 'ts-morph';
|
|
4
|
-
import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
|
|
5
|
-
|
|
6
|
-
const FLAGS_FILENAME = "flags.ts";
|
|
7
|
-
const FLAG_TYPES = /* @__PURE__ */ new Set(["boolean", "number", "object", "string"]);
|
|
8
|
-
const FLAGSHIP_PROVIDER_MODULE = "@lunora/flags/providers/flagship";
|
|
9
|
-
const isFlagshipProvider = (identifier) => {
|
|
10
|
-
const symbol = identifier.getSymbol();
|
|
11
|
-
if (!symbol) {
|
|
12
|
-
return identifier.getText() === "flagshipProvider";
|
|
13
|
-
}
|
|
14
|
-
for (const declaration of symbol.getDeclarations()) {
|
|
15
|
-
if (!Node.isImportSpecifier(declaration)) {
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
if (declaration.getImportDeclaration().getModuleSpecifierValue() !== FLAGSHIP_PROVIDER_MODULE) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
return declaration.getNameNode().getText() === "flagshipProvider";
|
|
22
|
-
}
|
|
23
|
-
return false;
|
|
24
|
-
};
|
|
25
|
-
const stringPropertyOrUndefined = (argument, property) => {
|
|
26
|
-
const node = argument.getProperty(property);
|
|
27
|
-
if (!node || !Node.isPropertyAssignment(node)) {
|
|
28
|
-
return void 0;
|
|
29
|
-
}
|
|
30
|
-
const initializer = node.getInitializerOrThrow();
|
|
31
|
-
if (Node.isStringLiteral(initializer) || Node.isNoSubstitutionTemplateLiteral(initializer)) {
|
|
32
|
-
return initializer.getLiteralValue();
|
|
33
|
-
}
|
|
34
|
-
return void 0;
|
|
35
|
-
};
|
|
36
|
-
const flagshipIrFromCall = (call) => {
|
|
37
|
-
const argument = call.getArguments()[0];
|
|
38
|
-
if (argument && Node.isObjectLiteralExpression(argument)) {
|
|
39
|
-
const bindingName = stringPropertyOrUndefined(argument, "binding");
|
|
40
|
-
if (bindingName !== void 0 && bindingName.length > 0) {
|
|
41
|
-
return { bindingName, mode: "binding", provider: "flagship" };
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return { mode: "http", provider: "flagship" };
|
|
45
|
-
};
|
|
46
|
-
const defaultExportExpression = (source) => {
|
|
47
|
-
const assignment = source.getExportAssignment((declaration2) => !declaration2.isExportEquals());
|
|
48
|
-
if (!assignment) {
|
|
49
|
-
return void 0;
|
|
50
|
-
}
|
|
51
|
-
const expression = assignment.getExpression();
|
|
52
|
-
if (!Node.isIdentifier(expression)) {
|
|
53
|
-
return expression;
|
|
54
|
-
}
|
|
55
|
-
const declaration = expression.getSymbol()?.getValueDeclaration();
|
|
56
|
-
if (declaration && Node.isVariableDeclaration(declaration)) {
|
|
57
|
-
return declaration.getInitializer();
|
|
58
|
-
}
|
|
59
|
-
return expression;
|
|
60
|
-
};
|
|
61
|
-
const providerInitializer = (defineFlagsCall) => {
|
|
62
|
-
const argument = defineFlagsCall.getArguments()[0];
|
|
63
|
-
if (!argument || !Node.isObjectLiteralExpression(argument)) {
|
|
64
|
-
return void 0;
|
|
65
|
-
}
|
|
66
|
-
const property = argument.getProperty("provider");
|
|
67
|
-
return property && Node.isPropertyAssignment(property) ? property.getInitializer() : void 0;
|
|
68
|
-
};
|
|
69
|
-
const discoverFlags = (project, lunoraDirectory) => {
|
|
70
|
-
const flagsPath = join(lunoraDirectory, FLAGS_FILENAME);
|
|
71
|
-
if (!existsSync(flagsPath)) {
|
|
72
|
-
return void 0;
|
|
73
|
-
}
|
|
74
|
-
const source = project.getSourceFile(flagsPath) ?? project.addSourceFileAtPath(flagsPath);
|
|
75
|
-
const exported = defaultExportExpression(source);
|
|
76
|
-
if (!exported || !Node.isCallExpression(exported)) {
|
|
77
|
-
return { provider: "custom" };
|
|
78
|
-
}
|
|
79
|
-
const provider = providerInitializer(exported);
|
|
80
|
-
if (provider && Node.isCallExpression(provider)) {
|
|
81
|
-
const callee = provider.getExpression();
|
|
82
|
-
if (Node.isIdentifier(callee) && isFlagshipProvider(callee)) {
|
|
83
|
-
return flagshipIrFromCall(provider);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return { provider: "custom" };
|
|
87
|
-
};
|
|
88
|
-
const isContextIdentifier = (node) => Node.isIdentifier(node) && node.getText() === "ctx";
|
|
89
|
-
const flagTypeFromAccess = (access) => {
|
|
90
|
-
const name = access.getName();
|
|
91
|
-
if (!FLAG_TYPES.has(name)) {
|
|
92
|
-
return void 0;
|
|
93
|
-
}
|
|
94
|
-
const receiver = access.getExpression();
|
|
95
|
-
if (!Node.isPropertyAccessExpression(receiver)) {
|
|
96
|
-
return void 0;
|
|
97
|
-
}
|
|
98
|
-
if (receiver.getName() === "flags" && isContextIdentifier(receiver.getExpression())) {
|
|
99
|
-
return name;
|
|
100
|
-
}
|
|
101
|
-
const inner = receiver.getExpression();
|
|
102
|
-
if (receiver.getName() === "details" && Node.isPropertyAccessExpression(inner) && inner.getName() === "flags" && isContextIdentifier(inner.getExpression())) {
|
|
103
|
-
return name;
|
|
104
|
-
}
|
|
105
|
-
return void 0;
|
|
106
|
-
};
|
|
107
|
-
const flagKeyFromCall = (call) => {
|
|
108
|
-
const callee = call.getExpression();
|
|
109
|
-
if (!Node.isPropertyAccessExpression(callee)) {
|
|
110
|
-
return void 0;
|
|
111
|
-
}
|
|
112
|
-
const type = flagTypeFromAccess(callee);
|
|
113
|
-
if (type === void 0) {
|
|
114
|
-
return void 0;
|
|
115
|
-
}
|
|
116
|
-
const argument = call.getArguments()[0];
|
|
117
|
-
if (!argument || !(Node.isStringLiteral(argument) || Node.isNoSubstitutionTemplateLiteral(argument))) {
|
|
118
|
-
return void 0;
|
|
119
|
-
}
|
|
120
|
-
const key = argument.getLiteralValue();
|
|
121
|
-
return key.length > 0 ? { key, type } : void 0;
|
|
122
|
-
};
|
|
123
|
-
const discoverFlagKeys = (project, lunoraDirectory) => {
|
|
124
|
-
const found = /* @__PURE__ */ new Map();
|
|
125
|
-
for (const filePath of listLunoraSourceFiles(lunoraDirectory)) {
|
|
126
|
-
const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPath(filePath);
|
|
127
|
-
for (const call of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
128
|
-
const candidate = flagKeyFromCall(call);
|
|
129
|
-
if (candidate && !found.has(candidate.key)) {
|
|
130
|
-
found.set(candidate.key, candidate.type);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return [...found.entries()].map(([key, type]) => {
|
|
135
|
-
return { key, type };
|
|
136
|
-
}).toSorted((a, b) => a.key.localeCompare(b.key));
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
export { FLAGS_FILENAME, discoverFlagKeys, discoverFlags };
|