@bobtail.software/b-ssr 1.0.53 → 1.0.56
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/tanstack-client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var _=Object.create;var a=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var g=(t,o)=>{for(var e in o)a(t,e,{get:o[e],enumerable:!0})},l=(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=f(o,n))||r.enumerable});return t};var y=(t,o,e)=>(e=t!=null?_(u(t)):{},l(o||!t||!t.__esModule?a(e,"default",{value:t,enumerable:!0}):e,t)),R=t=>l(a({},"__esModule",{value:!0}),t);var E={};g(E,{hydrateClient:()=>w});module.exports=R(E);var s=require("@tanstack/react-router/ssr/client"),m=y(require("react"),1),d=require("react-dom/client"),c=require("react/jsx-runtime");function w(t,o){let e=t(),r=window.__SSR_DATA__,n=window.__GLOBAL_SETTINGS__;n&&o&&o(n),(r||n)&&e.update({context:{...e.options.context,loaderData:r,globalSettings:n}});let i=document.getElementById("root")||document.getElementById("app");i&&!i.innerHTML?(0,d.createRoot)(i).render((0,c.jsx)(m.default.StrictMode,{children:(0,c.jsx)(s.RouterClient,{router:e})})):i&&(0,d.hydrateRoot)(document,(0,c.jsx)(s.RouterClient,{router:e}))}0&&(module.exports={hydrateClient});
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Hidrata la aplicación en el cliente.
|
|
3
3
|
* @param createRouterFn Función que crea el router
|
|
4
4
|
*/
|
|
5
|
-
declare function hydrateClient(createRouterFn: () => any): void;
|
|
5
|
+
declare function hydrateClient(createRouterFn: () => any, onHydrate?: (settings: any) => void): void;
|
|
6
6
|
|
|
7
7
|
export { hydrateClient };
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Hidrata la aplicación en el cliente.
|
|
3
3
|
* @param createRouterFn Función que crea el router
|
|
4
4
|
*/
|
|
5
|
-
declare function hydrateClient(createRouterFn: () => any): void;
|
|
5
|
+
declare function hydrateClient(createRouterFn: () => any, onHydrate?: (settings: any) => void): void;
|
|
6
6
|
|
|
7
7
|
export { hydrateClient };
|
package/dist/tanstack-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RouterClient as a}from"@tanstack/react-router/ssr/client";import
|
|
1
|
+
import{RouterClient as a}from"@tanstack/react-router/ssr/client";import d from"react";import{createRoot as s,hydrateRoot as l}from"react-dom/client";import{jsx as n}from"react/jsx-runtime";function u(c,r){let t=c(),i=window.__SSR_DATA__,o=window.__GLOBAL_SETTINGS__;o&&r&&r(o),(i||o)&&t.update({context:{...t.options.context,loaderData:i,globalSettings:o}});let e=document.getElementById("root")||document.getElementById("app");e&&!e.innerHTML?s(e).render(n(d.StrictMode,{children:n(a,{router:t})})):e&&l(document,n(a,{router:t}))}export{u as hydrateClient};
|
package/dist/vite-rpc-plugin.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var me=Object.create;var W=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,be=Object.prototype.hasOwnProperty;var Te=(i,p)=>{for(var P in p)W(i,P,{get:p[P],enumerable:!0})},te=(i,p,P,A)=>{if(p&&typeof p=="object"||typeof p=="function")for(let x of ye(p))!be.call(i,x)&&x!==P&&W(i,x,{get:()=>p[x],enumerable:!(A=fe(p,x))||A.enumerable});return i};var re=(i,p,P)=>(P=i!=null?me(he(i)):{},te(p||!i||!i.__esModule?W(P,"default",{value:i,enumerable:!0}):P,i)),Pe=i=>te(W({},"__esModule",{value:!0}),i);var Fe={};Te(Fe,{rpcGeneratorPlugin:()=>xe});module.exports=Pe(Fe);var se=re(require("fast-glob"),1),q=require("fs/promises"),c=re(require("path"),1),K=require("prettier"),r=require("ts-morph"),k="virtual:b-ssr-rpc-universal:";function we(i){let p=i.replace(/[^a-zA-Z0-9]+(.)?/g,(P,A)=>A?A.toUpperCase():"");return p.charAt(0).toLowerCase()+p.slice(1)}function Z(i,p,P){let A=c.default.basename(P,c.default.extname(P))||"Index",x=p.replace(/:[a-zA-Z0-9_]+/g,"").replace(/\//g," "),j=`${i} ${x} ${A}`;return we(j)}function xe(i={}){let{routerPattern:p="src-ts/routers/**/*.mts",tsConfigFilePath:P="tsconfig.json",routerBaseDir:A="src-ts/routers"}=i,x=new Map,j=new Set,B=new r.Project({tsConfigFilePath:P,skipAddingFilesFromTsConfig:!1}),ne=c.default.resolve(process.cwd(),A||".");async function I(t){try{let D=function(e){return e.replace(/import\(['"](.*?)['"]\)/g,(a,n)=>{if(!c.default.isAbsolute(n))return a;let o=n;if(!c.default.extname(o)){let T=B.getSourceFile(y=>y.getFilePath().replace(/\.(mts|ts|tsx)$/,"")===n);T&&(o=T.getFilePath())}let l=c.default.relative(c.default.dirname(M),o).replace(/\\/g,"/");return l.startsWith(".")||(l="./"+l),`import("${l}")`})},O=function(e,a){if(e.getSymbol()?.getName()==="Promise"){let d=e.getAwaitedType();if(d)return`Promise<${O(d,a)}>`}let n=e.getAliasSymbol()??e.getSymbol();if(n?.getName()==="__object")return D(e.getText(a,r.ts.TypeFormatFlags.NoTruncation|r.ts.TypeFormatFlags.UseFullyQualifiedType));if(e.isObject()&&!n){let d=(f,h=0)=>{if(!(h>5)){if(f.isArray()){let w=f.getArrayElementType();w&&d(w,h);return}if(f.isObject()&&!f.getSymbol()&&!f.getAliasSymbol()){for(let w of f.getApparentProperties()){let $=w.getValueDeclaration();$&&d(w.getTypeAtLocation($),h+1)}return}O(f,a)}};return d(e),D(e.getText(a,r.ts.TypeFormatFlags.NoTruncation|r.ts.TypeFormatFlags.UseFullyQualifiedType))}if(!n)return D(e.getText(a,r.ts.TypeFormatFlags.NoTruncation));let o=n.getDeclarations()[0];if(!o)return n.getName();if(r.Node.isImportSpecifier(o)||r.Node.isImportClause(o)){let d=o.getFirstAncestorByKind(r.SyntaxKind.ImportDeclaration);if(d){let f=d.getModuleSpecifierValue(),h=n.getName();return v.has(f)||v.set(f,new Set),v.get(f)?.add(h),h}}let l=o.getSourceFile();if(l.getFilePath()===b.getFilePath())return n.getName();if(l.isInNodeModules())return D(e.getText(a,r.ts.TypeFormatFlags.NoTruncation));let T=c.default.relative(c.default.dirname(M),l.getFilePath()).replace(/\\/g,"/"),E=T.startsWith(".")?T:`./${T}`,S=n.getName();return v.has(E)||v.set(E,new Set),v.get(E)?.add(S),S},Q=function(e){let a;if(r.Node.isFunctionLikeDeclaration(e)||r.Node.isArrowFunction(e)){let n=e.getDescendantsOfKind(r.SyntaxKind.ReturnStatement);for(let o of n){let l=o.getExpression();if(l?.isKind(r.SyntaxKind.SatisfiesExpression)){a=l.getTypeNode()?.getType();break}}}if(a)return O(a,e);{let n=e.getType().getCallSignatures();if(n.length>0){let o=n[0]?.getReturnType();return O(o,e)}}return"unknown"};var m=D,s=O,g=Q;let b=B.addSourceFileAtPath(t);await b.refreshFromFileSystem(),B.resolveSourceFileDependencies();let u=b.getDescendantsOfKind(r.SyntaxKind.CallExpression),C=(e,a)=>{if(!r.Node.isCallExpression(e))return!1;let n=e.getExpression();return r.Node.isPropertyAccessExpression(n)?n.getName()===a:!1},F=u.filter(e=>C(e,"addRpcRoute")),R=u.filter(e=>C(e,"addRenderRoute")),L=u.filter(e=>C(e,"addLoaderRoute")),ce=c.default.extname(t),M=t.substring(0,t.length-ce.length)+".universal.d.ts",V=c.default.resolve(t);if(F.length===0&&R.length===0&&L.length===0){x.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 pe=e=>{let a="unknown",n="unknown",o="unknown",l=!1;if(!e||!r.Node.isObjectLiteralExpression(e))return{paramsType:a,queryType:n,bodyType:o,isMultipart:l};let T=e.getProperty("schema");if(T?.isKind(r.SyntaxKind.PropertyAssignment)){let y=T.getInitializer();if(y?.isKind(r.SyntaxKind.Identifier)){let S=y.getSymbol()?.getValueDeclaration();if(S){let d=S.getFirstDescendantByKind(r.SyntaxKind.ObjectLiteralExpression);d&&(y=d)}}if(y&&r.Node.isObjectLiteralExpression(y)){let E=y.getProperty("consumes");if(E?.isKind(r.SyntaxKind.PropertyAssignment)){let d=E.getInitializer();r.Node.isArrayLiteralExpression(d)&&(l=d.getElements().some(f=>f.isKind(r.SyntaxKind.StringLiteral)&&f.getLiteralValue()==="multipart/form-data"))}let S=d=>{let f=y.getProperty(d);if(f?.isKind(r.SyntaxKind.PropertyAssignment)){let h=f.getInitializer();if(h){let w=h.getType(),$=w.getProperty("_output");return O($?$.getTypeAtLocation(h).getApparentType():w,h)}}return"unknown"};if(a=S("params"),n=S("querystring"),o=S("body"),l){let d="{ file: File }";o=o!=="unknown"&&o.trim().startsWith("{")?`(${o} & ${d})`:d}}}return{paramsType:a,queryType:n,bodyType:o,isMultipart:l}},N=c.default.relative(ne,c.default.dirname(t)).split(c.default.sep).join("/"),ue=N==="."||!N?"":N.startsWith("/")?N:"/"+N,z=(e,a)=>{let[n,o]=e.getArguments(),l="";if(r.Node.isStringLiteral(n))l=n.getLiteralValue();else if(r.Node.isNoSubstitutionTemplateLiteral(n))l=n.getLiteralText();else return;let T="unknown",y=ue,{paramsType:E,queryType:S,bodyType:d,isMultipart:f}=pe(o);if(o?.isKind(r.SyntaxKind.ObjectLiteralExpression)){let $=o.getProperty("prefix");if($?.isKind(r.SyntaxKind.PropertyAssignment)){let U=$.getInitializer();U?.isKind(r.SyntaxKind.StringLiteral)&&(y=U.getLiteralValue())}let ee=o.getProperty("handler");if(ee?.isKind(r.SyntaxKind.PropertyAssignment)){let U=ee.getInitializer();U&&(T=Q(U),T.startsWith("Promise<")||(T=`Promise<${T}>`))}}let h="",w="";a==="rpc"?(h=c.default.join(y,"rpc",l).replace(/\\/g,"/"),w=Z("action",y,l)):a==="loader"?(h=c.default.join(y,"loader",l).replace(/\\/g,"/"),w=Z("loader",y,l)):a==="api"&&(h=c.default.join(y,"api",l).replace(/\\/g,"/"),w=Z("get",y,l)),w&&_.push({type:a,name:w,returnType:T,url:l,rpcUrl:h,loaderUrl:h,paramsType:E,queryType:S,bodyType:d,isMultipart:f})};F.forEach(e=>z(e,"rpc")),R.forEach(e=>z(e,"loader")),L.forEach(e=>z(e,"api"));let H=[];for(let[e,a]of v.entries())H.push(`import type { ${[...a].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,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
|
|
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 n=e.type==="rpc"?"POST":"GET",o=e.type==="loader"?e.loaderUrl:e.rpcUrl;J.push({name:e.name,rpcUrl:o,method:n,isMultipart:!!e.isMultipart}),Y.push({name:e.name,url:e.url,type:e.type,requiresArgs:!0})});let ge=`
|
|
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: ${c.default.basename(t)}');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
${J.map(e=>`
|
|
@@ -21,17 +21,17 @@
|
|
|
21
21
|
});
|
|
22
22
|
`).join(`
|
|
23
23
|
`)}
|
|
24
|
-
`,
|
|
24
|
+
`,de=ae(Y,t);x.set(c.default.resolve(t),{client:ge,server:de})}catch(b){console.error(`[rpc-generator] Error al procesar ${t}:`,{error:b})}}let oe=(t,m,s)=>{if(m.includes("node_modules")||m.startsWith(k))return null;if(s?.ssr===!0&&/\.[cm]?[jt]sx?$/.test(m)){let g=/\brequire\s*\(/.test(t),b=/\bmodule\.exports\b/.test(t),u=/\bexports\./.test(t);if(g||b||u)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 ie(t){let m=
|
|
29
|
+
export default module.exports;`}return null};function ie(t){let m=Se(t),s="";return m.length>0&&(s=`args: { ${m.join("; ")} }`),s||(s="args: { signal?: AbortSignal }"),`export declare const ${t.name}: (${s}, ssrContext?: { req?: FastifyRequest, reply?: FastifyReply }) => ${t.returnType};`}function ae(t,m){if(t.length===0)return"";let s=c.default.relative(process.cwd(),m).replace(/\\/g,"/");return`
|
|
30
30
|
import path from 'path';
|
|
31
31
|
import { pathToFileURL } from 'url';
|
|
32
32
|
|
|
33
33
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
34
|
-
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: ${`./${c.default.relative(process.cwd(),m).replace(/\\/g,"/")}`}');
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
let initPromise;
|
|
@@ -45,7 +45,7 @@ export default module.exports;`}return null};function ie(t){let m=we(t),r="";ret
|
|
|
45
45
|
renderOptionsMap = new Map();
|
|
46
46
|
loaderApiOptionsMap = new Map();
|
|
47
47
|
const projectRoot = process.cwd();
|
|
48
|
-
const absolutePath = path.resolve(projectRoot, '${
|
|
48
|
+
const absolutePath = path.resolve(projectRoot, '${s}');
|
|
49
49
|
const serverModuleUrl = pathToFileURL(absolutePath).href;
|
|
50
50
|
|
|
51
51
|
if (typeof globalThis.require === 'undefined') {
|
|
@@ -93,25 +93,25 @@ export default module.exports;`}return null};function ie(t){let m=we(t),r="";ret
|
|
|
93
93
|
return initPromise;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
${t.map(
|
|
96
|
+
${t.map(u=>{let C=[];u.requiresArgs&&C.push("args"),C.push("ssrContext");let F=u.requiresArgs?"args":"{}",R="";return u.type==="rpc"?R=`
|
|
97
97
|
if (fn.isMultipart) throw new Error('RPC multipart no soportado en SSR.');
|
|
98
98
|
await getOptionsMaps();
|
|
99
|
-
const options = rpcOptionsMap.get('${
|
|
100
|
-
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${
|
|
99
|
+
const options = rpcOptionsMap.get('${u.url}');
|
|
100
|
+
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${u.name}');
|
|
101
101
|
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${F});
|
|
102
102
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
103
|
-
`:
|
|
103
|
+
`:u.type==="api"?R=`
|
|
104
104
|
await getOptionsMaps();
|
|
105
|
-
const options = loaderApiOptionsMap.get('${
|
|
105
|
+
const options = loaderApiOptionsMap.get('${u.url}');
|
|
106
106
|
if (!options?.handler) {
|
|
107
|
-
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${
|
|
107
|
+
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${u.name}', 'URL:', '${u.url}');
|
|
108
108
|
return null;
|
|
109
109
|
}
|
|
110
110
|
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${F});
|
|
111
111
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
112
112
|
`:R=`
|
|
113
113
|
await getOptionsMaps();
|
|
114
|
-
const options = renderOptionsMap.get('${
|
|
114
|
+
const options = renderOptionsMap.get('${u.url}');
|
|
115
115
|
if (!options) return {};
|
|
116
116
|
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${F});
|
|
117
117
|
let customData = {};
|
|
@@ -120,19 +120,19 @@ export default module.exports;`}return null};function ie(t){let m=we(t),r="";ret
|
|
|
120
120
|
customData = (await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply)) || {};
|
|
121
121
|
}
|
|
122
122
|
} catch (handlerErr) {
|
|
123
|
-
console.error('\u274C [B-SSR Handler Error] ${
|
|
123
|
+
console.error('\u274C [B-SSR Handler Error] ${u.name}:', handlerErr);
|
|
124
124
|
return {};
|
|
125
125
|
}
|
|
126
126
|
if (ssrContext.reply.sent) return;
|
|
127
127
|
return { ...customData };
|
|
128
|
-
`,`export const ${
|
|
128
|
+
`,`export const ${u.name} = async (${C.join(", ")}) => {
|
|
129
129
|
try {
|
|
130
|
-
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${
|
|
130
|
+
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${u.name} (SSR)');
|
|
131
131
|
${R}
|
|
132
132
|
} catch (error) {
|
|
133
|
-
console.error('\u274C [B-SSR Error] ${
|
|
133
|
+
console.error('\u274C [B-SSR Error] ${u.name}:', error);
|
|
134
134
|
throw error;
|
|
135
135
|
}
|
|
136
136
|
};`}).join(`
|
|
137
137
|
`)}
|
|
138
|
-
`}async function le(){let t=await(0,se.default)(
|
|
138
|
+
`}async function le(){let t=await(0,se.default)(p,{absolute:!0});await Promise.all(t.map(m=>I(m)))}return{name:"b-ssr-vite-plugin-rpc-universal-generator",enforce:"pre",async buildStart(){await le()},configureServer(t){let m=s=>s.endsWith(".mts")||s.endsWith(".ts");t.watcher.on("add",s=>m(s)&&I(s)),t.watcher.on("change",s=>m(s)&&I(s)),t.watcher.on("unlink",s=>{if(m(s)){let g=c.default.resolve(s);x.delete(g),j.delete(g);let b=c.default.extname(s),u=s.substring(0,s.length-b.length)+".universal.d.ts";(0,q.unlink)(u).catch(()=>{})}})},async resolveId(t,m,s){if(t.startsWith(k))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 u=[".mts",".ts"];for(let C of u){let F=b.slice(0,-10)+C,R=await this.resolve(F,m,{skipSelf:!0});if(R){let L=s?.ssr?"?mode=ssr":"?mode=client";return k+R.id+L}try{await(0,q.access)(F);let L=s?.ssr?"?mode=ssr":"?mode=client";return k+F+L}catch{}}}return null},async load(t,m){if(t.startsWith(k)){let s=t.slice(k.length).split("?")[0],g=x.get(s);return g||(await I(s),g=x.get(s)),g?m?.ssr===!0?g.server:g.client:null}if(m?.ssr!==!0){let s=c.default.resolve(t);if(j.has(s))return`throw new Error("\u{1F6A8} [B-SSR FIREWALL] BLOCKED: Backend File imported in Client: ${c.default.basename(t)}");`}return null},transform:oe}}function Se(i){let p=[];return i.paramsType!=="unknown"&&p.push(`params: ${i.paramsType}`),i.queryType!=="unknown"&&p.push(`query: ${i.queryType}`),i.bodyType!=="unknown"&&p.push(`body: ${i.bodyType}`),p.push("signal?: AbortSignal"),p}0&&(module.exports={rpcGeneratorPlugin});
|
package/dist/vite-rpc-plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ue from"fast-glob";import{access as ge,unlink as ee,writeFile as de}from"fs/promises";import a from"path";import{format as me,resolveConfig as fe}from"prettier";import{Node as R,Project as ye,SyntaxKind as b,ts as L}from"ts-morph";var k="virtual:b-ssr-rpc-universal:";function he(T){let P=T.replace(/[^a-zA-Z0-9]+(.)?/g,(D,O)=>O?O.toUpperCase():"");return P.charAt(0).toLowerCase()+P.slice(1)}function G(T,P,D){let O=a.basename(D,a.extname(D))||"Index",A=P.replace(/:[a-zA-Z0-9_]+/g,"").replace(/\//g," "),q=`${T} ${A} ${O}`;return he(q)}function ve(T={}){let{routerPattern:P="src-ts/routers/**/*.mts",tsConfigFilePath:D="tsconfig.json",routerBaseDir:O="src-ts/routers"}=T,A=new Map,q=new Set,K=new ye({tsConfigFilePath:D,skipAddingFilesFromTsConfig:!1}),te=a.resolve(process.cwd(),O||".");async function W(t){try{let N=function(e){return e.replace(/import\(['"](.*?)['"]\)/g,(o,s)=>{if(!a.isAbsolute(s))return o;let n=s;if(!a.extname(n)){let y=K.getSourceFile(d=>d.getFilePath().replace(/\.(mts|ts|tsx)$/,"")===s);y&&(n=y.getFilePath())}let i=a.relative(a.dirname($),n).replace(/\\/g,"/");return i.startsWith(".")||(i="./"+i),`import("${i}")`})},M=function(e,o){if(e.getSymbol()?.getName()==="Promise"){let p=e.getAwaitedType();if(p)return`Promise<${M(p,o)}>`}let s=e.getAliasSymbol()??e.getSymbol();if(s?.getName()==="__object")return N(e.getText(o,L.TypeFormatFlags.NoTruncation|L.TypeFormatFlags.UseFullyQualifiedType));if(e.isObject()&&!s){let p=(g,m=0)=>{if(!(m>5)){if(g.isArray()){let h=g.getArrayElementType();h&&p(h,m);return}if(g.isObject()&&!g.getSymbol()&&!g.getAliasSymbol()){for(let h of g.getApparentProperties()){let E=h.getValueDeclaration();E&&p(h.getTypeAtLocation(E),m+1)}return}M(g,o)}};return p(e),N(e.getText(o,L.TypeFormatFlags.NoTruncation|L.TypeFormatFlags.UseFullyQualifiedType))}if(!s)return N(e.getText(o,L.TypeFormatFlags.NoTruncation));let n=s.getDeclarations()[0];if(!n)return s.getName();if(R.isImportSpecifier(n)||R.isImportClause(n)){let p=n.getFirstAncestorByKind(b.ImportDeclaration);if(p){let g=p.getModuleSpecifierValue(),m=s.getName();return F.has(g)||F.set(g,new Set),F.get(g)?.add(m),m}}let i=n.getSourceFile();if(i.getFilePath()===f.getFilePath())return s.getName();if(i.isInNodeModules())return N(e.getText(o,L.TypeFormatFlags.NoTruncation));let y=a.relative(a.dirname($),i.getFilePath()).replace(/\\/g,"/"),C=y.startsWith(".")?y:`./${y}`,w=s.getName();return F.has(C)||F.set(C,new Set),F.get(C)?.add(w),w},Z=function(e){let o;if(R.isFunctionLikeDeclaration(e)||R.isArrowFunction(e)){let s=e.getDescendantsOfKind(b.ReturnStatement);for(let n of s){let i=n.getExpression();if(i?.isKind(b.SatisfiesExpression)){o=i.getTypeNode()?.getType();break}}}if(o)return M(o,e);{let s=e.getType().getCallSignatures();if(s.length>0){let n=s[0]?.getReturnType();return M(n,e)}}return"unknown"};var u=N,r=M,c=Z;let f=K.addSourceFileAtPath(t);await f.refreshFromFileSystem(),K.resolveSourceFileDependencies();let l=f.getDescendantsOfKind(b.CallExpression),v=(e,o)=>{if(!R.isCallExpression(e))return!1;let s=e.getExpression();return R.isPropertyAccessExpression(s)?s.getName()===o:!1},x=l.filter(e=>v(e,"addRpcRoute")),S=l.filter(e=>v(e,"addRenderRoute")),j=l.filter(e=>v(e,"addLoaderRoute")),ie=a.extname(t),$=t.substring(0,t.length-ie.length)+".universal.d.ts",B=a.resolve(t);if(x.length===0&&S.length===0&&j.length===0){A.delete(B),q.delete(B),$!==t&&await ee($).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 ae=e=>{let o="unknown",s="unknown",n="unknown",i=!1;if(!e||!R.isObjectLiteralExpression(e))return{paramsType:o,queryType:s,bodyType:n,isMultipart:i};let y=e.getProperty("schema");if(y?.isKind(b.PropertyAssignment)){let d=y.getInitializer();if(d?.isKind(b.Identifier)){let w=d.getSymbol()?.getValueDeclaration();if(w){let p=w.getFirstDescendantByKind(b.ObjectLiteralExpression);p&&(d=p)}}if(d&&R.isObjectLiteralExpression(d)){let C=d.getProperty("consumes");if(C?.isKind(b.PropertyAssignment)){let p=C.getInitializer();R.isArrayLiteralExpression(p)&&(i=p.getElements().some(g=>g.isKind(b.StringLiteral)&&g.getLiteralValue()==="multipart/form-data"))}let w=p=>{let g=d.getProperty(p);if(g?.isKind(b.PropertyAssignment)){let m=g.getInitializer();if(m){let h=m.getType(),E=h.getProperty("_output");return M(E?E.getTypeAtLocation(m).getApparentType():h,m)}}return"unknown"};if(o=w("params"),s=w("querystring"),n=w("body"),i){let p="{ file: File }";n=n!=="unknown"&&n.trim().startsWith("{")?`(${n} & ${p})`:p}}}return{paramsType:o,queryType:s,bodyType:n,isMultipart:i}},U=a.relative(te,a.dirname(t)).split(a.sep).join("/"),le=U==="."||!U?"":U.startsWith("/")?U:"/"+U,_=(e,o)=>{let[s,n]=e.getArguments(),i="";if(R.isStringLiteral(s))i=s.getLiteralValue();else if(R.isNoSubstitutionTemplateLiteral(s))i=s.getLiteralText();else return;let y="unknown",d=le,{paramsType:C,queryType:w,bodyType:p,isMultipart:g}=ae(n);if(n?.isKind(b.ObjectLiteralExpression)){let E=n.getProperty("prefix");if(E?.isKind(b.PropertyAssignment)){let I=E.getInitializer();I?.isKind(b.StringLiteral)&&(d=I.getLiteralValue())}let J=n.getProperty("handler");if(J?.isKind(b.PropertyAssignment)){let I=J.getInitializer();I&&(y=Z(I),y.startsWith("Promise<")||(y=`Promise<${y}>`))}}let m="",h="";o==="rpc"?(m=a.join(d,"rpc",i).replace(/\\/g,"/"),h=G("action",d,i)):o==="loader"?(m=a.join(d,"loader",i).replace(/\\/g,"/"),h=G("loader",d,i)):o==="api"&&(m=a.join(d,"api",i).replace(/\\/g,"/"),h=G("get",d,i)),h&&V.push({type:o,name:h,returnType:y,url:i,rpcUrl:m,loaderUrl:m,paramsType:C,queryType:w,bodyType:p,isMultipart:g})};x.forEach(e=>_(e,"rpc")),S.forEach(e=>_(e,"loader")),j.forEach(e=>_(e,"api"));let z=[];for(let[e,o]of F.entries())z.push(`import type { ${[...o].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
|
|
9
|
+
`);try{let e=await fe($)||{};H=await me(H,{...e,parser:"typescript",filepath:$})}catch{}await de($,H);let X=[],Y=[];V.forEach(e=>{let s=e.type==="rpc"?"POST":"GET",n=e.type==="loader"?e.loaderUrl:e.rpcUrl;Y.push({name:e.name,rpcUrl:n,method:s,isMultipart:!!e.isMultipart}),X.push({name:e.name,url:e.url,type:e.type,requiresArgs:!0})});let ce=`
|
|
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.basename(t)}');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
${Y.map(e=>`
|
|
@@ -21,17 +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
|
-
`,
|
|
24
|
+
`,pe=ne(X,t);A.set(a.resolve(t),{client:ce,server:pe})}catch(f){console.error(`[rpc-generator] Error al procesar ${t}:`,{error:f})}}let re=(t,u,r)=>{if(u.includes("node_modules")||u.startsWith(k))return null;if(r?.ssr===!0&&/\.[cm]?[jt]sx?$/.test(u)){let c=/\brequire\s*\(/.test(t),f=/\bmodule\.exports\b/.test(t),l=/\bexports\./.test(t);if(c||f||l)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 se(t){let u=
|
|
29
|
+
export default module.exports;`}return null};function se(t){let u=be(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=a.relative(process.cwd(),u).replace(/\\/g,"/");return`
|
|
30
30
|
import path from 'path';
|
|
31
31
|
import { pathToFileURL } from 'url';
|
|
32
32
|
|
|
33
33
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
34
|
-
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.relative(process.cwd(),u).replace(/\\/g,"/")}`}');
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
let initPromise;
|
|
@@ -93,46 +93,46 @@ export default module.exports;`}return null};function se(t){let u=he(t),r="";ret
|
|
|
93
93
|
return initPromise;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
${t.map(
|
|
96
|
+
${t.map(l=>{let v=[];l.requiresArgs&&v.push("args"),v.push("ssrContext");let x=l.requiresArgs?"args":"{}",S="";return l.type==="rpc"?S=`
|
|
97
97
|
if (fn.isMultipart) throw new Error('RPC multipart no soportado en SSR.');
|
|
98
98
|
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), ${
|
|
99
|
+
const options = rpcOptionsMap.get('${l.url}');
|
|
100
|
+
if (!options?.handler) throw new Error('Handler no encontrado para RPC: ${l.name}');
|
|
101
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${x});
|
|
102
102
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
103
|
-
`:
|
|
103
|
+
`:l.type==="api"?S=`
|
|
104
104
|
await getOptionsMaps();
|
|
105
|
-
const options = loaderApiOptionsMap.get('${
|
|
105
|
+
const options = loaderApiOptionsMap.get('${l.url}');
|
|
106
106
|
if (!options?.handler) {
|
|
107
|
-
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${
|
|
107
|
+
console.error('\u26A0\uFE0F [B-SSR Warning] Handler API no encontrado:', '${l.name}', 'URL:', '${l.url}');
|
|
108
108
|
return null;
|
|
109
109
|
}
|
|
110
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
110
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${x});
|
|
111
111
|
return await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply);
|
|
112
112
|
`:S=`
|
|
113
113
|
await getOptionsMaps();
|
|
114
|
-
const options = renderOptionsMap.get('${
|
|
114
|
+
const options = renderOptionsMap.get('${l.url}');
|
|
115
115
|
if (!options) return {};
|
|
116
|
-
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${
|
|
116
|
+
const augmentedReq = Object.assign(Object.create(ssrContext.req), ${x});
|
|
117
117
|
let customData = {};
|
|
118
118
|
try {
|
|
119
119
|
if (options.handler) {
|
|
120
120
|
customData = (await options.handler.call(ssrContext.req.server, augmentedReq, ssrContext.reply)) || {};
|
|
121
121
|
}
|
|
122
122
|
} catch (handlerErr) {
|
|
123
|
-
console.error('\u274C [B-SSR Handler Error] ${
|
|
123
|
+
console.error('\u274C [B-SSR Handler Error] ${l.name}:', handlerErr);
|
|
124
124
|
return {};
|
|
125
125
|
}
|
|
126
126
|
if (ssrContext.reply.sent) return;
|
|
127
127
|
return { ...customData };
|
|
128
|
-
`,`export const ${
|
|
128
|
+
`,`export const ${l.name} = async (${v.join(", ")}) => {
|
|
129
129
|
try {
|
|
130
|
-
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${
|
|
130
|
+
if (!ssrContext?.req) throw new Error('ssrContext requerido en ${l.name} (SSR)');
|
|
131
131
|
${S}
|
|
132
132
|
} catch (error) {
|
|
133
|
-
console.error('\u274C [B-SSR Error] ${
|
|
133
|
+
console.error('\u274C [B-SSR Error] ${l.name}:', error);
|
|
134
134
|
throw error;
|
|
135
135
|
}
|
|
136
136
|
};`}).join(`
|
|
137
137
|
`)}
|
|
138
|
-
`}async function oe(){let t=await
|
|
138
|
+
`}async function oe(){let t=await ue(P,{absolute:!0});await Promise.all(t.map(u=>W(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)&&W(r)),t.watcher.on("change",r=>u(r)&&W(r)),t.watcher.on("unlink",r=>{if(u(r)){let c=a.resolve(r);A.delete(c),q.delete(c);let f=a.extname(r),l=r.substring(0,r.length-f.length)+".universal.d.ts";ee(l).catch(()=>{})}})},async resolveId(t,u,r){if(t.startsWith(k))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 l=[".mts",".ts"];for(let v of l){let x=f.slice(0,-10)+v,S=await this.resolve(x,u,{skipSelf:!0});if(S){let j=r?.ssr?"?mode=ssr":"?mode=client";return k+S.id+j}try{await ge(x);let j=r?.ssr?"?mode=ssr":"?mode=client";return k+x+j}catch{}}}return null},async load(t,u){if(t.startsWith(k)){let r=t.slice(k.length).split("?")[0],c=A.get(r);return c||(await W(r),c=A.get(r)),c?u?.ssr===!0?c.server:c.client:null}if(u?.ssr!==!0){let r=a.resolve(t);if(q.has(r))return`throw new Error("\u{1F6A8} [B-SSR FIREWALL] BLOCKED: Backend File imported in Client: ${a.basename(t)}");`}return null},transform:re}}function be(T){let P=[];return T.paramsType!=="unknown"&&P.push(`params: ${T.paramsType}`),T.queryType!=="unknown"&&P.push(`query: ${T.queryType}`),T.bodyType!=="unknown"&&P.push(`body: ${T.bodyType}`),P.push("signal?: AbortSignal"),P}export{ve as rpcGeneratorPlugin};
|
package/package.json
CHANGED