@electrojs/codegen 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +33 -21
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readFileSync as e}from"node:fs";import{parseSync as t}from"oxc-parser";import{basename as n,dirname as r,isAbsolute as i,join as a,relative as o,resolve as s}from"node:path";function c(n){let r=t(n,e(n,`utf8`),{sourceType:`module`});for(let e of r.errors)console.warn(`[codegen] Parse error in ${n}: ${e.message}`);return{program:r.program,filePath:n}}function l(e){return e&&e.type===`Literal`&&typeof e.value==`string`?e.value:null}function u(e){if(!e||e.type!==`ArrayExpression`)return[];let t=[];for(let n of e.elements){let e=l(n);e!==null&&t.push(e)}return t}function d(e){if(!e||e.type!==`ArrayExpression`)return[];let t=[];for(let n of e.elements)n?.type===`Identifier`&&typeof n.name==`string`&&t.push(n.name);return t}function f(e){return e?e.type===`Identifier`&&typeof e.name==`string`?e.name:e.type===`Literal`&&typeof e.value==`string`?e.value:null:null}function p(e,t){let n=e.properties;if(!n)return null;for(let e of n)if(e.type===`Property`&&f(e.key)===t)return e.value;return null}function m(e){return e&&e.type===`Identifier`&&typeof e.name==`string`?e.name:null}function h(e){return(e.type===`ClassDeclaration`||e.type===`ClassExpression`)&&e.id?m(e.id):null}function g(e,t){let n=Array.isArray(t)?t:[t],r=e.decorators??[];for(let e of r){if(e.type!==`Decorator`)continue;let t=e.expression;if(t.type===`Identifier`&&n.includes(t.name))return t;if(t.type===`CallExpression`){let e=t.callee;if(e.type===`Identifier`&&n.includes(e.name))return t}}return null}function _(e,t){let n=g(e,t);if(!n||n.type!==`CallExpression`)return null;let r=n.arguments[0];return!r||r.type!==`ObjectExpression`?null:r}function v(e){let t=new Set,n=e.body;if(!n)return t;for(let e of n){if(e.type===`ExportNamedDeclaration`){let n=e.declaration;if(n?.type===`ClassDeclaration`||n?.type===`FunctionDeclaration`||n?.type===`TSInterfaceDeclaration`||n?.type===`TSTypeAliasDeclaration`){let e=m(n.id);e&&t.add(e);continue}if(n?.type===`VariableDeclaration`){for(let e of n.declarations){let n=m(e.id);n&&t.add(n)}continue}for(let n of e.specifiers??[]){if(n.type!==`ExportSpecifier`)continue;let e=m(n.local);e&&t.add(e)}continue}if(e.type===`ExportDefaultDeclaration`){let n=e.declaration,r=m(n)||m(n?.id??null);r&&t.add(r)}}return t}function y(e,t){let n=t?.trim();if(n&&n.length>0)return n;let r=e.endsWith(`Module`)?e.slice(0,-6):e,i=r.length>0?r:e;return i.charAt(0).toLowerCase()+i.slice(1)}function b(e,t){let n=t?.trim();return n&&n.length>0?n:e}function x(e,t){let n=e.trim();if(n.startsWith(`view:`)){let e=n.slice(5).trim();return e.length>0?e:null}let r=t?.trim();return r&&r.length>0?r:null}const S=new Set([`onInit`,`onStart`,`onReady`,`onShutdown`,`onDispose`]);function C(e){if(!e||e.type!==`CallExpression`)return!1;let t=e.callee;if(t?.type!==`Identifier`||t.name!==`inject`)return!1;let n=e.arguments??[];return n[0]?.type===`Identifier`&&n[0].name===`SignalBus`}function
|
|
1
|
+
import{readFileSync as e}from"node:fs";import{parseSync as t}from"oxc-parser";import{basename as n,dirname as r,isAbsolute as i,join as a,relative as o,resolve as s}from"node:path";function c(n){let r=t(n,e(n,`utf8`),{sourceType:`module`});for(let e of r.errors)console.warn(`[codegen] Parse error in ${n}: ${e.message}`);return{program:r.program,filePath:n}}function l(e){return e&&e.type===`Literal`&&typeof e.value==`string`?e.value:null}function u(e){if(!e||e.type!==`ArrayExpression`)return[];let t=[];for(let n of e.elements){let e=l(n);e!==null&&t.push(e)}return t}function d(e){if(!e||e.type!==`ArrayExpression`)return[];let t=[];for(let n of e.elements)n?.type===`Identifier`&&typeof n.name==`string`&&t.push(n.name);return t}function f(e){return e?e.type===`Identifier`&&typeof e.name==`string`?e.name:e.type===`Literal`&&typeof e.value==`string`?e.value:null:null}function p(e,t){let n=e.properties;if(!n)return null;for(let e of n)if(e.type===`Property`&&f(e.key)===t)return e.value;return null}function m(e){return e&&e.type===`Identifier`&&typeof e.name==`string`?e.name:null}function h(e){return(e.type===`ClassDeclaration`||e.type===`ClassExpression`)&&e.id?m(e.id):null}function g(e,t){let n=Array.isArray(t)?t:[t],r=e.decorators??[];for(let e of r){if(e.type!==`Decorator`)continue;let t=e.expression;if(t.type===`Identifier`&&n.includes(t.name))return t;if(t.type===`CallExpression`){let e=t.callee;if(e.type===`Identifier`&&n.includes(e.name))return t}}return null}function _(e,t){let n=g(e,t);if(!n||n.type!==`CallExpression`)return null;let r=n.arguments[0];return!r||r.type!==`ObjectExpression`?null:r}function v(e){let t=new Set,n=e.body;if(!n)return t;for(let e of n){if(e.type===`ExportNamedDeclaration`){let n=e.declaration;if(n?.type===`ClassDeclaration`||n?.type===`FunctionDeclaration`||n?.type===`TSInterfaceDeclaration`||n?.type===`TSTypeAliasDeclaration`){let e=m(n.id);e&&t.add(e);continue}if(n?.type===`VariableDeclaration`){for(let e of n.declarations){let n=m(e.id);n&&t.add(n)}continue}for(let n of e.specifiers??[]){if(n.type!==`ExportSpecifier`)continue;let e=m(n.local);e&&t.add(e)}continue}if(e.type===`ExportDefaultDeclaration`){let n=e.declaration,r=m(n)||m(n?.id??null);r&&t.add(r)}}return t}function y(e,t){let n=t?.trim();if(n&&n.length>0)return n;let r=e.endsWith(`Module`)?e.slice(0,-6):e,i=r.length>0?r:e;return i.charAt(0).toLowerCase()+i.slice(1)}function b(e,t){let n=t?.trim();return n&&n.length>0?n:e}function x(e,t){let n=e.trim();if(n.startsWith(`view:`)){let e=n.slice(5).trim();return e.length>0?e:null}let r=t?.trim();return r&&r.length>0?r:null}const S=new Set([`onInit`,`onStart`,`onReady`,`onShutdown`,`onDispose`]);function C(e){if(!e||e.type!==`CallExpression`)return!1;let t=e.callee;if(t?.type!==`Identifier`||t.name!==`inject`)return!1;let n=e.arguments??[];return n[0]?.type===`Identifier`&&n[0].name===`SignalBus`}function w(e){let t=new Set,n=e.body?.body??[];for(let e of n){if(e.type!==`PropertyDefinition`||e.computed||!C(e.value))continue;let n=f(e.key);n&&t.add(n)}return t}function T(e){let t=e.value?.params??[],n=[];return t.forEach((e,t)=>{let r=m(e);r&&n.push({index:t,name:r})}),n}function E(e,t){let n=e.find(e=>e.name===t);return n?n.index:null}function ee(e,t){if(!e)return{kind:`void`};if(e.type===`Identifier`){if(e.name===`undefined`)return{kind:`void`};let n=E(t,e.name);return n===null?{kind:`unknown`}:{kind:`method-parameter`,parameterIndex:n}}if(e.type!==`ObjectExpression`)return{kind:`unknown`};let n=null,r=[];for(let t of e.properties??[]){if(t.type!==`Property`||t.kind!==`init`||t.computed)return{kind:`unknown`};let e=f(t.key),i=t.value;if(!e||!i||i.type!==`MemberExpression`||i.computed)return{kind:`unknown`};let a=m(i.object),o=f(i.property);if(!a||!o||e!==o)return{kind:`unknown`};if(n===null)n=a;else if(n!==a)return{kind:`unknown`};r.push(e)}if(!n)return{kind:`unknown`};let i=E(t,n);return i===null?{kind:`unknown`}:{kind:`method-parameter-pick`,parameterIndex:i,keys:r}}function te(e,t){if(!e||e.type!==`MemberExpression`||e.computed)return!1;let n=f(e.property);return e.object?.type!==`ThisExpression`||!n?!1:n===`signals`?!0:t.has(n)}function ne(e,t){return te(e,t)||C(e)}function D(e,t){if(!(!e||typeof e!=`object`)){t(e);for(let n of Object.values(e)){if(Array.isArray(n)){for(let e of n)D(e,t);continue}D(n,t)}}}function re(e,t,n,r){let i=[],a=T(e);return D(e.value?.body,e=>{if(e.type!==`CallExpression`)return;let o=e.callee;if(!o||o.type!==`MemberExpression`||o.computed||!ne(o.object,r))return;let s=f(o.property);if(s!==`publish`&&s!==`subscribe`)return;let c=e.arguments??[],u=l(c[0]);u&&i.push({id:u,methodName:n,ownerClassName:t,source:s,payload:s===`publish`?ee(c[1],a):{kind:`unknown`}})}),i}function O(e,t){let n=[],r=[],i=[],a=w(e),o=e.body?.body??[];for(let e of o){if(e.type!==`MethodDefinition`||e.kind!==`method`||e.computed||e.static||e.accessibility===`private`)continue;let o=f(e.key);if(!o||(r.push(...re(e,t,o,a)),S.has(o)))continue;let s=g(e,`command`),c=g(e,`query`),u=g(e,`signal`),d=g(e,`job`);if(s||c){let r=_(e,s?`command`:`query`),i=l(r?p(r,`id`):null);n.push({id:b(o,i),methodName:o,kind:s?`command`:`query`,ownerClassName:t})}if(u){let n=_(e,`signal`),i=l(n?p(n,`id`):null);r.push({id:b(o,i),methodName:o,ownerClassName:t,source:`decorator`,payload:{kind:`method-parameter`,parameterIndex:0}})}if(d){let n=_(e,`job`),r=l(n?p(n,`id`):null),a=l(n?p(n,`cron`):null);i.push({id:b(o,r),methodName:o,ownerClassName:t,cron:a})}}return{methods:n,signals:r,jobs:i}}function ie(e,t){let n=v(e),r=[],i=[],a=[],o=[],s=e.body;if(!s)return{modules:r,providers:i,windows:a,views:o};for(let e of s){let s=null;if(e.type===`ClassDeclaration`?s=e:(e.type===`ExportNamedDeclaration`&&e.declaration?.type===`ClassDeclaration`||e.type===`ExportDefaultDeclaration`&&e.declaration?.type===`ClassDeclaration`)&&(s=e.declaration),!s)continue;let c=h(s);if(!c)continue;let f=n.has(c);if(g(s,`Module`)){let e=_(s,`Module`),n=l(e?p(e,`id`):null),i=[...d(e?p(e,`imports`):null),...d(e?p(e,`dependsOn`):null)],a=[...d(e?p(e,`providers`):null),...d(e?p(e,`services`):null)],{methods:o,signals:u,jobs:m}=O(s,c);r.push({kind:`module`,id:y(c,n),className:c,filePath:t,exported:f,importClassNames:[...new Set(i)],providerClassNames:[...new Set(a)],methods:o,signals:u,jobs:m});continue}if(g(s,`Injectable`)){let{methods:e,signals:n,jobs:r}=O(s,c);i.push({kind:`injectable`,className:c,filePath:t,exported:f,methods:e,signals:n,jobs:r});continue}if(g(s,`Window`)){let{methods:e,signals:n,jobs:r}=O(s,c),o=_(s,`Window`),u=l(o?p(o,`id`):null);if(!u){console.warn(`[codegen] Skipping @Window() with non-literal id in ${t}`);continue}i.push({kind:`injectable`,className:c,filePath:t,exported:f,methods:e,signals:n,jobs:r}),a.push({id:u,className:c,filePath:t,exported:f});continue}if(g(s,`View`)){let{methods:e,signals:n,jobs:r}=O(s,c),a=_(s,`View`),d=l(a?p(a,`source`):null);if(!d){console.warn(`[codegen] Skipping @View() with non-literal source in ${t}`);continue}let m=x(d,l(a?p(a,`id`):null));if(!m){console.warn(`[codegen] Skipping @View() with non-literal id in ${t}`);continue}i.push({kind:`injectable`,className:c,filePath:t,exported:f,methods:e,signals:n,jobs:r}),o.push({id:m,className:c,filePath:t,exported:f,source:d,access:u(a?p(a,`access`):null),signals:u(a?p(a,`signals`):null)})}}return{modules:r,providers:i,windows:a,views:o}}const k=[/\.d\.ts$/,/\.test\.ts$/,/\.spec\.ts$/,/\.gen\.ts$/];function A(e){return n(e).startsWith(`._`)||e.includes(`/__MACOSX/`)?!1:e.endsWith(`.ts`)&&!k.some(t=>t.test(e))}async function ae(e){let{glob:t}=await import(`tinyglobby`);return(await t([`**/*.ts`],{cwd:e,absolute:!0,ignore:[`node_modules/**`,`**/__MACOSX/**`,`**/.DS_Store`,`**/._*`]})).filter(A).sort()}async function oe(e){let t=await ae(e),n=[],r=[],i=[],a=[];for(let e of t){let{program:t}=c(e),o=ie(t,e);n.push(...o.modules),r.push(...o.providers),i.push(...o.windows),a.push(...o.views)}let o=new Map(r.map(e=>[e.className,e])),s=new Map(n.map(e=>[e.className,e]));return{modules:n.map(e=>{let t=[];for(let n of e.providerClassNames){let r=o.get(n);if(!r){console.warn(`[codegen] Module "${e.id}" references unknown provider class "${n}" in ${e.filePath}`);continue}t.push({className:r.className,filePath:r.filePath,exported:r.exported,methods:[...r.methods],signals:[...r.signals],jobs:[...r.jobs]})}let n=[];for(let t of e.importClassNames){let r=s.get(t);if(!r){console.warn(`[codegen] Module "${e.id}" references unknown module class "${t}" in ${e.filePath}`);continue}n.push(r.id)}return{id:e.id,className:e.className,filePath:e.filePath,exported:e.exported,imports:[...new Set(n)],providers:t,methods:[...e.methods],signals:[...e.signals],jobs:[...e.jobs]}}),windows:i,views:a}}function j(e,t){let n=o(r(e),t).replaceAll(`\\`,`/`).replace(/\.(?:[cm]?tsx?|[cm]?jsx?)$/,``);return n.startsWith(`.`)?n:`./${n}`}function M(e,t){let n=o(r(e),t).replaceAll(`\\`,`/`);return n.startsWith(`.`)?n:`./${n}`}function N(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}const P=`// Auto-generated by ElectroJS codegen. Do not edit.
|
|
2
2
|
`;function F(e){switch(e.source){case`decorator`:return 400;case`publish`:switch(e.payload.kind){case`method-parameter-pick`:return 350;case`method-parameter`:return 340;case`void`:return 330;case`unknown`:return 320}case`subscribe`:return 100}}function I(e,t){return F(t)>F(e)}function L(e){let t=new Map,n=(e,n)=>{let r=t.get(e.id);(!r||I(r.signal,e))&&t.set(e.id,{signal:e,filePath:n})};for(let t of e){for(let e of t.signals)n(e,t.filePath);for(let e of t.providers)for(let t of e.signals)n(t,e.filePath)}return t}const R=`${P}// @ts-nocheck
|
|
3
3
|
// ElectroJS runtime authoring contract types — provides IDE completions for modules, signals, jobs, windows, and runtime-declared views.
|
|
4
4
|
|
|
@@ -25,28 +25,40 @@ type _SignalPayloadFromMethodParam<T, K extends PropertyKey, I extends number> =
|
|
|
25
25
|
: never;
|
|
26
26
|
type _SignalPayloadFromMethod<T, K extends PropertyKey> =
|
|
27
27
|
_SignalPayloadFromMethodParam<T, K, 0>;
|
|
28
|
+
type _SignalId = Extract<keyof import("@electrojs/runtime").ModuleSignalPayloadMap, string>;
|
|
29
|
+
type _VoidSignalId = {
|
|
30
|
+
[TKey in _SignalId]: import("@electrojs/runtime").ModuleSignalPayloadMap[TKey] extends void ? TKey : never;
|
|
31
|
+
}[_SignalId];
|
|
32
|
+
type _NonVoidSignalId = Exclude<_SignalId, _VoidSignalId>;
|
|
28
33
|
`;function z(e,t,n){return`_InvokeMethod<typeof import("${j(e,n)}").${t.ownerClassName}, ${JSON.stringify(t.methodName)}>`}function B(e,t,n){let r=`typeof import("${j(e,n)}").${t.ownerClassName}`;switch(t.payload.kind){case`method-parameter`:return t.source===`decorator`&&t.payload.parameterIndex===0?`_SignalPayloadFromMethod<${r}, ${JSON.stringify(t.methodName)}>`:`_SignalPayloadFromMethodParam<${r}, ${JSON.stringify(t.methodName)}, ${t.payload.parameterIndex}>`;case`method-parameter-pick`:{let e=t.payload.keys.map(e=>JSON.stringify(e)).join(` | `)||`never`;return`Pick<_SignalPayloadFromMethodParam<${r}, ${JSON.stringify(t.methodName)}, ${t.payload.parameterIndex}>, ${e}>`}case`void`:return`void`;case`unknown`:return`unknown`}}function V(e,t){let n=[];for(let r of e){for(let e of r.methods){let i=`${r.id}:${e.id}`;n.push(` ${JSON.stringify(i)}: ${z(t,e,r.filePath)};`)}for(let e of r.providers)for(let i of e.methods){let a=`${r.id}:${i.id}`;n.push(` ${JSON.stringify(a)}: ${z(t,i,e.filePath)};`)}}return`\n interface ModuleMethodMap {\n${n.join(`
|
|
29
34
|
`)}\n }\n`}function H(e,t){return`\n interface ModuleApiRegistry {\n${e.filter(e=>e.exported).map(e=>{let n=[...e.methods.map(t=>({method:t,filePath:e.filePath})),...e.providers.flatMap(e=>e.methods.map(t=>({method:t,filePath:e.filePath})))].map(({method:e,filePath:n})=>` ${N(e.id)}: ${z(t,e,n)};`),r=n.length>0?`{\n${n.join(`
|
|
30
35
|
`)}\n }`:`{}`;return` ${JSON.stringify(e.id)}: ${r};`}).join(`
|
|
31
36
|
`)}\n }\n`}function U(e,t){let n=new Map;for(let r of L(e).values())n.set(r.signal.id,` ${JSON.stringify(r.signal.id)}: ${B(t,r.signal,r.filePath)};`);return`\n interface ModuleSignalPayloadMap {\n${[...n.values()].join(`
|
|
32
|
-
`)}\n }\n`}function W(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`
|
|
37
|
+
`)}\n }\n`}function W(){return`
|
|
38
|
+
interface SignalBus {
|
|
39
|
+
publish<TSignalId extends _VoidSignalId>(signalId: TSignalId): void;
|
|
40
|
+
publish<TSignalId extends _NonVoidSignalId>(signalId: TSignalId, payload: ModuleSignalPayloadMap[TSignalId]): void;
|
|
41
|
+
subscribe<TSignalId extends _SignalId>(signalId: TSignalId, handler: SignalListener<ModuleSignalPayloadMap[TSignalId]>): () => void;
|
|
42
|
+
subscribe<TSignalId extends _SignalId>(signalId: TSignalId, handler: ContextualSignalHandler<ModuleSignalPayloadMap[TSignalId]>): () => void;
|
|
43
|
+
}
|
|
44
|
+
`}function G(e){return`\n interface ModuleJobRegistry {\n${e.map(e=>{let t=[...new Set([...e.jobs.map(e=>e.id),...e.providers.flatMap(e=>e.jobs.map(e=>e.id))])],n=t.length>0?t.map(e=>JSON.stringify(e)).join(` | `):`never`;return` ${JSON.stringify(e.id)}: ${n};`}).join(`
|
|
45
|
+
`)}\n }\n`}function K(e,t){let n=new Map;for(let r of e)for(let e of r.providers)if(e.exported&&!n.has(e.className)){let r=j(t,e.filePath);n.set(e.className,` ${JSON.stringify(e.className)}: typeof import("${r}").${e.className};`)}return`\n interface InjectableClassRegistry {\n${[...n.values()].join(`
|
|
46
|
+
`)}\n }\n`}function q(e,t){return`\n interface WindowClassRegistry {\n${e.filter(e=>e.exported).map(e=>{let n=j(t,e.filePath);return` ${JSON.stringify(e.id)}: typeof import("${n}").${e.className};`}).join(`
|
|
47
|
+
`)}\n }\n`}function se(e,t){return`\n interface ViewClassRegistry {\n${e.filter(e=>e.exported).map(e=>{let n=j(t,e.filePath);return` ${JSON.stringify(e.id)}: typeof import("${n}").${e.className};`}).join(`
|
|
48
|
+
`)}\n }\n`}function ce(e){return`\n interface ViewAccessRegistry {\n${[...new Set([...e.flatMap(e=>e.methods.map(t=>`${e.id}:${t.id}`)),...e.flatMap(e=>e.providers.flatMap(t=>t.methods.map(t=>`${e.id}:${t.id}`)))])].map(e=>` ${JSON.stringify(e)}: true;`).join(`
|
|
49
|
+
`)}\n }\n`}function le(e){return`\n interface ViewSignalRegistry {\n${[...L(e).keys()].map(e=>` ${JSON.stringify(e)}: true;`).join(`
|
|
50
|
+
`)}\n }\n`}function ue(e){return`\n interface BundledViewIdRegistry {\n${e.filter(e=>e.source.startsWith(`view:`)).map(e=>e.id).map(e=>` ${JSON.stringify(e)}: true;`).join(`
|
|
51
|
+
`)}\n }\n`}function de(e,t){let n=new Set,r=new Set(e.views.map(e=>e.className)),i=new Set(e.windows.map(e=>e.className)),a=(e,r,i,a,o)=>{if(!a)return;let s=j(t,e),c;switch(i){case`module`:c=`_ModuleAuthoringApi<${JSON.stringify(o)}>`;break;case`window`:c=`_WindowAuthoringApi`;break;case`view`:c=`_ViewAuthoringApi`;break}n.add(`import "${s}";\ndeclare module "${s}" {\n interface ${r} extends ${c} {}\n}`)};for(let t of e.modules){a(t.filePath,t.className,`module`,t.exported,t.id);for(let e of t.providers)r.has(e.className)||i.has(e.className)||a(e.filePath,e.className,`module`,e.exported,t.id)}for(let t of e.windows)a(t.filePath,t.className,`window`,t.exported);for(let t of e.views)a(t.filePath,t.className,`view`,t.exported);return n.size>0?`\n${[...n].join(`
|
|
40
52
|
|
|
41
53
|
`)}\n`:`
|
|
42
|
-
`}function
|
|
54
|
+
`}function fe(e,t){let n=a(t,`electro-env.d.ts`);return{path:`electro-env.d.ts`,content:`${R}
|
|
43
55
|
declare module "@electrojs/runtime" {
|
|
44
|
-
${V(e.modules,n)}${H(e.modules,n)}${U(e.modules,n)}${W(e.modules)}${
|
|
56
|
+
${V(e.modules,n)}${H(e.modules,n)}${U(e.modules,n)}${W()}${G(e.modules)}${K(e.modules,n)}${q(e.windows,n)}${se(e.views,n)}
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
declare module "@electrojs/common" {
|
|
48
|
-
${
|
|
49
|
-
}${
|
|
60
|
+
${ce(e.modules)}${le(e.modules)}${ue(e.views)}
|
|
61
|
+
}${de(e,n)}`}}const pe=`${P}// @ts-nocheck
|
|
50
62
|
// ElectroJS renderer bridge contract types — provides IDE completions for bridge access and forwarded signals.
|
|
51
63
|
|
|
52
64
|
export {};
|
|
@@ -78,7 +90,7 @@ type _BridgeOutputFromMethod<T, K extends PropertyKey> =
|
|
|
78
90
|
? Awaited<V>
|
|
79
91
|
: never
|
|
80
92
|
: never;
|
|
81
|
-
`;function
|
|
93
|
+
`;function me(e,t){let n=new Set(e.access),r=[];for(let e of t){for(let t of e.methods)n.has(`${e.id}:${t.id}`)&&r.push({moduleId:e.id,method:t,filePath:e.filePath});for(let t of e.providers)for(let i of t.methods)n.has(`${e.id}:${i.id}`)&&r.push({moduleId:e.id,method:i,filePath:t.filePath})}return r}function he(e,t){let n=new Set(e.signals),r=[];for(let e of L(t).values())n.has(e.signal.id)&&r.push({signal:e.signal,filePath:e.filePath});return r}function ge(e,t){return`_BridgeInputFromMethod<typeof import("${j(e,t.filePath)}").${t.method.ownerClassName}, ${JSON.stringify(t.method.methodName)}>`}function _e(e,t){return`_BridgeOutputFromMethod<typeof import("${j(e,t.filePath)}").${t.method.ownerClassName}, ${JSON.stringify(t.method.methodName)}>`}function ve(e,t){return`import("@electrojs/renderer").BridgeContractEntry<${ge(e,t)}, ${_e(e,t)}>`}function ye(e,t){let n=`typeof import("${j(e,t.filePath)}").${t.signal.ownerClassName}`;switch(t.signal.payload.kind){case`method-parameter`:return t.signal.source===`decorator`&&t.signal.payload.parameterIndex===0?`_SignalPayloadFromMethod<${n}, ${JSON.stringify(t.signal.methodName)}>`:`_SignalPayloadFromMethodParam<${n}, ${JSON.stringify(t.signal.methodName)}, ${t.signal.payload.parameterIndex}>`;case`method-parameter-pick`:{let e=t.signal.payload.keys.map(e=>JSON.stringify(e)).join(` | `)||`never`;return`Pick<_SignalPayloadFromMethodParam<${n}, ${JSON.stringify(t.signal.methodName)}, ${t.signal.payload.parameterIndex}>, ${e}>`}case`void`:return`void`;case`unknown`:return`unknown`}}function be(e,t,n){let r=me(e,t),i=he(e,t),a=e=>r.filter(t=>t.method.kind===e).map(e=>` ${JSON.stringify(`${e.moduleId}:${e.method.id}`)}: ${ve(n,e)};`).join(`
|
|
82
94
|
`);return`declare module "@electrojs/renderer" {
|
|
83
95
|
interface BridgeQueries {
|
|
84
96
|
${[a(`query`),a(`command`)].filter(Boolean).join(`
|
|
@@ -90,12 +102,12 @@ ${a(`command`)}
|
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
interface BridgeSignals {
|
|
93
|
-
${i.map(e=>` ${JSON.stringify(e.signal.id)}: ${
|
|
105
|
+
${i.map(e=>` ${JSON.stringify(e.signal.id)}: ${ye(n,e)};`).join(`
|
|
94
106
|
`)}
|
|
95
107
|
}
|
|
96
|
-
}`}function
|
|
97
|
-
${t?
|
|
98
|
-
`}function
|
|
108
|
+
}`}function xe(e,t,n){return`${pe}
|
|
109
|
+
${t?be(t,e.modules,n):``}
|
|
110
|
+
`}function Se(e,t){return t.map(t=>{let n=a(t.packageRoot,`electro-env.d.ts`),r=xe(e,e.views.find(e=>e.id===t.viewId),n);return{packageRoot:t.packageRoot,path:`electro-env.d.ts`,content:r,indexDts:r}})}function Ce(e,t,n){let a=n.trim();return a.length===0||!(a.startsWith(`.`)||i(a))?a:M(t,i(a)?a:s(r(e.__source),a))}function J(e,t,n){let r=`generated/preload/${e.id}.gen.ts`,i=`${n}/${r}`,a=`${P}
|
|
99
111
|
import { contextBridge, ipcRenderer } from "electron";
|
|
100
112
|
import { createBridgeClient } from "@electrojs/runtime/client";
|
|
101
113
|
|
|
@@ -103,8 +115,8 @@ contextBridge.exposeInMainWorld("__ELECTRO_RENDERER__", createBridgeClient({
|
|
|
103
115
|
viewId: ${JSON.stringify(e.id)},
|
|
104
116
|
ipcRenderer,
|
|
105
117
|
}));
|
|
106
|
-
`;if(t?.preload&&t.preload.length>0){let e=
|
|
107
|
-
`)}\n]`}function
|
|
118
|
+
`;if(t?.preload&&t.preload.length>0){let e=Ce(t,i,t.preload);e.length>0&&(a+=`\n// User preload extension\nimport ${JSON.stringify(e)};\n`)}return{path:r,content:a}}function Y(e,t){return e.id.localeCompare(t.id)||e.filePath.localeCompare(t.filePath)}function X(e){return e.length===0?`[]`:`[\n${e.map(e=>` ${e},`).join(`
|
|
119
|
+
`)}\n]`}function we(e,t){let{modules:n,windows:r,views:i}=e;if(n.length===0&&r.length===0&&i.length===0)return null;let o=`generated/runtime/registry.gen.ts`,s=a(t,o),c=[],l=[...n].sort(Y).flatMap((e,t)=>{if(!e.exported)return console.warn(`[codegen] Skipping non-exported module "${e.className}" from runtime registry`),[];let n=`__electro_module_${t}`,r=j(s,e.filePath);return c.push(`import { ${e.className} as ${n} } from "${r}";`),[{...e,localName:n}]}),u=[...r].sort(Y).flatMap((e,t)=>{if(!e.exported)return console.warn(`[codegen] Skipping non-exported window "${e.className}" from runtime registry`),[];let n=`__electro_window_${t}`,r=j(s,e.filePath);return c.push(`import { ${e.className} as ${n} } from "${r}";`),[{...e,localName:n}]}),d=[...i].sort(Y).flatMap((e,t)=>{if(!e.exported)return console.warn(`[codegen] Skipping non-exported view "${e.className}" from runtime registry`),[];let n=`__electro_view_${t}`,r=j(s,e.filePath);return c.push(`import { ${e.className} as ${n} } from "${r}";`),[{...e,localName:n}]}),f=new Set(l.flatMap(e=>e.imports)),p=l.filter(e=>!f.has(e.id)),m=new Set(l.map(e=>e.id));for(let e of l)for(let t of e.imports)m.has(t)||console.warn(`[codegen] Module "${e.id}" depends on non-exported module "${t}" in runtime registry`);l.length>0&&p.length===0?console.warn(`[codegen] Runtime registry found no root module candidate; skipping electroAppDefinition`):p.length>1&&console.warn(`[codegen] Runtime registry found multiple root module candidates (${p.map(e=>e.id).join(`, `)}); skipping electroAppDefinition`);let h=p.length===1,g=h?[`AppKernelDefinition`,`ModuleClass`,`ViewClass`,`WindowClass`]:[`ModuleClass`,`ViewClass`,`WindowClass`],_=X(l.map(e=>e.localName)),v=X(u.map(e=>e.localName)),y=X(d.map(e=>e.localName)),b=X(p.map(e=>e.localName)),x=p[0],S=h&&x?`\nexport const electroAppDefinition = {\n root: ${x.localName},\n modules: electroModules,\n windows: electroWindows,\n views: electroViews,\n} satisfies AppKernelDefinition;\n`:``;return{path:o,content:`${P}
|
|
108
120
|
import type { ${g.join(`, `)} } from "@electrojs/runtime";
|
|
109
121
|
${c.length>0?`${c.join(`
|
|
110
122
|
`)}\n`:``}
|
|
@@ -121,4 +133,4 @@ export const electroRuntimeRegistry = {
|
|
|
121
133
|
} as const;${S}
|
|
122
134
|
export default electroRuntimeRegistry;
|
|
123
135
|
`}}var Z=class extends Error{constructor(e,t){super(e),this.name=`CodegenError`,this.code=t}},Q=class extends Z{constructor(e){super(e.map(e=>e.message).join(`
|
|
124
|
-
`),`VALIDATION_ERROR`),this.name=`ValidationError`,this.diagnostics=e}};function
|
|
136
|
+
`),`VALIDATION_ERROR`),this.name=`ValidationError`,this.diagnostics=e}};function Te(e){let t=Oe(e);if(t.length>0)throw new Q(t)}function $(e){let t=new Set,n=new Set;for(let r of e)t.has(r)?n.add(r):t.add(r);return[...n]}function Ee(e){let t=new Set;for(let n of e.modules){for(let e of n.methods)t.add(`${n.id}:${e.id}`);for(let e of n.providers)for(let r of e.methods)t.add(`${n.id}:${r.id}`)}return t}function De(e){return new Set(L(e.modules).keys())}function Oe(e){let{scanResult:t}=e,n=[];for(let e of $(t.modules.map(e=>e.id)))n.push({code:`duplicate-module-id`,message:`Duplicate module id "${e}" detected in scan result`});for(let e of t.modules){let t=[...e.methods.map(e=>e.id),...e.providers.flatMap(e=>e.methods.map(e=>e.id))];for(let r of $(t))n.push({code:`duplicate-module-method`,message:`Module "${e.id}" exposes duplicate method id "${r}"`})}for(let e of $(t.windows.map(e=>e.id)))n.push({code:`duplicate-window-id`,message:`Duplicate window id "${e}" detected in scan result`});for(let e of $(t.views.map(e=>e.id)))n.push({code:`duplicate-view-id`,message:`Duplicate view id "${e}" detected in scan result`});let r=Ee(t);for(let e of t.views)for(let t of e.access)r.has(t)||n.push({code:`unknown-access-key`,message:`View "${e.id}" references unknown access key "${t}"`,filePath:e.filePath});let i=De(t);for(let e of t.views)for(let t of e.signals)i.has(t)||n.push({code:`unknown-signal-key`,message:`View "${e.id}" references unknown signal key "${t}"`,filePath:e.filePath});if(e.views&&e.views.length>0){let r=new Set(t.views.map(e=>e.id));for(let t of e.views)r.has(t.id)||n.push({code:`missing-runtime-view`,message:`Generator view definition "${t.id}" has no matching @View() class`})}return n}function ke(e){Te(e);let{scanResult:t,outputDir:n,srcDir:r}=e,i=[],a=new Map;if(e.views)for(let t of e.views)a.set(t.id,t);for(let e of t.views){let t=a.get(e.id);i.push(J(e,t,n))}let o=we(t,n);return o&&i.push(o),{files:i,envTypes:fe(t,r),packageTypes:e.packageTargets?Se(t,e.packageTargets):[]}}export{Z as CodegenError,Q as ValidationError,ke as generate,oe as scan};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electrojs/codegen",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "TypeScript code generation for ElectroJS preload scripts, typed IPC, and runtime registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"tsdown": "^0.21.4",
|
|
45
45
|
"vitest": "^4.1.1",
|
|
46
|
-
"@electrojs/common": "1.0.
|
|
47
|
-
"@electrojs/
|
|
48
|
-
"@electrojs/
|
|
46
|
+
"@electrojs/common": "1.0.9",
|
|
47
|
+
"@electrojs/config": "1.0.9",
|
|
48
|
+
"@electrojs/runtime": "1.0.9"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@electrojs/common": "1.0.
|
|
52
|
-
"@electrojs/config": "1.0.
|
|
53
|
-
"@electrojs/runtime": "1.0.
|
|
51
|
+
"@electrojs/common": "1.0.9",
|
|
52
|
+
"@electrojs/config": "1.0.9",
|
|
53
|
+
"@electrojs/runtime": "1.0.9",
|
|
54
54
|
"@types/node": "^25.5.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|