@bobtail.software/b-ssr 1.0.64 → 1.0.66
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/README.md +593 -0
- package/bin/generate-rpc-types.mjs +91 -0
- package/dist/fastify-b-ssr-plugin.cjs +1 -1
- package/dist/fastify-b-ssr-plugin.d.cts +2 -0
- package/dist/fastify-b-ssr-plugin.d.ts +2 -0
- package/dist/fastify-b-ssr-plugin.js +1 -1
- package/dist/rpc-type-generator.cjs +9 -0
- package/dist/rpc-type-generator.d.cts +14 -0
- package/dist/rpc-type-generator.d.ts +14 -0
- package/dist/rpc-type-generator.js +9 -0
- package/dist/vite-rpc-plugin.cjs +36 -28
- package/dist/vite-rpc-plugin.d.cts +1 -0
- package/dist/vite-rpc-plugin.d.ts +1 -0
- package/dist/vite-rpc-plugin.js +35 -27
- package/package.json +27 -6
package/dist/vite-rpc-plugin.js
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import
|
|
1
|
+
import je from"fast-glob";import{access as Oe,unlink as xe,writeFile as Me}from"fs/promises";import C from"path";import{format as Le,resolveConfig as qe}from"prettier";import{Node as re,Project as ke,SyntaxKind as D,ts as se}from"ts-morph";import be from"fast-glob";import{access as we,unlink as de,writeFile as Fe}from"fs/promises";import L from"path";import{format as Se,resolveConfig as Ce}from"prettier";import{Node as te,Project as Ee,SyntaxKind as k,ts as ne}from"ts-morph";function Re(i){let m=i.replace(/[^a-zA-Z0-9]+(.)?/g,(j,w)=>w?w.toUpperCase():"");return m.charAt(0).toLowerCase()+m.slice(1)}function ye(i,m,j){let w=L.basename(j,L.extname(j))||"Index",F=m.replace(/:[a-zA-Z0-9_]+/g,"").replace(/\//g," "),d=`${i} ${F} ${w}`;return Re(d)}function ve(i){let m=/([a-zA-Z_$][a-zA-Z0-9_$]*(?:\s*\|\s*)?)+/g,j=/'[^']+'/g,w=/`[^`]+`/g,F=i,d=[],s,R=i.replace(/[^'`]*/g,M=>" ".repeat(M.length));for(;(s=j.exec(i))!==null;)d.push({start:s.index,end:s.index+s[0].length,value:s[0]});for(;(s=w.exec(i))!==null;)d.push({start:s.index,end:s.index+s[0].length,value:s[0]});if(d.length>1){let M=d.map(t=>t.value).sort((t,l)=>{let n=t.replace(/['`]/g,""),b=l.replace(/['`]/g,"");return n.localeCompare(b)}),$=0,Q=[...M].sort((t,l)=>{let n=t.replace(/['`]/g,""),b=l.replace(/['`]/g,"");return n.localeCompare(b)}),V="",_=0;for(let t=0;t<d.length;t++)V+=i.slice(_,d[t].start),V+=Q[t],_=d[t].end;V+=i.slice(_),F=V}return F}function $e(i){let m=i.match(/^\{([\s\S]*)\}$/);if(!m)return i;let j=m[1];if(!j.includes(":"))return i;let w=j.split(/[;,]/).map(s=>s.trim()).filter(s=>s),F=[];for(let s of w){let R=s.indexOf(":");if(R===-1)continue;let M=s.slice(0,R).trim(),$=s.slice(R+1).trim();F.push({name:M,value:$})}return F.length<=1?i:(F.sort((s,R)=>s.name.localeCompare(R.name)),`{ ${F.map(s=>`${s.name}: ${s.value}`).join("; ")} }`)}function ce(i){let m=ve(i);return m=$e(m),m}async function Ae(i={}){let{routerPattern:m="src-ts/routers/**/*.mts",tsConfigFilePath:j="tsconfig.json",routerBaseDir:w="src-ts/routers",clean:F=!1}=i,d=[],s=[],R=[];try{let _=function(l){let n=[];return l.paramsType!=="unknown"&&n.push(`params: ${l.paramsType}`),l.queryType!=="unknown"&&n.push(`query: ${l.queryType}`),l.bodyType!=="unknown"&&n.push(`body: ${l.bodyType}`),n.push("signal?: AbortSignal"),n};var M=_;let $=new Ee({tsConfigFilePath:j,skipAddingFilesFromTsConfig:!1}),Q=L.resolve(process.cwd(),w||".");async function V(l){try{let B=function(r){return r.replace(/import\(['"](.*?)['"]\)/g,(f,h)=>{if(!L.isAbsolute(h))return f;let x=h;if(!L.extname(x)){let a=$.getSourceFile(o=>o.getFilePath().replace(/\.(mts|ts|tsx)$/,"")===h);a&&(x=a.getFilePath())}let e=L.relative(L.dirname(K),x).replace(/\\/g,"/");return e.startsWith(".")||(e="./"+e),`import("${e}")`})},q=function(r,f){if(r.getSymbol()?.getName()==="Promise"){let p=r.getAwaitedType();if(p)return`Promise<${q(p,f)}>`}let h=r.getAliasSymbol()??r.getSymbol();if(h?.getName()==="__object")return ce(B(r.getText(f,ne.TypeFormatFlags.NoTruncation|ne.TypeFormatFlags.UseFullyQualifiedType)));if(r.isObject()&&!h){let p=(u,P=0)=>{if(!(P>5)){if(u.isArray()){let S=u.getArrayElementType();S&&p(S,P);return}if(u.isObject()&&!u.getSymbol()&&!u.getAliasSymbol()){for(let S of u.getApparentProperties()){let T=S.getValueDeclaration();T&&p(S.getTypeAtLocation(T),P+1)}return}q(u,f)}};return p(r),ce(B(r.getText(f,ne.TypeFormatFlags.NoTruncation|ne.TypeFormatFlags.UseFullyQualifiedType)))}if(!h)return ce(B(r.getText(f,ne.TypeFormatFlags.NoTruncation)));let x=h.getDeclarations()[0];if(!x)return h.getName();if(te.isImportSpecifier(x)||te.isImportClause(x)){let p=x.getFirstAncestorByKind(k.ImportDeclaration);if(p){let u=p.getModuleSpecifierValue(),P=h.getName();return v.has(u)||v.set(u,new Set),v.get(u)?.add(P),P}}let e=x.getSourceFile();if(e.getFilePath()===y.getFilePath())return h.getName();if(e.isInNodeModules())return ce(B(r.getText(f,ne.TypeFormatFlags.NoTruncation)));let a=L.relative(L.dirname(K),e.getFilePath()).replace(/\\/g,"/"),c=a.startsWith(".")?a:`./${a}`,g=h.getName();return v.has(c)||v.set(c,new Set),v.get(c)?.add(g),g},oe=function(r){let f;if(te.isFunctionLikeDeclaration(r)||te.isArrowFunction(r)){let h=r.getDescendantsOfKind(k.ReturnStatement);for(let x of h){let e=x.getExpression();if(e?.isKind(k.SatisfiesExpression)){f=e.getTypeNode()?.getType();break}}}if(f)return q(f,r);{let h=r.getType().getCallSignatures();if(h.length>0){let x=h[0]?.getReturnType();return q(x,r)}}return"unknown"};var n=B,b=q,O=oe;let y=$.addSourceFileAtPath(l);await y.refreshFromFileSystem(),$.resolveSourceFileDependencies();let W=y.getDescendantsOfKind(k.CallExpression),N=W.filter(r=>r.getExpression().getText().endsWith(".addRpcRoute")),I=W.filter(r=>r.getExpression().getText().endsWith(".addRenderRoute")),Z=W.filter(r=>r.getExpression().getText().endsWith(".addLoaderRoute")),G=L.extname(l),K=l.substring(0,l.length-G.length)+".universal.d.ts";if(N.length===0&&I.length===0&&Z.length===0){if(F)try{await de(K),s.push(K)}catch{}return!1}let X=[],v=new Map;v.has("fastify")||v.set("fastify",new Set),v.get("fastify")?.add("FastifyRequest"),v.get("fastify")?.add("FastifyReply");let ue=r=>{let f="unknown",h="unknown",x="unknown",e=!1;if(!r||!te.isObjectLiteralExpression(r))return{paramsType:f,queryType:h,bodyType:x,isMultipart:e};let a=r.getProperty("schema");if(a?.isKind(k.PropertyAssignment)){let o=a.getInitializer();if(o?.isKind(k.Identifier)){let g=o.getSymbol()?.getValueDeclaration();if(g){let p=g.getFirstDescendantByKind(k.ObjectLiteralExpression);p&&(o=p)}}if(o&&te.isObjectLiteralExpression(o)){let c=o.getProperty("consumes");if(c?.isKind(k.PropertyAssignment)){let p=c.getInitializer();te.isArrayLiteralExpression(p)&&(e=p.getElements().some(u=>u.isKind(k.StringLiteral)&&u.getLiteralValue()==="multipart/form-data"))}let g=p=>{let u=o.getProperty(p);if(u?.isKind(k.PropertyAssignment)){let P=u.getInitializer();if(P){let S=P.getType(),T=S.getProperty("_output");return q(T?T.getTypeAtLocation(P).getApparentType():S,P)}}return"unknown"};if(f=g("params"),h=g("querystring"),x=g("body"),e){let p="{ file: File }";x=x!=="unknown"&&x.trim().startsWith("{")?`(${x} & ${p})`:p}}}return{paramsType:f,queryType:h,bodyType:x,isMultipart:e}},z=L.relative(Q,L.dirname(l)).split(L.sep).join("/"),ge=z==="."||!z?"":z.startsWith("/")?z:"/"+z,Y=(r,f)=>{let[h,x]=r.getArguments();if(!h?.isKind(k.StringLiteral))return;let e=h.getLiteralValue(),a="unknown",o=ge,{paramsType:c,queryType:g,bodyType:p,isMultipart:u}=ue(x);if(x?.isKind(k.ObjectLiteralExpression)){let T=x.getProperty("prefix");if(T?.isKind(k.PropertyAssignment)){let E=T.getInitializer();E?.isKind(k.StringLiteral)&&(o=E.getLiteralValue())}let A=x.getProperty("handler");if(A?.isKind(k.PropertyAssignment)){let E=A.getInitializer();E&&(a=oe(E),a.startsWith("Promise<")||(a=`Promise<${a}>`))}}let P="",S="";f==="rpc"?(P=L.join(o,"rpc",e).replace(/\\/g,"/"),S=ye("action",o,e)):f==="loader"?(P=L.join(o,"loader",e).replace(/\\/g,"/"),S=ye("loader",o,e)):f==="api"&&(P=L.join(o,"api",e).replace(/\\/g,"/"),S=ye("get",o,e)),S&&X.push({type:f,name:S,returnType:a,url:e,rpcUrl:P,loaderUrl:P,paramsType:c,queryType:g,bodyType:p,isMultipart:u})};if(N.forEach(r=>Y(r,"rpc")),I.forEach(r=>Y(r,"loader")),Z.forEach(r=>Y(r,"api")),X.length===0){if(F)try{await de(K),s.push(K)}catch{}return!1}let J=[],me=[...v.entries()].sort((r,f)=>r[0].localeCompare(f[0]));for(let[r,f]of me)J.push(`import type { ${[...f].sort().join(", ")} } from "${r}";`);let fe=[...X].sort((r,f)=>r.name.localeCompare(f.name)),ae=[];fe.forEach(r=>{let f=_(r),h="";f.length>0&&(h=`args: { ${f.join("; ")} }`),h||(h="args: { signal?: AbortSignal }"),ae.push(`export declare const ${r.name}: (${h}, ssrContext?: { req?: FastifyRequest, reply?: FastifyReply }) => ${r.returnType};`)});let ee=`// AUTO-GENERATED by @bobtail.software/b-ssr. DO NOT EDIT.
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
|
|
4
|
-
`+(
|
|
4
|
+
`+(J.length>0?J.join(`
|
|
5
5
|
`)+`
|
|
6
6
|
|
|
7
|
-
`:"")+
|
|
7
|
+
`:"")+ae.join(`
|
|
8
8
|
|
|
9
|
-
`);try{let
|
|
9
|
+
`);try{let r=await Ce(K)||{};ee=await Se(ee,{...r,parser:"typescript",filepath:K})}catch{}return await Fe(K,ee),d.push(K),!0}catch(y){return R.push(`Error processing ${l}: ${y instanceof Error?y.message:String(y)}`),!1}}let t=await be(m,{absolute:!0});if(await Promise.all(t.map(l=>V(l))),F){let l=await be(L.join(w,"**/*.universal.d.ts"),{absolute:!0});for(let n of l){let b=n.replace(".universal.d.ts",".mts").replace(".universal.d.ts",".ts");if(!await we(b).then(()=>!0).catch(()=>!1))try{await de(n),s.push(n)}catch{}}}}catch($){R.push(`Fatal error: ${$ instanceof Error?$.message:String($)}`)}return{generated:d,cleaned:s,errors:R}}var ie="virtual:b-ssr-rpc-universal:";function De(i){let m=i.replace(/[^a-zA-Z0-9]+(.)?/g,(j,w)=>w?w.toUpperCase():"");return m.charAt(0).toLowerCase()+m.slice(1)}function he(i,m,j){let w=C.basename(j,C.extname(j))||"Index",F=m.replace(/:[a-zA-Z0-9_]+/g,"").replace(/\//g," "),d=`${i} ${F} ${w}`;return De(d)}function Ne(i){let m=/'[^']+'/g,j=/`[^`]+`/g,w=[];for(;m.exec(i)!==null;);let F=/'[^']+'/g,d;for(;(d=F.exec(i))!==null;)w.push({start:d.index,end:d.index+d[0].length,value:d[0]});for(;(d=j.exec(i))!==null;)w.push({start:d.index,end:d.index+d[0].length,value:d[0]});if(w.length>1){let s=[...w].sort(($,Q)=>{let V=$.value.replace(/['`]/g,""),_=Q.value.replace(/['`]/g,"");return V.localeCompare(_)}),R="",M=0;for(let $=0;$<w.length;$++)R+=i.slice(M,w[$].start),R+=s[$].value,M=w[$].end;return R+=i.slice(M),R}return i}function Ie(i){let m=i.match(/^\{([\s\S]*)\}$/);if(!m)return i;let j=m[1];if(!j.includes(":"))return i;let w=j.split(/[;,]/).map(s=>s.trim()).filter(s=>s),F=[];for(let s of w){let R=s.indexOf(":");if(R===-1)continue;let M=s.slice(0,R).trim(),$=s.slice(R+1).trim();F.push({name:M,value:$})}return F.length<=1?i:(F.sort((s,R)=>s.name.localeCompare(R.name)),`{ ${F.map(s=>`${s.name}: ${s.value}`).join("; ")} }`)}function pe(i){let m=Ne(i);return m=Ie(m),m}function et(i={}){let{routerPattern:m="src-ts/routers/**/*.mts",tsConfigFilePath:j="tsconfig.json",routerBaseDir:w="src-ts/routers"}=i,F=new Map,d=new Set,s=new ke({tsConfigFilePath:j,skipAddingFilesFromTsConfig:!1}),R=C.resolve(process.cwd(),w||".");async function M(t){try{let B=function(e){return e.replace(/import\(['"](.*?)['"]\)/g,(a,o)=>{if(!C.isAbsolute(o))return a;let c=o;if(!C.extname(c)){let p=s.getSourceFile(u=>u.getFilePath().replace(/\.(mts|ts|tsx)$/,"")===o);p&&(c=p.getFilePath())}let g=C.relative(C.dirname(G),c).replace(/\\/g,"/");return g.startsWith(".")||(g="./"+g),`import("${g}")`})},q=function(e,a){if(e.getSymbol()?.getName()==="Promise"){let T=e.getAwaitedType();if(T)return`Promise<${q(T,a)}>`}let o=e.getAliasSymbol()??e.getSymbol();if(o?.getName()==="__object")return pe(B(e.getText(a,se.TypeFormatFlags.NoTruncation|se.TypeFormatFlags.UseFullyQualifiedType)));if(e.isObject()&&!o){let T=(A,E=0)=>{if(!(E>5)){if(A.isArray()){let U=A.getArrayElementType();U&&T(U,E);return}if(A.isObject()&&!A.getSymbol()&&!A.getAliasSymbol()){for(let U of A.getApparentProperties()){let H=U.getValueDeclaration();H&&T(U.getTypeAtLocation(H),E+1)}return}q(A,a)}};return T(e),pe(B(e.getText(a,se.TypeFormatFlags.NoTruncation|se.TypeFormatFlags.UseFullyQualifiedType)))}if(!o)return pe(B(e.getText(a,se.TypeFormatFlags.NoTruncation)));let c=o.getDeclarations()[0];if(!c)return o.getName();if(re.isImportSpecifier(c)||re.isImportClause(c)){let T=c.getFirstAncestorByKind(D.ImportDeclaration);if(T){let A=T.getModuleSpecifierValue(),E=o.getName();return v.has(A)||v.set(A,new Set),v.get(A)?.add(E),E}}let g=c.getSourceFile();if(g.getFilePath()===O.getFilePath())return o.getName();if(g.isInNodeModules())return pe(B(e.getText(a,se.TypeFormatFlags.NoTruncation)));let p=C.relative(C.dirname(G),g.getFilePath()).replace(/\\/g,"/"),P=p.startsWith(".")?p:`./${p}`,S=o.getName();return v.has(P)||v.set(P,new Set),v.get(P)?.add(S),S},oe=function(e){let a;if(re.isFunctionLikeDeclaration(e)||re.isArrowFunction(e)){let o=e.getDescendantsOfKind(D.ReturnStatement);for(let c of o){let g=c.getExpression();if(g?.isKind(D.SatisfiesExpression)){a=g.getTypeNode()?.getType();break}}}if(a)return q(a,e);{let o=e.getType().getCallSignatures();if(o.length>0){let c=o[0]?.getReturnType();return q(c,e)}}return"unknown"};var l=B,n=q,b=oe;let O=s.addSourceFileAtPath(t);await O.refreshFromFileSystem(),s.resolveSourceFileDependencies();let y=O.getDescendantsOfKind(D.CallExpression),W=y.filter(e=>e.getExpression().getText().endsWith(".addRpcRoute")),N=y.filter(e=>e.getExpression().getText().endsWith(".addRenderRoute")),I=y.filter(e=>e.getExpression().getText().endsWith(".addLoaderRoute")),Z=C.extname(t),G=t.substring(0,t.length-Z.length)+".universal.d.ts",K=C.resolve(t);if(W.length===0&&N.length===0&&I.length===0){F.delete(K),d.delete(K),G!==t&&await xe(G).catch(()=>{});return}d.add(K);let X=[],v=new Map;v.has("fastify")||v.set("fastify",new Set),v.get("fastify")?.add("FastifyRequest"),v.get("fastify")?.add("FastifyReply");let ue=e=>{let a="unknown",o="unknown",c="unknown",g=!1;if(!e||!re.isObjectLiteralExpression(e))return{paramsType:a,queryType:o,bodyType:c,isMultipart:g};let p=e.getProperty("schema");if(p?.isKind(D.PropertyAssignment)){let u=p.getInitializer();if(u?.isKind(D.Identifier)){let S=u.getSymbol()?.getValueDeclaration();if(S){let T=S.getFirstDescendantByKind(D.ObjectLiteralExpression);T&&(u=T)}}if(u&&re.isObjectLiteralExpression(u)){let P=u.getProperty("consumes");if(P?.isKind(D.PropertyAssignment)){let T=P.getInitializer();re.isArrayLiteralExpression(T)&&(g=T.getElements().some(A=>A.isKind(D.StringLiteral)&&A.getLiteralValue()==="multipart/form-data"))}let S=T=>{let A=u.getProperty(T);if(A?.isKind(D.PropertyAssignment)){let E=A.getInitializer();if(E){let U=E.getType(),H=U.getProperty("_output");return q(H?H.getTypeAtLocation(E).getApparentType():U,E)}}return"unknown"};if(a=S("params"),o=S("querystring"),c=S("body"),g){let T="{ file: File }";c=c!=="unknown"&&c.trim().startsWith("{")?`(${c} & ${T})`:T}}}return{paramsType:a,queryType:o,bodyType:c,isMultipart:g}},z=C.relative(R,C.dirname(t)).split(C.sep).join("/"),ge=z==="."||!z?"":z.startsWith("/")?z:"/"+z,Y=(e,a)=>{let[o,c]=e.getArguments();if(!o?.isKind(D.StringLiteral))return;let g=o.getLiteralValue(),p="unknown",u=ge,{paramsType:P,queryType:S,bodyType:T,isMultipart:A}=ue(c);if(c?.isKind(D.ObjectLiteralExpression)){let H=c.getProperty("prefix");if(H?.isKind(D.PropertyAssignment)){let le=H.getInitializer();le?.isKind(D.StringLiteral)&&(u=le.getLiteralValue())}let Te=c.getProperty("handler");if(Te?.isKind(D.PropertyAssignment)){let le=Te.getInitializer();le&&(p=oe(le),p.startsWith("Promise<")||(p=`Promise<${p}>`))}}let E="",U="";a==="rpc"?(E=C.join(u,"rpc",g).replace(/\\/g,"/"),U=he("action",u,g)):a==="loader"?(E=C.join(u,"loader",g).replace(/\\/g,"/"),U=he("loader",u,g)):a==="api"&&(E=C.join(u,"api",g).replace(/\\/g,"/"),U=he("get",u,g)),U&&X.push({type:a,name:U,returnType:p,url:g,rpcUrl:E,loaderUrl:E,paramsType:P,queryType:S,bodyType:T,isMultipart:A})};W.forEach(e=>Y(e,"rpc")),N.forEach(e=>Y(e,"loader")),I.forEach(e=>Y(e,"api"));let J=[],me=[...v.entries()].sort((e,a)=>e[0].localeCompare(a[0]));for(let[e,a]of me)J.push(`import type { ${[...a].sort().join(", ")} } from "${e}";`);let fe=[...X].sort((e,a)=>e.name.localeCompare(a.name)),ae=[];fe.forEach(e=>{ae.push(Q(e))});let ee=`// AUTO-GENERATED by @bobtail.software/b-ssr. DO NOT EDIT.
|
|
10
|
+
/* eslint-disable */
|
|
11
|
+
|
|
12
|
+
`+(J.length>0?J.join(`
|
|
13
|
+
`)+`
|
|
14
|
+
|
|
15
|
+
`:"")+ae.join(`
|
|
16
|
+
|
|
17
|
+
`);try{let e=await qe(G)||{};ee=await Le(ee,{...e,parser:"typescript",filepath:G})}catch{}await Me(G,ee);let r=[],f=[];X.forEach(e=>{let o=e.type==="rpc"?"POST":"GET",c=e.type==="loader"?e.loaderUrl:e.rpcUrl;f.push({name:e.name,rpcUrl:c,method:o,isMultipart:!!e.isMultipart}),r.push({name:e.name,url:e.url,type:e.type,requiresArgs:!0})});let h=`
|
|
10
18
|
import { createClientRpc } from '@bobtail.software/b-ssr/client';
|
|
11
19
|
|
|
12
20
|
if (import.meta.env.DEV) {
|
|
13
|
-
console.debug('\u{1F6E1}\uFE0F [B-SSR Security] Loaded SAFE Client-Stub for: ${
|
|
21
|
+
console.debug('\u{1F6E1}\uFE0F [B-SSR Security] Loaded SAFE Client-Stub for: ${C.basename(t)}');
|
|
14
22
|
}
|
|
15
23
|
|
|
16
|
-
${
|
|
24
|
+
${f.map(e=>`
|
|
17
25
|
export const ${e.name} = createClientRpc({
|
|
18
26
|
url: '${e.rpcUrl}',
|
|
19
27
|
method: '${e.method}',
|
|
@@ -21,17 +29,17 @@ import pe from"fast-glob";import{access as ue,unlink as ee,writeFile as ge}from"
|
|
|
21
29
|
});
|
|
22
30
|
`).join(`
|
|
23
31
|
`)}
|
|
24
|
-
`,
|
|
32
|
+
`,x=V(r,t);F.set(C.resolve(t),{client:h,server:x})}catch(O){console.error(`[rpc-generator] Error al procesar ${t}:`,{error:O})}}let $=(t,l,n)=>{if(l.includes("node_modules")||l.startsWith(ie))return null;if(n?.ssr===!0&&/\.[cm]?[jt]sx?$/.test(l)){let b=/\brequire\s*\(/.test(t),O=/\bmodule\.exports\b/.test(t),y=/\bexports\./.test(t);if(b||O||y)return"import { createRequire } from 'module';"+`
|
|
25
33
|
const require = createRequire(import.meta.url);
|
|
26
34
|
const module = { exports: {} };
|
|
27
35
|
const exports = module.exports;
|
|
28
36
|
`+t+`
|
|
29
|
-
export default module.exports;`}return null};function
|
|
37
|
+
export default module.exports;`}return null};function Q(t){let l=Ke(t),n="";return l.length>0&&(n=`args: { ${l.join("; ")} }`),n||(n="args: { signal?: AbortSignal }"),`export declare const ${t.name}: (${n}, ssrContext?: { req?: FastifyRequest, reply?: FastifyReply }) => ${t.returnType};`}function V(t,l){if(t.length===0)return"";let n=C.relative(process.cwd(),l).replace(/\\/g,"/");return`
|
|
30
38
|
import path from 'path';
|
|
31
39
|
import { pathToFileURL } from 'url';
|
|
32
40
|
|
|
33
41
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
34
|
-
throw new Error('\u{1F6A8} [B-SSR SECURITY ALERT] Server-side code leaked to browser: ${`./${
|
|
42
|
+
throw new Error('\u{1F6A8} [B-SSR SECURITY ALERT] Server-side code leaked to browser: ${`./${C.relative(process.cwd(),l).replace(/\\/g,"/")}`}');
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
let initPromise;
|
|
@@ -45,7 +53,7 @@ export default module.exports;`}return null};function se(t){let u=he(t),r="";ret
|
|
|
45
53
|
renderOptionsMap = new Map();
|
|
46
54
|
loaderApiOptionsMap = new Map();
|
|
47
55
|
const projectRoot = process.cwd();
|
|
48
|
-
const absolutePath = path.resolve(projectRoot, '${
|
|
56
|
+
const absolutePath = path.resolve(projectRoot, '${n}');
|
|
49
57
|
const serverModuleUrl = pathToFileURL(absolutePath).href;
|
|
50
58
|
|
|
51
59
|
if (typeof globalThis.require === 'undefined') {
|
|
@@ -93,46 +101,46 @@ export default module.exports;`}return null};function se(t){let u=he(t),r="";ret
|
|
|
93
101
|
return initPromise;
|
|
94
102
|
}
|
|
95
103
|
|
|
96
|
-
${t.map(
|
|
104
|
+
${t.map(y=>{let W=[];y.requiresArgs&&W.push("args"),W.push("ssrContext");let N=y.requiresArgs?"args":"{}",I="";return y.type==="rpc"?I=`
|
|
97
105
|
if (fn.isMultipart) throw new Error('RPC multipart no soportado en SSR.');
|
|
98
106
|
await getOptionsMaps();
|
|
99
|
-
const options = rpcOptionsMap.get('${
|
|
100
|
-
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${
|
|
101
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
107
|
+
const options = rpcOptionsMap.get('${y.url}');
|
|
108
|
+
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${y.name}');
|
|
109
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${N});
|
|
102
110
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
103
|
-
`:
|
|
111
|
+
`:y.type==="api"?I=`
|
|
104
112
|
await getOptionsMaps();
|
|
105
|
-
const options = loaderApiOptionsMap.get('${
|
|
113
|
+
const options = loaderApiOptionsMap.get('${y.url}');
|
|
106
114
|
if (!options?.handler) {
|
|
107
|
-
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${
|
|
115
|
+
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${y.name}', 'URL:', '${y.url}');
|
|
108
116
|
return null;
|
|
109
117
|
}
|
|
110
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
118
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${N});
|
|
111
119
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
112
|
-
`:
|
|
120
|
+
`:I=`
|
|
113
121
|
await getOptionsMaps();
|
|
114
|
-
const options = renderOptionsMap.get('${
|
|
122
|
+
const options = renderOptionsMap.get('${y.url}');
|
|
115
123
|
if (!options) return {};
|
|
116
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
124
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${N});
|
|
117
125
|
let customData = {};
|
|
118
126
|
try {
|
|
119
127
|
if (options.handler) {
|
|
120
128
|
customData = (await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply)) || {};
|
|
121
129
|
}
|
|
122
130
|
} catch (handlerErr) {
|
|
123
|
-
console.error('\u274C [B-SSR Handler Error] ${
|
|
131
|
+
console.error('\u274C [B-SSR Handler Error] ${y.name}:', handlerErr);
|
|
124
132
|
return {};
|
|
125
133
|
}
|
|
126
134
|
if (ssrContext.reply.sent) return;
|
|
127
135
|
return { ...customData };
|
|
128
|
-
`,`export const ${
|
|
136
|
+
`,`export const ${y.name} = async (${W.join(", ")}) => {
|
|
129
137
|
try {
|
|
130
|
-
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${
|
|
131
|
-
${
|
|
138
|
+
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${y.name} (SSR)');
|
|
139
|
+
${I}
|
|
132
140
|
} catch (error) {
|
|
133
|
-
console.error('\u274C [B-SSR Error] ${
|
|
141
|
+
console.error('\u274C [B-SSR Error] ${y.name}:', error);
|
|
134
142
|
throw error;
|
|
135
143
|
}
|
|
136
144
|
};`}).join(`
|
|
137
145
|
`)}
|
|
138
|
-
`}async function
|
|
146
|
+
`}async function _(){let t=await je(m,{absolute:!0});await Promise.all(t.map(l=>M(l)))}return{name:"b-ssr-vite-plugin-rpc-universal-generator",enforce:"pre",async buildStart(){await _()},configureServer(t){let l=n=>n.endsWith(".mts")||n.endsWith(".ts");t.watcher.on("add",n=>l(n)&&M(n)),t.watcher.on("change",n=>l(n)&&M(n)),t.watcher.on("unlink",n=>{if(l(n)){let b=C.resolve(n);F.delete(b),d.delete(b);let O=C.extname(n),y=n.substring(0,n.length-O.length)+".universal.d.ts";xe(y).catch(()=>{})}})},async resolveId(t,l,n){if(t.startsWith(ie))return null;if(t.includes(".universal")){let b=t.split("?")[0],O=b;if(b.endsWith(".universal"))O=b;else if(b.endsWith(".universal.ts"))O=b.slice(0,-3);else if(b.endsWith(".universal.mts"))O=b.slice(0,-4);else if(b.endsWith(".universal.js"))O=b.slice(0,-3);else return null;let y=[".mts",".ts"];for(let W of y){let N=O.slice(0,-10)+W,I=await this.resolve(N,l,{skipSelf:!0});if(I){let Z=n?.ssr?"?mode=ssr":"?mode=client";return ie+I.id+Z}try{await Oe(N);let Z=n?.ssr?"?mode=ssr":"?mode=client";return ie+N+Z}catch{}}}return null},async load(t,l){if(t.startsWith(ie)){let n=t.slice(ie.length).split("?")[0],b=F.get(n);return b||(await M(n),b=F.get(n)),b?l?.ssr===!0?b.server:b.client:null}if(l?.ssr!==!0){let n=C.resolve(t);if(d.has(n))return`throw new Error("\u{1F6A8} [B-SSR FIREWALL] BLOCKED: Backend File imported in Client: ${C.basename(t)}");`}return null},transform:$}}function Ke(i){let m=[];return i.paramsType!=="unknown"&&m.push(`params: ${i.paramsType}`),i.queryType!=="unknown"&&m.push(`query: ${i.queryType}`),i.bodyType!=="unknown"&&m.push(`body: ${i.bodyType}`),m.push("signal?: AbortSignal"),m}export{Ae as generateRpcTypes,et as rpcGeneratorPlugin};
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobtail.software/b-ssr",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.66",
|
|
4
4
|
"description": "Fastify + Vite SSR Plugin wrapper with RPC",
|
|
5
5
|
"author": "Victor Moreno <info@bobtail.software> (https://bobtail.software)",
|
|
6
6
|
"license": "GPL-3.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/fastify-b-ssr-plugin.js",
|
|
9
9
|
"types": "./dist/fastify-b-ssr-plugin.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"generate-rpc-types": "./bin/generate-rpc-types.mjs"
|
|
12
|
+
},
|
|
10
13
|
"exports": {
|
|
11
14
|
".": {
|
|
12
15
|
"import": "./dist/fastify-b-ssr-plugin.js",
|
|
@@ -18,6 +21,11 @@
|
|
|
18
21
|
"require": "./dist/vite-rpc-plugin.cjs",
|
|
19
22
|
"types": "./dist/vite-rpc-plugin.d.ts"
|
|
20
23
|
},
|
|
24
|
+
"./type-generator": {
|
|
25
|
+
"import": "./dist/rpc-type-generator.js",
|
|
26
|
+
"require": "./dist/rpc-type-generator.cjs",
|
|
27
|
+
"types": "./dist/rpc-type-generator.d.ts"
|
|
28
|
+
},
|
|
21
29
|
"./client": {
|
|
22
30
|
"import": "./dist/rpc-client.js",
|
|
23
31
|
"require": "./dist/rpc-client.cjs",
|
|
@@ -35,7 +43,8 @@
|
|
|
35
43
|
}
|
|
36
44
|
},
|
|
37
45
|
"files": [
|
|
38
|
-
"dist"
|
|
46
|
+
"dist",
|
|
47
|
+
"bin"
|
|
39
48
|
],
|
|
40
49
|
"keywords": [
|
|
41
50
|
"fastify",
|
|
@@ -57,23 +66,35 @@
|
|
|
57
66
|
"fast-glob": "^3.3.3",
|
|
58
67
|
"fastify-plugin": "^5.1.0",
|
|
59
68
|
"fastify-type-provider-zod": "^6.1.0",
|
|
60
|
-
"ts-morph": "^27.0.2"
|
|
69
|
+
"ts-morph": "^27.0.2",
|
|
70
|
+
"zod": "^4.1.12"
|
|
61
71
|
},
|
|
62
72
|
"devDependencies": {
|
|
73
|
+
"@tanstack/react-router": "^1.139.1",
|
|
63
74
|
"@types/node": "^24.10.0",
|
|
64
75
|
"@types/react": "^19.0.0",
|
|
65
76
|
"@types/react-dom": "^19.0.0",
|
|
66
|
-
"@
|
|
77
|
+
"@types/supertest": "^6.0.0",
|
|
78
|
+
"@vitest/ui": "^2.0.0",
|
|
79
|
+
"fastify": "^5.6.2",
|
|
80
|
+
"happy-dom": "^16.0.0",
|
|
67
81
|
"react": "^18.0.0 || ^19.0.0",
|
|
68
82
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
69
|
-
"
|
|
83
|
+
"supertest": "^7.0.0",
|
|
70
84
|
"tsup": "^8.5.0",
|
|
71
85
|
"typescript": "^5.9.3",
|
|
72
86
|
"vite": "^7.2.4",
|
|
87
|
+
"vitest": "^2.0.0",
|
|
73
88
|
"zod": "^4.1.12"
|
|
74
89
|
},
|
|
75
90
|
"scripts": {
|
|
76
91
|
"build": "tsup",
|
|
77
|
-
"dev": "tsup --watch"
|
|
92
|
+
"dev": "tsup --watch",
|
|
93
|
+
"generate:types": "node bin/generate-rpc-types.mjs",
|
|
94
|
+
"generate:types:clean": "node bin/generate-rpc-types.mjs --clean",
|
|
95
|
+
"test": "vitest",
|
|
96
|
+
"test:ui": "vitest --ui",
|
|
97
|
+
"test:coverage": "vitest --coverage",
|
|
98
|
+
"test:watch": "vitest --watch"
|
|
78
99
|
}
|
|
79
100
|
}
|