@bobtail.software/b-ssr 1.0.50 → 1.0.52
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/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/tanstack-client.cjs +1 -1
- package/dist/tanstack-client.js +1 -1
- package/dist/tanstack-server.cjs +1 -1
- package/dist/tanstack-server.d.cts +2 -1
- package/dist/tanstack-server.d.ts +2 -1
- package/dist/tanstack-server.js +1 -1
- package/dist/vite-rpc-plugin.cjs +30 -26
- package/dist/vite-rpc-plugin.js +30 -26
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var E=Object.create;var S=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,
|
|
1
|
+
"use strict";var E=Object.create;var S=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var I=(e,r)=>{for(var d in r)S(e,d,{get:r[d],enumerable:!0})},v=(e,r,d,f)=>{if(r&&typeof r=="object"||typeof r=="function")for(let l of D(r))!G.call(e,l)&&l!==d&&S(e,l,{get:()=>r[l],enumerable:!(f=x(r,l))||f.enumerable});return e};var R=(e,r,d)=>(d=e!=null?E(O(e)):{},v(r||!e||!e.__esModule?S(d,"default",{value:e,enumerable:!0}):d,e)),k=e=>v(S({},"__esModule",{value:!0}),e);var A={};I(A,{default:()=>b});module.exports=k(A);var _=require("@fastify/multipart"),T=R(require("fastify-plugin"),1),y=R(require("path"),1),g=async(e,r)=>{if(!e.isMultipart())return r.status(415).send({statusCode:415,error:"Unsupported Media Type",message:"Multipart/form-data expected"});let d=e.parts(),f={};for await(let l of d)if(l.type==="field")f[l.fieldname]=l.value;else{let t=Symbol.for("file-stream");e[t]=l}e.body=f},P=async(e,r)=>{let d=t=>{if(r.errorHandler){let a=r.errorHandler(t);if(a)return a}return{message:"Internal Server Error",statusCode:500}};if(e.hasDecorator("viteInitDone")&&e.viteInitDone)return;if(!e.hasDecorator("multipartErrors"))try{let t=await import("@fastify/multipart");await e.register(t.default)}catch(t){if(t.code!=="FST_ERR_DEC_ALREADY_PRESENT")throw t}let f=process.env.NODE_ENV==="production";if(f){if(r.clientDistDir)try{let t=await import("@fastify/static"),a=y.default.resolve(r.root,r.clientDistDir);await e.register(t.default,{root:a,wildcard:!1}),console.log(`\u{1F4C2} [Fastify-SSR] Serving static assets from: ${a}`)}catch(t){console.error("\u274C [Fastify-SSR] Error registering @fastify/static. Did you install it?",t)}}else{if(!e.hasDecorator("use"))try{let o=await import("@fastify/middie");await e.register(o.default,{hook:"onRequest"})}catch(o){if(o.code!=="FST_ERR_DEC_ALREADY_PRESENT")throw o}let t=await import("vite"),a=r.viteConfig||{},m=await t.createServer({root:r.root,appType:"custom",...a,server:{hmr:{port:24678},...a.server,middlewareMode:!0}});e.use(m.middlewares),e.hasDecorator("viteServer")||e.decorate("viteServer",m),console.log("\u{1F680} [Fastify-SSR] Vite Dev Server Ready")}e.decorate("viteInitDone",!0);let l=async(t,a,m)=>{try{let o=t.raw.url,h=r.getGlobalSettings?await r.getGlobalSettings(t):void 0;if(y.default.extname(o)!==""){a.status(404).send(`File not found: ${o}`);return}let s="";!f&&e.viteServer&&(s=await e.viteServer.transformIndexHtml(o,"<html><head></head><body></body></html>"),s=s.substring(s.indexOf("<head>")+6,s.indexOf("</head>"))),s=(h?`<script>window.__GLOBAL_SETTINGS__ = ${JSON.stringify(h)}</script>`:"")+s;let i=f?await import(y.default.resolve(r.root,r.prodEntryFile)):await e.viteServer.ssrLoadModule(r.devEntryFile),n=i.render||i.default;if(typeof n!="function")throw new Error(`Entry file ${r.devEntryFile} must export a 'render' function.`);await n({req:t,reply:a,head:s,data:m})}catch(o){e.viteServer?.ssrFixStacktrace(o),console.error("[SSR Error]:",o),a.sent||a.status(500).send("Internal Server Error")}};e.decorate("addRpcRoute",function(t,a){let{handler:m,schema:o,...h}=a,s=`/rpc${t}`,u={...h,schema:o};if(o?.consumes?.includes("multipart/form-data")){let n=u.preValidation;u.preValidation=n?Array.isArray(n)?[g,...n]:[g,n]:g}this.route({method:"POST",url:s,...u,handler:async(n,c)=>{try{let p=await m.call(this,n,c);return c.sent?void 0:p}catch(p){if(console.error(`[RPC Error] ${s}:`,p),!c.sent){let{statusCode:F,message:w}=d(p);c.status(F).send({error:{message:w}})}}}})}),e.decorate("addRenderRoute",function(t,a){let{handler:m,schema:o,...h}=a||{},s=async(u,i,n)=>{try{let c=await m?.call(this,u,i);return n?c:l(u,i,c)}catch(c){if(console.error(`[Render Error] ${t}:`,c),!i.sent){let{statusCode:p,message:F}=d(c);if(n)i.status(p).send({error:{message:F}});else return l(u,i,{ssrError:{statusCode:500,message:"Internal Error"}})}}};if(this.route({method:"GET",url:t,schema:o,...h,handler:(u,i)=>s(u,i,!1)}),t!=="*"&&t!=="/*"){this.route({method:"GET",url:`/loader${t}`,schema:o,...h,handler:(n,c)=>s(n,c,!0)});let u=t.endsWith("/")?"*":"/*",i=`${t}${u}`;this.route({method:"GET",url:i,schema:o,...h,handler:(n,c)=>s(n,c,!1)})}}),e.decorate("addLoaderRoute",function(t,a){let{handler:m,schema:o,...h}=a,s=`/api${t}`;this.route({method:"GET",url:s,schema:o,...h,handler:async(u,i)=>{try{let n=await m.call(this,u,i);return i.sent?void 0:n}catch(n){if(console.error(`[Loader API Error] ${s}:`,n),!i.sent){let{statusCode:c,message:p}=d(n);i.status(c).send({error:{message:p}})}}}})})},b=(0,T.default)(P,{name:"fastify-b-ssr"});
|
|
@@ -44,6 +44,8 @@ interface FastifyReactSsrOptions {
|
|
|
44
44
|
message: string;
|
|
45
45
|
statusCode: number;
|
|
46
46
|
} | null | undefined;
|
|
47
|
+
/** Función opcional para obtener ajustes globales (ej: de MySQL) que se inyectarán en el SSR */
|
|
48
|
+
getGlobalSettings?: (req: FastifyRequest) => Promise<unknown> | unknown;
|
|
47
49
|
}
|
|
48
50
|
declare module 'fastify' {
|
|
49
51
|
interface FastifyInstance {
|
|
@@ -44,6 +44,8 @@ interface FastifyReactSsrOptions {
|
|
|
44
44
|
message: string;
|
|
45
45
|
statusCode: number;
|
|
46
46
|
} | null | undefined;
|
|
47
|
+
/** Función opcional para obtener ajustes globales (ej: de MySQL) que se inyectarán en el SSR */
|
|
48
|
+
getGlobalSettings?: (req: FastifyRequest) => Promise<unknown> | unknown;
|
|
47
49
|
}
|
|
48
50
|
declare module 'fastify' {
|
|
49
51
|
interface FastifyInstance {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@fastify/multipart";import
|
|
1
|
+
import"@fastify/multipart";import g from"fastify-plugin";import S from"path";var y=async(t,c)=>{if(!t.isMultipart())return c.status(415).send({statusCode:415,error:"Unsupported Media Type",message:"Multipart/form-data expected"});let p=t.parts(),f={};for await(let h of p)if(h.type==="field")f[h.fieldname]=h.value;else{let e=Symbol.for("file-stream");t[e]=h}t.body=f},v=async(t,c)=>{let p=e=>{if(c.errorHandler){let o=c.errorHandler(e);if(o)return o}return{message:"Internal Server Error",statusCode:500}};if(t.hasDecorator("viteInitDone")&&t.viteInitDone)return;if(!t.hasDecorator("multipartErrors"))try{let e=await import("@fastify/multipart");await t.register(e.default)}catch(e){if(e.code!=="FST_ERR_DEC_ALREADY_PRESENT")throw e}let f=process.env.NODE_ENV==="production";if(f){if(c.clientDistDir)try{let e=await import("@fastify/static"),o=S.resolve(c.root,c.clientDistDir);await t.register(e.default,{root:o,wildcard:!1}),console.log(`\u{1F4C2} [Fastify-SSR] Serving static assets from: ${o}`)}catch(e){console.error("\u274C [Fastify-SSR] Error registering @fastify/static. Did you install it?",e)}}else{if(!t.hasDecorator("use"))try{let n=await import("@fastify/middie");await t.register(n.default,{hook:"onRequest"})}catch(n){if(n.code!=="FST_ERR_DEC_ALREADY_PRESENT")throw n}let e=await import("vite"),o=c.viteConfig||{},u=await e.createServer({root:c.root,appType:"custom",...o,server:{hmr:{port:24678},...o.server,middlewareMode:!0}});t.use(u.middlewares),t.hasDecorator("viteServer")||t.decorate("viteServer",u),console.log("\u{1F680} [Fastify-SSR] Vite Dev Server Ready")}t.decorate("viteInitDone",!0);let h=async(e,o,u)=>{try{let n=e.raw.url,l=c.getGlobalSettings?await c.getGlobalSettings(e):void 0;if(S.extname(n)!==""){o.status(404).send(`File not found: ${n}`);return}let a="";!f&&t.viteServer&&(a=await t.viteServer.transformIndexHtml(n,"<html><head></head><body></body></html>"),a=a.substring(a.indexOf("<head>")+6,a.indexOf("</head>"))),a=(l?`<script>window.__GLOBAL_SETTINGS__ = ${JSON.stringify(l)}</script>`:"")+a;let s=f?await import(S.resolve(c.root,c.prodEntryFile)):await t.viteServer.ssrLoadModule(c.devEntryFile),r=s.render||s.default;if(typeof r!="function")throw new Error(`Entry file ${c.devEntryFile} must export a 'render' function.`);await r({req:e,reply:o,head:a,data:u})}catch(n){t.viteServer?.ssrFixStacktrace(n),console.error("[SSR Error]:",n),o.sent||o.status(500).send("Internal Server Error")}};t.decorate("addRpcRoute",function(e,o){let{handler:u,schema:n,...l}=o,a=`/rpc${e}`,d={...l,schema:n};if(n?.consumes?.includes("multipart/form-data")){let r=d.preValidation;d.preValidation=r?Array.isArray(r)?[y,...r]:[y,r]:y}this.route({method:"POST",url:a,...d,handler:async(r,i)=>{try{let m=await u.call(this,r,i);return i.sent?void 0:m}catch(m){if(console.error(`[RPC Error] ${a}:`,m),!i.sent){let{statusCode:R,message:F}=p(m);i.status(R).send({error:{message:F}})}}}})}),t.decorate("addRenderRoute",function(e,o){let{handler:u,schema:n,...l}=o||{},a=async(d,s,r)=>{try{let i=await u?.call(this,d,s);return r?i:h(d,s,i)}catch(i){if(console.error(`[Render Error] ${e}:`,i),!s.sent){let{statusCode:m,message:R}=p(i);if(r)s.status(m).send({error:{message:R}});else return h(d,s,{ssrError:{statusCode:500,message:"Internal Error"}})}}};if(this.route({method:"GET",url:e,schema:n,...l,handler:(d,s)=>a(d,s,!1)}),e!=="*"&&e!=="/*"){this.route({method:"GET",url:`/loader${e}`,schema:n,...l,handler:(r,i)=>a(r,i,!0)});let d=e.endsWith("/")?"*":"/*",s=`${e}${d}`;this.route({method:"GET",url:s,schema:n,...l,handler:(r,i)=>a(r,i,!1)})}}),t.decorate("addLoaderRoute",function(e,o){let{handler:u,schema:n,...l}=o,a=`/api${e}`;this.route({method:"GET",url:a,schema:n,...l,handler:async(d,s)=>{try{let r=await u.call(this,d,s);return s.sent?void 0:r}catch(r){if(console.error(`[Loader API Error] ${a}:`,r),!s.sent){let{statusCode:i,message:m}=p(r);s.status(i).send({error:{message:m}})}}}})})},x=g(v,{name:"fastify-b-ssr"});export{x as default};
|
package/dist/tanstack-client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.create;var a=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var f=(t,o)=>{for(var e in o)a(t,e,{get:o[e],enumerable:!0})},s=(t,o,e,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of p(o))!S.call(t,n)&&n!==e&&a(t,n,{get:()=>o[n],enumerable:!(r=_(o,n))||r.enumerable});return t};var y=(t,o,e)=>(e=t!=null?m(u(t)):{},s(o||!t||!t.__esModule?a(e,"default",{value:t,enumerable:!0}):e,t)),g=t=>s(a({},"__esModule",{value:!0}),t);var w={};f(w,{hydrateClient:()=>R});module.exports=g(w);var d=require("@tanstack/react-router/ssr/client"),l=y(require("react"),1),c=require("react-dom/client"),i=require("react/jsx-runtime");function R(t){let o=t(),e=window.__SSR_DATA__,r=window.__GLOBAL_SETTINGS__;(e||r)&&o.update({context:{...o.options.context,loaderData:e,globalSettings:r}});let n=document.getElementById("root")||document.getElementById("app");n&&!n.innerHTML?(0,c.createRoot)(n).render((0,i.jsx)(l.default.StrictMode,{children:(0,i.jsx)(d.RouterClient,{router:o})})):n&&(0,c.hydrateRoot)(document,(0,i.jsx)(d.RouterClient,{router:o}))}0&&(module.exports={hydrateClient});
|
package/dist/tanstack-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RouterClient as
|
|
1
|
+
import{RouterClient as a}from"@tanstack/react-router/ssr/client";import c from"react";import{createRoot as d,hydrateRoot as s}from"react-dom/client";import{jsx as e}from"react/jsx-runtime";function u(i){let t=i(),n=window.__SSR_DATA__,r=window.__GLOBAL_SETTINGS__;(n||r)&&t.update({context:{...t.options.context,loaderData:n,globalSettings:r}});let o=document.getElementById("root")||document.getElementById("app");o&&!o.innerHTML?d(o).render(e(c.StrictMode,{children:e(a,{router:t})})):o&&s(document,e(a,{router:t}))}export{u as hydrateClient};
|
package/dist/tanstack-server.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var h=Object.defineProperty;var
|
|
1
|
+
"use strict";var h=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var q=(e,t)=>{for(var n in t)h(e,n,{get:t[n],enumerable:!0})},g=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of p(t))!m.call(e,r)&&r!==n&&h(e,r,{get:()=>t[r],enumerable:!(o=y(t,r))||o.enumerable});return e};var w=e=>g(h({},"__esModule",{value:!0}),e);var S={};q(S,{createServerHandler:()=>x});module.exports=w(S);var u=require("@tanstack/react-router/ssr/server"),l=require("react/jsx-runtime");function F(e){let t=e.protocol,n=e.hostname,o=`${t}://${n}`,r=new URL(e.url,o||"http://localhost:3000").href,c=new Headers;for(let[d,a]of Object.entries(e.headers))a&&c.set(d,Array.isArray(a)?a.join(", "):a);return new Request(r,{method:e.method,headers:c})}function x(e){return async function({req:n,reply:o,head:r,data:c,globalSettings:d}){let a=F(n),f=await(0,u.createRequestHandler)({request:a,createRouter:()=>{let s=e(),i=s.options.context||{};return s.update({context:{...i,head:r,req:n,reply:o,loaderData:c,globalSettings:d}}),s}})(({request:s,responseHeaders:i,router:R})=>(0,u.renderRouterToStream)({request:s,responseHeaders:i,router:R,children:(0,l.jsx)(u.RouterServer,{router:R})}));return o.status(f.status),f.headers.forEach((s,i)=>{o.header(i,s)}),o.send(f.body)}}0&&(module.exports={createServerHandler});
|
|
@@ -5,6 +5,7 @@ interface RenderOptions {
|
|
|
5
5
|
reply: FastifyReply;
|
|
6
6
|
head: string;
|
|
7
7
|
data?: unknown;
|
|
8
|
+
globalSettings?: unknown;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* Crea el handler de renderizado SSR para TanStack Router.
|
|
@@ -12,6 +13,6 @@ interface RenderOptions {
|
|
|
12
13
|
* @param createRouterFn Función que devuelve una instancia del Router
|
|
13
14
|
* @returns Una función `render` lista para ser exportada en entry-server.tsx
|
|
14
15
|
*/
|
|
15
|
-
declare function createServerHandler(createRouterFn: () => any): ({ req, reply, head, data }: RenderOptions) => Promise<never>;
|
|
16
|
+
declare function createServerHandler(createRouterFn: () => any): ({ req, reply, head, data, globalSettings }: RenderOptions) => Promise<never>;
|
|
16
17
|
|
|
17
18
|
export { type RenderOptions, createServerHandler };
|
|
@@ -5,6 +5,7 @@ interface RenderOptions {
|
|
|
5
5
|
reply: FastifyReply;
|
|
6
6
|
head: string;
|
|
7
7
|
data?: unknown;
|
|
8
|
+
globalSettings?: unknown;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* Crea el handler de renderizado SSR para TanStack Router.
|
|
@@ -12,6 +13,6 @@ interface RenderOptions {
|
|
|
12
13
|
* @param createRouterFn Función que devuelve una instancia del Router
|
|
13
14
|
* @returns Una función `render` lista para ser exportada en entry-server.tsx
|
|
14
15
|
*/
|
|
15
|
-
declare function createServerHandler(createRouterFn: () => any): ({ req, reply, head, data }: RenderOptions) => Promise<never>;
|
|
16
|
+
declare function createServerHandler(createRouterFn: () => any): ({ req, reply, head, data, globalSettings }: RenderOptions) => Promise<never>;
|
|
16
17
|
|
|
17
18
|
export { type RenderOptions, createServerHandler };
|
package/dist/tanstack-server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequestHandler as h,renderRouterToStream as R,RouterServer as
|
|
1
|
+
import{createRequestHandler as h,renderRouterToStream as R,RouterServer as l}from"@tanstack/react-router/ssr/server";import{jsx as p}from"react/jsx-runtime";function y(e){let d=e.protocol,s=e.hostname,n=`${d}://${s}`,u=new URL(e.url,n||"http://localhost:3000").href,a=new Headers;for(let[i,o]of Object.entries(e.headers))o&&a.set(i,Array.isArray(o)?o.join(", "):o);return new Request(u,{method:e.method,headers:a})}function g(e){return async function({req:s,reply:n,head:u,data:a,globalSettings:i}){let o=y(s),c=await h({request:o,createRouter:()=>{let t=e(),r=t.options.context||{};return t.update({context:{...r,head:u,req:s,reply:n,loaderData:a,globalSettings:i}}),t}})(({request:t,responseHeaders:r,router:f})=>R({request:t,responseHeaders:r,router:f,children:p(l,{router:f})}));return n.status(c.status),c.headers.forEach((t,r)=>{n.header(r,t)}),n.send(c.body)}}export{g as createServerHandler};
|
package/dist/vite-rpc-plugin.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var de=Object.create;var
|
|
1
|
+
"use strict";var de=Object.create;var I=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var ye=Object.getPrototypeOf,he=Object.prototype.hasOwnProperty;var be=(o,l)=>{for(var x in l)I(o,x,{get:l[x],enumerable:!0})},te=(o,l,x,C)=>{if(l&&typeof l=="object"||typeof l=="function")for(let w of fe(l))!he.call(o,w)&&w!==x&&I(o,w,{get:()=>l[w],enumerable:!(C=me(l,w))||C.enumerable});return o};var re=(o,l,x)=>(x=o!=null?de(ye(o)):{},te(l||!o||!o.__esModule?I(x,"default",{value:o,enumerable:!0}):x,o)),Te=o=>te(I({},"__esModule",{value:!0}),o);var Se={};be(Se,{rpcGeneratorPlugin:()=>Pe});module.exports=Te(Se);var se=re(require("fast-glob"),1),q=require("fs/promises"),a=re(require("path"),1),K=require("prettier"),s=require("ts-morph"),L="virtual:b-ssr-rpc-universal:";function xe(o){let l=o.replace(/[^a-zA-Z0-9]+(.)?/g,(x,C)=>C?C.toUpperCase():"");return l.charAt(0).toLowerCase()+l.slice(1)}function Z(o,l,x){let C=a.default.basename(x,a.default.extname(x))||"Index",w=l.replace(/:[a-zA-Z0-9_]+/g,"").replace(/\//g," "),j=`${o} ${w} ${C}`;return xe(j)}function Pe(o={}){let{routerPattern:l="src-ts/routers/**/*.mts",tsConfigFilePath:x="tsconfig.json",routerBaseDir:C="src-ts/routers"}=o,w=new Map,j=new Set,B=new s.Project({tsConfigFilePath:x,skipAddingFilesFromTsConfig:!1}),ne=a.default.resolve(process.cwd(),C||".");async function W(t){try{let D=function(e){return e.replace(/import\(['"](.*?)['"]\)/g,(p,i)=>{if(!a.default.isAbsolute(i))return p;let n=i;if(!a.default.extname(n)){let T=B.getSourceFile(y=>y.getFilePath().replace(/\.(mts|ts|tsx)$/,"")===i);T&&(n=T.getFilePath())}let u=a.default.relative(a.default.dirname(M),n).replace(/\\/g,"/");return u.startsWith(".")||(u="./"+u),`import("${u}")`})},O=function(e,p){if(e.getSymbol()?.getName()==="Promise"){let d=e.getAwaitedType();if(d)return`Promise<${O(d,p)}>`}let i=e.getAliasSymbol()??e.getSymbol();if(i?.getName()==="__object")return D(e.getText(p,s.ts.TypeFormatFlags.NoTruncation|s.ts.TypeFormatFlags.UseFullyQualifiedType));if(e.isObject()&&!i){let d=(f,h=0)=>{if(!(h>5)){if(f.isArray()){let P=f.getArrayElementType();P&&d(P,h);return}if(f.isObject()&&!f.getSymbol()&&!f.getAliasSymbol()){for(let P of f.getApparentProperties()){let $=P.getValueDeclaration();$&&d(P.getTypeAtLocation($),h+1)}return}O(f,p)}};return d(e),D(e.getText(p,s.ts.TypeFormatFlags.NoTruncation|s.ts.TypeFormatFlags.UseFullyQualifiedType))}if(!i)return D(e.getText(p,s.ts.TypeFormatFlags.NoTruncation));let n=i.getDeclarations()[0];if(!n)return i.getName();if(s.Node.isImportSpecifier(n)||s.Node.isImportClause(n)){let d=n.getFirstAncestorByKind(s.SyntaxKind.ImportDeclaration);if(d){let f=d.getModuleSpecifierValue(),h=i.getName();return v.has(f)||v.set(f,new Set),v.get(f)?.add(h),h}}let u=n.getSourceFile();if(u.getFilePath()===b.getFilePath())return i.getName();if(u.isInNodeModules())return D(e.getText(p,s.ts.TypeFormatFlags.NoTruncation));let T=a.default.relative(a.default.dirname(M),u.getFilePath()).replace(/\\/g,"/"),E=T.startsWith(".")?T:`./${T}`,S=i.getName();return v.has(E)||v.set(E,new Set),v.get(E)?.add(S),S},Q=function(e){let p;if(s.Node.isFunctionLikeDeclaration(e)||s.Node.isArrowFunction(e)){let i=e.getDescendantsOfKind(s.SyntaxKind.ReturnStatement);for(let n of i){let u=n.getExpression();if(u?.isKind(s.SyntaxKind.SatisfiesExpression)){p=u.getTypeNode()?.getType();break}}}if(p)return O(p,e);{let i=e.getType().getCallSignatures();if(i.length>0){let n=i[0]?.getReturnType();return O(n,e)}}return"unknown"};var m=D,r=O,g=Q;let b=B.addSourceFileAtPath(t);await b.refreshFromFileSystem(),B.resolveSourceFileDependencies();let c=b.getDescendantsOfKind(s.SyntaxKind.CallExpression),A=c.filter(e=>e.getExpression().getText().endsWith(".addRpcRoute")),F=c.filter(e=>e.getExpression().getText().endsWith(".addRenderRoute")),R=c.filter(e=>e.getExpression().getText().endsWith(".addLoaderRoute")),k=a.default.extname(t),M=t.substring(0,t.length-k.length)+".universal.d.ts",V=a.default.resolve(t);if(A.length===0&&F.length===0&&R.length===0){w.delete(V),j.delete(V),M!==t&&await(0,q.unlink)(M).catch(()=>{});return}j.add(V);let _=[],v=new Map;v.has("fastify")||v.set("fastify",new Set),v.get("fastify")?.add("FastifyRequest"),v.get("fastify")?.add("FastifyReply");let ce=e=>{let p="unknown",i="unknown",n="unknown",u=!1;if(!e||!s.Node.isObjectLiteralExpression(e))return{paramsType:p,queryType:i,bodyType:n,isMultipart:u};let T=e.getProperty("schema");if(T?.isKind(s.SyntaxKind.PropertyAssignment)){let y=T.getInitializer();if(y?.isKind(s.SyntaxKind.Identifier)){let S=y.getSymbol()?.getValueDeclaration();if(S){let d=S.getFirstDescendantByKind(s.SyntaxKind.ObjectLiteralExpression);d&&(y=d)}}if(y&&s.Node.isObjectLiteralExpression(y)){let E=y.getProperty("consumes");if(E?.isKind(s.SyntaxKind.PropertyAssignment)){let d=E.getInitializer();s.Node.isArrayLiteralExpression(d)&&(u=d.getElements().some(f=>f.isKind(s.SyntaxKind.StringLiteral)&&f.getLiteralValue()==="multipart/form-data"))}let S=d=>{let f=y.getProperty(d);if(f?.isKind(s.SyntaxKind.PropertyAssignment)){let h=f.getInitializer();if(h){let P=h.getType(),$=P.getProperty("_output");return O($?$.getTypeAtLocation(h).getApparentType():P,h)}}return"unknown"};if(p=S("params"),i=S("querystring"),n=S("body"),u){let d="{ file: File }";n=n!=="unknown"&&n.trim().startsWith("{")?`(${n} & ${d})`:d}}}return{paramsType:p,queryType:i,bodyType:n,isMultipart:u}},N=a.default.relative(ne,a.default.dirname(t)).split(a.default.sep).join("/"),pe=N==="."||!N?"":N.startsWith("/")?N:"/"+N,z=(e,p)=>{let[i,n]=e.getArguments();if(!i?.isKind(s.SyntaxKind.StringLiteral))return;let u=i.getLiteralValue(),T="unknown",y=pe,{paramsType:E,queryType:S,bodyType:d,isMultipart:f}=ce(n);if(n?.isKind(s.SyntaxKind.ObjectLiteralExpression)){let $=n.getProperty("prefix");if($?.isKind(s.SyntaxKind.PropertyAssignment)){let U=$.getInitializer();U?.isKind(s.SyntaxKind.StringLiteral)&&(y=U.getLiteralValue())}let ee=n.getProperty("handler");if(ee?.isKind(s.SyntaxKind.PropertyAssignment)){let U=ee.getInitializer();U&&(T=Q(U),T.startsWith("Promise<")||(T=`Promise<${T}>`))}}let h="",P="";p==="rpc"?(h=a.default.join(y,"rpc",u).replace(/\\/g,"/"),P=Z("action",y,u)):p==="loader"?(h=a.default.join(y,"loader",u).replace(/\\/g,"/"),P=Z("loader",y,u)):p==="api"&&(h=a.default.join(y,"api",u).replace(/\\/g,"/"),P=Z("get",y,u)),P&&_.push({type:p,name:P,returnType:T,url:u,rpcUrl:h,loaderUrl:h,paramsType:E,queryType:S,bodyType:d,isMultipart:f})};A.forEach(e=>z(e,"rpc")),F.forEach(e=>z(e,"loader")),R.forEach(e=>z(e,"api"));let H=[];for(let[e,p]of v.entries())H.push(`import type { ${[...p].sort().join(", ")} } from "${e}";`);let X=[];_.forEach(e=>{X.push(ie(e))});let G=`// AUTO-GENERATED by @bobtail.software/b-ssr. DO NOT EDIT.
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
|
|
4
4
|
`+(H.length>0?H.join(`
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
`:"")+X.join(`
|
|
8
8
|
|
|
9
|
-
`);try{let e=await(0,
|
|
9
|
+
`);try{let e=await(0,K.resolveConfig)(M)||{};G=await(0,K.format)(G,{...e,parser:"typescript",filepath:M})}catch{}await(0,q.writeFile)(M,G);let Y=[],J=[];_.forEach(e=>{let i=e.type==="rpc"?"POST":"GET",n=e.type==="loader"?e.loaderUrl:e.rpcUrl;J.push({name:e.name,rpcUrl:n,method:i,isMultipart:!!e.isMultipart}),Y.push({name:e.name,url:e.url,type:e.type,requiresArgs:!0})});let ue=`
|
|
10
10
|
import { createClientRpc } from '@bobtail.software/b-ssr/client';
|
|
11
11
|
|
|
12
12
|
if (import.meta.env.DEV) {
|
|
13
|
-
console.debug('\u{1F6E1}\uFE0F [B-SSR Security] Loaded SAFE Client-Stub for: ${
|
|
13
|
+
console.debug('\u{1F6E1}\uFE0F [B-SSR Security] Loaded SAFE Client-Stub for: ${a.default.basename(t)}');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
${J.map(e=>`
|
|
@@ -21,15 +21,17 @@
|
|
|
21
21
|
});
|
|
22
22
|
`).join(`
|
|
23
23
|
`)}
|
|
24
|
-
`,ge=ae(Y,t);
|
|
24
|
+
`,ge=ae(Y,t);w.set(a.default.resolve(t),{client:ue,server:ge})}catch(b){console.error(`[rpc-generator] Error al procesar ${t}:`,{error:b})}}let oe=(t,m,r)=>{if(m.includes("node_modules")||m.startsWith(L))return null;if(r?.ssr===!0&&/\.[cm]?[jt]sx?$/.test(m)){let g=/\brequire\s*\(/.test(t),b=/\bmodule\.exports\b/.test(t),c=/\bexports\./.test(t);if(g||b||c)return"import { createRequire } from 'module';"+`
|
|
25
25
|
const require = createRequire(import.meta.url);
|
|
26
26
|
const module = { exports: {} };
|
|
27
27
|
const exports = module.exports;
|
|
28
28
|
`+t+`
|
|
29
|
-
export default module.exports;`}return null};function
|
|
30
|
-
|
|
29
|
+
export default module.exports;`}return null};function ie(t){let m=we(t),r="";return m.length>0&&(r=`args: { ${m.join("; ")} }`),r||(r="args: { signal?: AbortSignal }"),`export declare const ${t.name}: (${r}, ssrContext?: { req?: FastifyRequest, reply?: FastifyReply }) => ${t.returnType};`}function ae(t,m){if(t.length===0)return"";let r=a.default.relative(process.cwd(),m).replace(/\\/g,"/");return`
|
|
30
|
+
import path from 'path';
|
|
31
|
+
import { pathToFileURL } from 'url';
|
|
32
|
+
|
|
31
33
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
32
|
-
throw new Error('\u{1F6A8} [B-SSR SECURITY ALERT] Server-side code leaked to browser: ${
|
|
34
|
+
throw new Error('\u{1F6A8} [B-SSR SECURITY ALERT] Server-side code leaked to browser: ${`./${a.default.relative(process.cwd(),m).replace(/\\/g,"/")}`}');
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
let initPromise;
|
|
@@ -42,7 +44,9 @@ export default module.exports;`}return null};function oe(t){let m=we(t),n="";ret
|
|
|
42
44
|
rpcOptionsMap = new Map();
|
|
43
45
|
renderOptionsMap = new Map();
|
|
44
46
|
loaderApiOptionsMap = new Map();
|
|
45
|
-
const
|
|
47
|
+
const projectRoot = process.cwd();
|
|
48
|
+
const absolutePath = path.resolve(projectRoot, '${r}');
|
|
49
|
+
const serverModuleUrl = pathToFileURL(absolutePath).href;
|
|
46
50
|
|
|
47
51
|
if (typeof globalThis.require === 'undefined') {
|
|
48
52
|
try {
|
|
@@ -51,7 +55,7 @@ export default module.exports;`}return null};function oe(t){let m=we(t),n="";ret
|
|
|
51
55
|
} catch (e) {}
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
const routeModule = await import(/* @vite-ignore */
|
|
58
|
+
const routeModule = await import(/* @vite-ignore */ serverModuleUrl);
|
|
55
59
|
|
|
56
60
|
const mockMethods = {
|
|
57
61
|
addRpcRoute: (url, options) => rpcOptionsMap.set(url, options),
|
|
@@ -89,46 +93,46 @@ export default module.exports;`}return null};function oe(t){let m=we(t),n="";ret
|
|
|
89
93
|
return initPromise;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
${t.map(
|
|
96
|
+
${t.map(c=>{let A=[];c.requiresArgs&&A.push("args"),A.push("ssrContext");let F=c.requiresArgs?"args":"{}",R="";return c.type==="rpc"?R=`
|
|
93
97
|
if (fn.isMultipart) throw new Error('RPC multipart no soportado en SSR.');
|
|
94
98
|
await getOptionsMaps();
|
|
95
|
-
const options = rpcOptionsMap.get('${
|
|
96
|
-
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${
|
|
97
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
99
|
+
const options = rpcOptionsMap.get('${c.url}');
|
|
100
|
+
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${c.name}');
|
|
101
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${F});
|
|
98
102
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
99
|
-
`:
|
|
103
|
+
`:c.type==="api"?R=`
|
|
100
104
|
await getOptionsMaps();
|
|
101
|
-
const options = loaderApiOptionsMap.get('${
|
|
105
|
+
const options = loaderApiOptionsMap.get('${c.url}');
|
|
102
106
|
if (!options?.handler) {
|
|
103
|
-
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${
|
|
107
|
+
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${c.name}', 'URL:', '${c.url}');
|
|
104
108
|
return null;
|
|
105
109
|
}
|
|
106
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
110
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${F});
|
|
107
111
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
108
|
-
`:
|
|
112
|
+
`:R=`
|
|
109
113
|
await getOptionsMaps();
|
|
110
|
-
const options = renderOptionsMap.get('${
|
|
114
|
+
const options = renderOptionsMap.get('${c.url}');
|
|
111
115
|
if (!options) return {};
|
|
112
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
116
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${F});
|
|
113
117
|
let customData = {};
|
|
114
118
|
try {
|
|
115
119
|
if (options.handler) {
|
|
116
120
|
customData = (await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply)) || {};
|
|
117
121
|
}
|
|
118
122
|
} catch (handlerErr) {
|
|
119
|
-
console.error('\u274C [B-SSR Handler Error] ${
|
|
123
|
+
console.error('\u274C [B-SSR Handler Error] ${c.name}:', handlerErr);
|
|
120
124
|
return {};
|
|
121
125
|
}
|
|
122
126
|
if (ssrContext.reply.sent) return;
|
|
123
127
|
return { ...customData };
|
|
124
|
-
`,`export const ${
|
|
128
|
+
`,`export const ${c.name} = async (${A.join(", ")}) => {
|
|
125
129
|
try {
|
|
126
|
-
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${
|
|
127
|
-
${
|
|
130
|
+
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${c.name} (SSR)');
|
|
131
|
+
${R}
|
|
128
132
|
} catch (error) {
|
|
129
|
-
console.error('\u274C [B-SSR Error] ${
|
|
133
|
+
console.error('\u274C [B-SSR Error] ${c.name}:', error);
|
|
130
134
|
throw error;
|
|
131
135
|
}
|
|
132
136
|
};`}).join(`
|
|
133
137
|
`)}
|
|
134
|
-
`}async function le(){let t=await(0,
|
|
138
|
+
`}async function le(){let t=await(0,se.default)(l,{absolute:!0});await Promise.all(t.map(m=>W(m)))}return{name:"b-ssr-vite-plugin-rpc-universal-generator",enforce:"pre",async buildStart(){await le()},configureServer(t){let m=r=>r.endsWith(".mts")||r.endsWith(".ts");t.watcher.on("add",r=>m(r)&&W(r)),t.watcher.on("change",r=>m(r)&&W(r)),t.watcher.on("unlink",r=>{if(m(r)){let g=a.default.resolve(r);w.delete(g),j.delete(g);let b=a.default.extname(r),c=r.substring(0,r.length-b.length)+".universal.d.ts";(0,q.unlink)(c).catch(()=>{})}})},async resolveId(t,m,r){if(t.startsWith(L))return null;if(t.includes(".universal")){let g=t.split("?")[0],b=g;if(g.endsWith(".universal"))b=g;else if(g.endsWith(".universal.ts"))b=g.slice(0,-3);else if(g.endsWith(".universal.mts"))b=g.slice(0,-4);else if(g.endsWith(".universal.js"))b=g.slice(0,-3);else return null;let c=[".mts",".ts"];for(let A of c){let F=b.slice(0,-10)+A,R=await this.resolve(F,m,{skipSelf:!0});if(R){let k=r?.ssr?"?mode=ssr":"?mode=client";return L+R.id+k}try{await(0,q.access)(F);let k=r?.ssr?"?mode=ssr":"?mode=client";return L+F+k}catch{}}}return null},async load(t,m){if(t.startsWith(L)){let r=t.slice(L.length).split("?")[0],g=w.get(r);return g||(await W(r),g=w.get(r)),g?m?.ssr===!0?g.server:g.client:null}if(m?.ssr!==!0){let r=a.default.resolve(t);if(j.has(r))return`throw new Error("\u{1F6A8} [B-SSR FIREWALL] BLOCKED: Backend File imported in Client: ${a.default.basename(t)}");`}return null},transform:oe}}function we(o){let l=[];return o.paramsType!=="unknown"&&l.push(`params: ${o.paramsType}`),o.queryType!=="unknown"&&l.push(`query: ${o.queryType}`),o.bodyType!=="unknown"&&l.push(`body: ${o.bodyType}`),l.push("signal?: AbortSignal"),l}0&&(module.exports={rpcGeneratorPlugin});
|
package/dist/vite-rpc-plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import pe from"fast-glob";import{access as ue,unlink as ee,writeFile as ge}from"fs/promises";import
|
|
1
|
+
import pe from"fast-glob";import{access as ue,unlink as ee,writeFile as ge}from"fs/promises";import o from"path";import{format as de,resolveConfig as me}from"prettier";import{Node as M,Project as fe,SyntaxKind as h,ts as j}from"ts-morph";var L="virtual:b-ssr-rpc-universal:";function ye(T){let x=T.replace(/[^a-zA-Z0-9]+(.)?/g,(k,O)=>O?O.toUpperCase():"");return x.charAt(0).toLowerCase()+x.slice(1)}function G(T,x,k){let O=o.basename(k,o.extname(k))||"Index",C=x.replace(/:[a-zA-Z0-9_]+/g,"").replace(/\//g," "),q=`${T} ${C} ${O}`;return ye(q)}function Re(T={}){let{routerPattern:x="src-ts/routers/**/*.mts",tsConfigFilePath:k="tsconfig.json",routerBaseDir:O="src-ts/routers"}=T,C=new Map,q=new Set,K=new fe({tsConfigFilePath:k,skipAddingFilesFromTsConfig:!1}),te=o.resolve(process.cwd(),O||".");async function I(t){try{let N=function(e){return e.replace(/import\(['"](.*?)['"]\)/g,(a,n)=>{if(!o.isAbsolute(n))return a;let s=n;if(!o.extname(s)){let y=K.getSourceFile(d=>d.getFilePath().replace(/\.(mts|ts|tsx)$/,"")===n);y&&(s=y.getFilePath())}let l=o.relative(o.dirname(A),s).replace(/\\/g,"/");return l.startsWith(".")||(l="./"+l),`import("${l}")`})},$=function(e,a){if(e.getSymbol()?.getName()==="Promise"){let p=e.getAwaitedType();if(p)return`Promise<${$(p,a)}>`}let n=e.getAliasSymbol()??e.getSymbol();if(n?.getName()==="__object")return N(e.getText(a,j.TypeFormatFlags.NoTruncation|j.TypeFormatFlags.UseFullyQualifiedType));if(e.isObject()&&!n){let p=(g,m=0)=>{if(!(m>5)){if(g.isArray()){let b=g.getArrayElementType();b&&p(b,m);return}if(g.isObject()&&!g.getSymbol()&&!g.getAliasSymbol()){for(let b of g.getApparentProperties()){let E=b.getValueDeclaration();E&&p(b.getTypeAtLocation(E),m+1)}return}$(g,a)}};return p(e),N(e.getText(a,j.TypeFormatFlags.NoTruncation|j.TypeFormatFlags.UseFullyQualifiedType))}if(!n)return N(e.getText(a,j.TypeFormatFlags.NoTruncation));let s=n.getDeclarations()[0];if(!s)return n.getName();if(M.isImportSpecifier(s)||M.isImportClause(s)){let p=s.getFirstAncestorByKind(h.ImportDeclaration);if(p){let g=p.getModuleSpecifierValue(),m=n.getName();return F.has(g)||F.set(g,new Set),F.get(g)?.add(m),m}}let l=s.getSourceFile();if(l.getFilePath()===f.getFilePath())return n.getName();if(l.isInNodeModules())return N(e.getText(a,j.TypeFormatFlags.NoTruncation));let y=o.relative(o.dirname(A),l.getFilePath()).replace(/\\/g,"/"),R=y.startsWith(".")?y:`./${y}`,P=n.getName();return F.has(R)||F.set(R,new Set),F.get(R)?.add(P),P},Z=function(e){let a;if(M.isFunctionLikeDeclaration(e)||M.isArrowFunction(e)){let n=e.getDescendantsOfKind(h.ReturnStatement);for(let s of n){let l=s.getExpression();if(l?.isKind(h.SatisfiesExpression)){a=l.getTypeNode()?.getType();break}}}if(a)return $(a,e);{let n=e.getType().getCallSignatures();if(n.length>0){let s=n[0]?.getReturnType();return $(s,e)}}return"unknown"};var u=N,r=$,c=Z;let f=K.addSourceFileAtPath(t);await f.refreshFromFileSystem(),K.resolveSourceFileDependencies();let i=f.getDescendantsOfKind(h.CallExpression),v=i.filter(e=>e.getExpression().getText().endsWith(".addRpcRoute")),w=i.filter(e=>e.getExpression().getText().endsWith(".addRenderRoute")),S=i.filter(e=>e.getExpression().getText().endsWith(".addLoaderRoute")),D=o.extname(t),A=t.substring(0,t.length-D.length)+".universal.d.ts",B=o.resolve(t);if(v.length===0&&w.length===0&&S.length===0){C.delete(B),q.delete(B),A!==t&&await ee(A).catch(()=>{});return}q.add(B);let V=[],F=new Map;F.has("fastify")||F.set("fastify",new Set),F.get("fastify")?.add("FastifyRequest"),F.get("fastify")?.add("FastifyReply");let ie=e=>{let a="unknown",n="unknown",s="unknown",l=!1;if(!e||!M.isObjectLiteralExpression(e))return{paramsType:a,queryType:n,bodyType:s,isMultipart:l};let y=e.getProperty("schema");if(y?.isKind(h.PropertyAssignment)){let d=y.getInitializer();if(d?.isKind(h.Identifier)){let P=d.getSymbol()?.getValueDeclaration();if(P){let p=P.getFirstDescendantByKind(h.ObjectLiteralExpression);p&&(d=p)}}if(d&&M.isObjectLiteralExpression(d)){let R=d.getProperty("consumes");if(R?.isKind(h.PropertyAssignment)){let p=R.getInitializer();M.isArrayLiteralExpression(p)&&(l=p.getElements().some(g=>g.isKind(h.StringLiteral)&&g.getLiteralValue()==="multipart/form-data"))}let P=p=>{let g=d.getProperty(p);if(g?.isKind(h.PropertyAssignment)){let m=g.getInitializer();if(m){let b=m.getType(),E=b.getProperty("_output");return $(E?E.getTypeAtLocation(m).getApparentType():b,m)}}return"unknown"};if(a=P("params"),n=P("querystring"),s=P("body"),l){let p="{ file: File }";s=s!=="unknown"&&s.trim().startsWith("{")?`(${s} & ${p})`:p}}}return{paramsType:a,queryType:n,bodyType:s,isMultipart:l}},U=o.relative(te,o.dirname(t)).split(o.sep).join("/"),ae=U==="."||!U?"":U.startsWith("/")?U:"/"+U,_=(e,a)=>{let[n,s]=e.getArguments();if(!n?.isKind(h.StringLiteral))return;let l=n.getLiteralValue(),y="unknown",d=ae,{paramsType:R,queryType:P,bodyType:p,isMultipart:g}=ie(s);if(s?.isKind(h.ObjectLiteralExpression)){let E=s.getProperty("prefix");if(E?.isKind(h.PropertyAssignment)){let W=E.getInitializer();W?.isKind(h.StringLiteral)&&(d=W.getLiteralValue())}let J=s.getProperty("handler");if(J?.isKind(h.PropertyAssignment)){let W=J.getInitializer();W&&(y=Z(W),y.startsWith("Promise<")||(y=`Promise<${y}>`))}}let m="",b="";a==="rpc"?(m=o.join(d,"rpc",l).replace(/\\/g,"/"),b=G("action",d,l)):a==="loader"?(m=o.join(d,"loader",l).replace(/\\/g,"/"),b=G("loader",d,l)):a==="api"&&(m=o.join(d,"api",l).replace(/\\/g,"/"),b=G("get",d,l)),b&&V.push({type:a,name:b,returnType:y,url:l,rpcUrl:m,loaderUrl:m,paramsType:R,queryType:P,bodyType:p,isMultipart:g})};v.forEach(e=>_(e,"rpc")),w.forEach(e=>_(e,"loader")),S.forEach(e=>_(e,"api"));let z=[];for(let[e,a]of F.entries())z.push(`import type { ${[...a].sort().join(", ")} } from "${e}";`);let Q=[];V.forEach(e=>{Q.push(se(e))});let H=`// AUTO-GENERATED by @bobtail.software/b-ssr. DO NOT EDIT.
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
|
|
4
4
|
`+(z.length>0?z.join(`
|
|
@@ -6,11 +6,11 @@ import pe from"fast-glob";import{access as ue,unlink as ee,writeFile as ge}from"
|
|
|
6
6
|
|
|
7
7
|
`:"")+Q.join(`
|
|
8
8
|
|
|
9
|
-
`);try{let e=await me(
|
|
9
|
+
`);try{let e=await me(A)||{};H=await de(H,{...e,parser:"typescript",filepath:A})}catch{}await ge(A,H);let X=[],Y=[];V.forEach(e=>{let n=e.type==="rpc"?"POST":"GET",s=e.type==="loader"?e.loaderUrl:e.rpcUrl;Y.push({name:e.name,rpcUrl:s,method:n,isMultipart:!!e.isMultipart}),X.push({name:e.name,url:e.url,type:e.type,requiresArgs:!0})});let le=`
|
|
10
10
|
import { createClientRpc } from '@bobtail.software/b-ssr/client';
|
|
11
11
|
|
|
12
12
|
if (import.meta.env.DEV) {
|
|
13
|
-
console.debug('\u{1F6E1}\uFE0F [B-SSR Security] Loaded SAFE Client-Stub for: ${
|
|
13
|
+
console.debug('\u{1F6E1}\uFE0F [B-SSR Security] Loaded SAFE Client-Stub for: ${o.basename(t)}');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
${Y.map(e=>`
|
|
@@ -21,15 +21,17 @@ import pe from"fast-glob";import{access as ue,unlink as ee,writeFile as ge}from"
|
|
|
21
21
|
});
|
|
22
22
|
`).join(`
|
|
23
23
|
`)}
|
|
24
|
-
`,ce=
|
|
24
|
+
`,ce=ne(X,t);C.set(o.resolve(t),{client:le,server:ce})}catch(f){console.error(`[rpc-generator] Error al procesar ${t}:`,{error:f})}}let re=(t,u,r)=>{if(u.includes("node_modules")||u.startsWith(L))return null;if(r?.ssr===!0&&/\.[cm]?[jt]sx?$/.test(u)){let c=/\brequire\s*\(/.test(t),f=/\bmodule\.exports\b/.test(t),i=/\bexports\./.test(t);if(c||f||i)return"import { createRequire } from 'module';"+`
|
|
25
25
|
const require = createRequire(import.meta.url);
|
|
26
26
|
const module = { exports: {} };
|
|
27
27
|
const exports = module.exports;
|
|
28
28
|
`+t+`
|
|
29
|
-
export default module.exports;`}return null};function
|
|
30
|
-
|
|
29
|
+
export default module.exports;`}return null};function se(t){let u=he(t),r="";return u.length>0&&(r=`args: { ${u.join("; ")} }`),r||(r="args: { signal?: AbortSignal }"),`export declare const ${t.name}: (${r}, ssrContext?: { req?: FastifyRequest, reply?: FastifyReply }) => ${t.returnType};`}function ne(t,u){if(t.length===0)return"";let r=o.relative(process.cwd(),u).replace(/\\/g,"/");return`
|
|
30
|
+
import path from 'path';
|
|
31
|
+
import { pathToFileURL } from 'url';
|
|
32
|
+
|
|
31
33
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
32
|
-
throw new Error('\u{1F6A8} [B-SSR SECURITY ALERT] Server-side code leaked to browser: ${o}');
|
|
34
|
+
throw new Error('\u{1F6A8} [B-SSR SECURITY ALERT] Server-side code leaked to browser: ${`./${o.relative(process.cwd(),u).replace(/\\/g,"/")}`}');
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
let initPromise;
|
|
@@ -42,7 +44,9 @@ export default module.exports;`}return null};function ne(t){let u=he(t),r="";ret
|
|
|
42
44
|
rpcOptionsMap = new Map();
|
|
43
45
|
renderOptionsMap = new Map();
|
|
44
46
|
loaderApiOptionsMap = new Map();
|
|
45
|
-
const
|
|
47
|
+
const projectRoot = process.cwd();
|
|
48
|
+
const absolutePath = path.resolve(projectRoot, '${r}');
|
|
49
|
+
const serverModuleUrl = pathToFileURL(absolutePath).href;
|
|
46
50
|
|
|
47
51
|
if (typeof globalThis.require === 'undefined') {
|
|
48
52
|
try {
|
|
@@ -51,7 +55,7 @@ export default module.exports;`}return null};function ne(t){let u=he(t),r="";ret
|
|
|
51
55
|
} catch (e) {}
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
const routeModule = await import(/* @vite-ignore */
|
|
58
|
+
const routeModule = await import(/* @vite-ignore */ serverModuleUrl);
|
|
55
59
|
|
|
56
60
|
const mockMethods = {
|
|
57
61
|
addRpcRoute: (url, options) => rpcOptionsMap.set(url, options),
|
|
@@ -89,46 +93,46 @@ export default module.exports;`}return null};function ne(t){let u=he(t),r="";ret
|
|
|
89
93
|
return initPromise;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
${t.map(
|
|
96
|
+
${t.map(i=>{let v=[];i.requiresArgs&&v.push("args"),v.push("ssrContext");let w=i.requiresArgs?"args":"{}",S="";return i.type==="rpc"?S=`
|
|
93
97
|
if (fn.isMultipart) throw new Error('RPC multipart no soportado en SSR.');
|
|
94
98
|
await getOptionsMaps();
|
|
95
|
-
const options = rpcOptionsMap.get('${
|
|
96
|
-
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${
|
|
97
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
99
|
+
const options = rpcOptionsMap.get('${i.url}');
|
|
100
|
+
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${i.name}');
|
|
101
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${w});
|
|
98
102
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
99
|
-
`:
|
|
103
|
+
`:i.type==="api"?S=`
|
|
100
104
|
await getOptionsMaps();
|
|
101
|
-
const options = loaderApiOptionsMap.get('${
|
|
105
|
+
const options = loaderApiOptionsMap.get('${i.url}');
|
|
102
106
|
if (!options?.handler) {
|
|
103
|
-
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${
|
|
107
|
+
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${i.name}', 'URL:', '${i.url}');
|
|
104
108
|
return null;
|
|
105
109
|
}
|
|
106
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
110
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${w});
|
|
107
111
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
108
|
-
`:
|
|
112
|
+
`:S=`
|
|
109
113
|
await getOptionsMaps();
|
|
110
|
-
const options = renderOptionsMap.get('${
|
|
114
|
+
const options = renderOptionsMap.get('${i.url}');
|
|
111
115
|
if (!options) return {};
|
|
112
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
116
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${w});
|
|
113
117
|
let customData = {};
|
|
114
118
|
try {
|
|
115
119
|
if (options.handler) {
|
|
116
120
|
customData = (await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply)) || {};
|
|
117
121
|
}
|
|
118
122
|
} catch (handlerErr) {
|
|
119
|
-
console.error('\u274C [B-SSR Handler Error] ${
|
|
123
|
+
console.error('\u274C [B-SSR Handler Error] ${i.name}:', handlerErr);
|
|
120
124
|
return {};
|
|
121
125
|
}
|
|
122
126
|
if (ssrContext.reply.sent) return;
|
|
123
127
|
return { ...customData };
|
|
124
|
-
`,`export const ${
|
|
128
|
+
`,`export const ${i.name} = async (${v.join(", ")}) => {
|
|
125
129
|
try {
|
|
126
|
-
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${
|
|
127
|
-
${
|
|
130
|
+
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${i.name} (SSR)');
|
|
131
|
+
${S}
|
|
128
132
|
} catch (error) {
|
|
129
|
-
console.error('\u274C [B-SSR Error] ${
|
|
133
|
+
console.error('\u274C [B-SSR Error] ${i.name}:', error);
|
|
130
134
|
throw error;
|
|
131
135
|
}
|
|
132
136
|
};`}).join(`
|
|
133
137
|
`)}
|
|
134
|
-
`}async function
|
|
138
|
+
`}async function oe(){let t=await pe(x,{absolute:!0});await Promise.all(t.map(u=>I(u)))}return{name:"b-ssr-vite-plugin-rpc-universal-generator",enforce:"pre",async buildStart(){await oe()},configureServer(t){let u=r=>r.endsWith(".mts")||r.endsWith(".ts");t.watcher.on("add",r=>u(r)&&I(r)),t.watcher.on("change",r=>u(r)&&I(r)),t.watcher.on("unlink",r=>{if(u(r)){let c=o.resolve(r);C.delete(c),q.delete(c);let f=o.extname(r),i=r.substring(0,r.length-f.length)+".universal.d.ts";ee(i).catch(()=>{})}})},async resolveId(t,u,r){if(t.startsWith(L))return null;if(t.includes(".universal")){let c=t.split("?")[0],f=c;if(c.endsWith(".universal"))f=c;else if(c.endsWith(".universal.ts"))f=c.slice(0,-3);else if(c.endsWith(".universal.mts"))f=c.slice(0,-4);else if(c.endsWith(".universal.js"))f=c.slice(0,-3);else return null;let i=[".mts",".ts"];for(let v of i){let w=f.slice(0,-10)+v,S=await this.resolve(w,u,{skipSelf:!0});if(S){let D=r?.ssr?"?mode=ssr":"?mode=client";return L+S.id+D}try{await ue(w);let D=r?.ssr?"?mode=ssr":"?mode=client";return L+w+D}catch{}}}return null},async load(t,u){if(t.startsWith(L)){let r=t.slice(L.length).split("?")[0],c=C.get(r);return c||(await I(r),c=C.get(r)),c?u?.ssr===!0?c.server:c.client:null}if(u?.ssr!==!0){let r=o.resolve(t);if(q.has(r))return`throw new Error("\u{1F6A8} [B-SSR FIREWALL] BLOCKED: Backend File imported in Client: ${o.basename(t)}");`}return null},transform:re}}function he(T){let x=[];return T.paramsType!=="unknown"&&x.push(`params: ${T.paramsType}`),T.queryType!=="unknown"&&x.push(`query: ${T.queryType}`),T.bodyType!=="unknown"&&x.push(`body: ${T.bodyType}`),x.push("signal?: AbortSignal"),x}export{Re as rpcGeneratorPlugin};
|
package/package.json
CHANGED