rpc4next 0.3.6 → 0.3.7

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Wt}from"commander";import $t from"path";var R=["page.tsx","route.ts"],w=0,$=1,Y=1,M=20,W="\u2192";import U from"path";var et=(t,r)=>{let e=P(U.relative(U.dirname(t),r)).replace(/\.tsx?$/,"");return e.startsWith("../")||(e="./"+e),e},P=t=>t.replace(/\\/g,"/"),C=t=>U.relative(process.cwd(),t);import _t from"fs";import Yt from"path";var rt=["Query","OptionalQuery"],L=" ",g=`
3
- `,S=";",H=";",j="Endpoint",X="QueryKey",K="OptionalQueryKey",Q="ParamsKey",ot=[j,K,Q,X],nt="rpc4next/client";import ht from"fs";import b from"path";import G from"path";var T=new Map,N=new Map,st=(t,r)=>{let e=G.resolve(r);[...t.keys()].forEach(o=>{let n=G.resolve(o);(n===e||e.startsWith(n+G.sep))&&t.delete(o)})},it=t=>{st(T,t)},at=t=>{st(N,t)};import vt from"fs";import bt from"crypto";var pt=(t,r)=>{let e=bt.createHash("md5").update(`${t}::${r}`).digest("hex").slice(0,16);return`${r}_${e}`};var I=(t,r)=>!t||!r?"":`Record<${t}, ${r}>`,O=t=>t.length===0||t.some(({name:r,type:e})=>!r||!e)?"":`{ ${t.map(({name:r,type:e})=>`"${r}": ${e}`).join(`${H} `)}${t.length>1?H:""} }`,D=(t,r,e)=>!t||!r?"":e?`import type { ${t} as ${e} } from "${r}"${S}`:`import type { ${t} } from "${r}"${S}`;var ct=(t,r,e,o)=>{let n=vt.readFileSync(r,"utf8"),i=e(n);if(!i)return;let s=et(t,r),p=pt(s,i);return{importName:p,importPath:s,importStatement:D(i,s,p),type:o(i,p)}},mt=(t,r)=>ct(t,r,e=>rt.find(o=>new RegExp(`export (interface ${o} ?{|type ${o} ?=)`).test(e)),(e,o)=>e==="Query"?I(X,o):I(K,o)),lt=(t,r,e)=>ct(t,r,o=>[e].find(n=>new RegExp(`export (async )?(function ${n} ?\\(|const ${n} ?=|\\{[^}]*\\b${n}\\b[^}]*\\} ?=|const \\{[^}]*\\b${n}\\b[^}]*\\} ?=|\\{[^}]*\\b${n}\\b[^}]*\\} from)`).test(o)),(o,n)=>O([{name:`$${o.toLowerCase()}`,type:`typeof ${n}`}]));import{HTTP_METHODS as Ft}from"next/dist/server/web/http";var ut="_____",ft="___",gt="_",k=Ft.filter(t=>t!=="OPTIONS"),ne=k.map(t=>`$${t.toLowerCase()}`);var Et=new Set(R),Tt=t=>{if(T.has(t))return T.get(t);let r=ht.readdirSync(t,{withFileTypes:!0});for(let e of r){let{name:o}=e,n=b.join(t,o);if(o==="node_modules"||o.startsWith("_")||o.startsWith("(.)")||o.startsWith("(..)")||o.startsWith("(...)"))return T.set(t,!1),!1;if(e.isFile()&&Et.has(o))return T.set(t,!0),!0;if(e.isDirectory()&&Tt(n))return T.set(t,!0),!0}return T.set(t,!1),!1},wt=(t,{isDynamic:r,isCatchAll:e,isOptionalCatchAll:o})=>{let n=t;return r&&(n=n.replace(/^\[+|\]+$/g,"")),(e||o)&&(n=n.replace(/^\.{3}/,"")),{paramName:n,keyName:`${o?ut:e?ft:r?gt:""}${n}`}},V=(t,r,e="",o=[])=>{if(N.has(r))return N.get(r);let n=e,i=e+L,s=[],p=[],a=[],m=[],c=[...o],x=ht.readdirSync(r,{withFileTypes:!0}).filter(y=>{if(y.isDirectory()){let _=b.join(r,y.name);return Tt(_)}return Et.has(y.name)}).sort();for(let y of x){let _=P(b.join(r,y.name));if(y.isDirectory()){let l=y.name,h=l.startsWith("(")&&l.endsWith(")"),u=l.startsWith("@"),f=l.startsWith("[[...")&&l.endsWith("]]"),E=l.startsWith("[...")&&l.endsWith("]"),d=l.startsWith("[")&&l.endsWith("]"),{paramName:At,keyName:Rt}=wt(l,{isDynamic:d,isCatchAll:E,isOptionalCatchAll:f}),Lt=d||E||f?[...c,{paramName:At,routeType:{isDynamic:d,isCatchAll:E,isOptionalCatchAll:f,isGroup:h,isParallel:u}}]:c,J=h||u,{pathStructure:Z,imports:Ot,paramsTypes:Dt}=V(t,_,J?n:i,Lt);if(p.push(...Ot),m.push(...Dt),J){let tt=Z.match(/^\s*\{([\s\S]*)\}\s*$/);tt&&s.push(`${i}${tt[1].trim()}`)}else s.push(`${i}"${Rt}": ${Z}`)}else{let l=mt(t,_);if(l){let{importStatement:h,importPath:u,type:f}=l;p.push({statement:h,path:u}),a.push(f)}if(k.forEach(h=>{let u=lt(t,_,h);if(u){let{importStatement:f,importPath:E,type:d}=u;p.push({statement:f,path:E}),a.push(d)}}),a.push(j),c.length>0){let h=c.map(({paramName:f,routeType:E})=>{let d=E.isCatchAll?"string[]":E.isOptionalCatchAll?"string[] | undefined":"string";return{name:f,type:d}}),u=O(h);m.push({paramsType:u,dirPath:b.dirname(_)}),a.push(I(Q,u))}}}let A=a.join(" & "),F=s.length>0?`{${g}${s.join(`,${g}`)}${g}${n}}`:"",z={pathStructure:A&&F?`${A} & ${F}`:A||F,imports:p,paramsTypes:m};return N.set(r,z),z};var yt=(t,r)=>{let{pathStructure:e,imports:o,paramsTypes:n}=V(t,r),i=`export type PathStructure = ${e}${S}`,s=o.length?`${o.sort((c,x)=>c.path.localeCompare(x.path,void 0,{numeric:!0})).map(c=>c.statement).join(g)}`:"",p=ot.filter(c=>e.includes(c)),a=D(p.join(" ,"),nt),m=n.map(({paramsType:c,dirPath:x})=>({paramsType:`export type Params = ${c}${S}`,dirPath:x}));return{pathStructure:`${a}${g}${s}${g}${g}${i}`,paramsTypes:m}};import v from"chalk";var q=(t,r,e="\u2192",o=24)=>t.padEnd(o)+` ${e} ${r}`,B=(t=0)=>L.repeat(t),dt=()=>({info:(t,r={})=>{let{indentLevel:e=0,event:o}=r,n=o?`${v.cyan(`[${o}]`)} `:"";console.log(`${B(e)}${n}${t}`)},success:(t,r={})=>{let{indentLevel:e=0}=r;console.log(`${B(e)}${v.green("\u2713")} ${t}`)},error:(t,r={})=>{let{indentLevel:e=0}=r;console.error(`${B(e)}${v.red("\u2717")} ${v.red(t)}`)}});var Pt=({baseDir:t,outputPath:r,paramsFileName:e,logger:o})=>{o.info("Generating types...",{event:"generate"});let{pathStructure:n,paramsTypes:i}=yt(r,t);_t.writeFileSync(r,n),o.success(q("Path structure type",C(r),W,M),{indentLevel:Y}),e&&(i.forEach(({paramsType:s,dirPath:p})=>{let a=Yt.join(p,e);_t.writeFileSync(a,s)}),o.success(q("Params types",e,W,M),{indentLevel:Y}))};import Mt from"chokidar";var St=(t,r)=>{let e=null,o=!1,n=null,i=async(...s)=>{o=!0;try{await t(...s)}finally{if(o=!1,n){let p=n;n=null,i(...p)}}};return(...s)=>{e&&clearTimeout(e),e=setTimeout(()=>{if(o){n=s;return}i(...s)},r)}};var xt=(t,r,e)=>{e.info(`${C(t)}`,{event:"watch"});let o=a=>R.some(m=>a.endsWith(m)),n=new Set,i=St(()=>{n.forEach(a=>{it(a),at(a)}),n.clear(),r()},300),s=Mt.watch(t,{ignoreInitial:!0,ignored:(a,m)=>!!m?.isFile()&&!o(a)});s.on("ready",()=>{i(),s.on("all",(a,m)=>{if(o(m)){let c=C(m);e.info(c,{event:a}),n.add(m),i()}})}),s.on("error",a=>{a instanceof Error?e.error(`Watcher error: ${a.message}`):e.error(`Unknown watcher error: ${String(a)}`)});let p=()=>{s.close().then(()=>{e.info("Watcher closed.",{event:"watch"})}).catch(a=>{e.error(`Failed to close watcher: ${a.message}`)})};process.on("SIGINT",p),process.on("SIGTERM",p)};var Ct=(t,r,e,o)=>{try{return Pt({baseDir:t,outputPath:r,paramsFileName:e,logger:o}),w}catch(n){return n instanceof Error?o.error(`Failed to generate: ${n.message}`):o.error(`Unknown error occurred during generate: ${String(n)}`),$}},Nt=(t,r,e,o)=>{let n=P($t.resolve(t)),i=P($t.resolve(r)),s=typeof e.paramsFile=="string"?e.paramsFile:null;return e.paramsFile!==void 0&&!s?(o.error("Error: --params-file requires a filename."),$):e.watch?(xt(n,()=>{Ct(n,i,s,o)},o),w):Ct(n,i,s,o)};var It=(t,r=dt())=>{let e=new Wt;e.description("Generate RPC client type definitions based on the Next.js path structure.").argument("<baseDir>","Base directory containing Next.js paths for type generation").argument("<outputPath>","Output path for the generated type definitions").option("-w, --watch","Watch mode: regenerate on file changes").option("-p, --params-file [filename]","Generate params types file with specified filename").action(async(o,n,i)=>{try{let s=await Nt(o,n,i,r);i.watch||process.exit(s)}catch(s){r.error(`Unexpected error occurred:${s instanceof Error?s.message:String(s)}`),process.exit($)}}),e.parse(t)};It(process.argv);
2
+ import{Command as Wt}from"commander";import $t from"path";var R=["page.tsx","route.ts"],w=0,$=1,Y=1,M=20,W="\u2192";import U from"path";var et=(t,r)=>{let e=_(U.relative(U.dirname(t),r)).replace(/\.tsx?$/,"");return e.startsWith("../")||(e="./"+e),e},_=t=>t.replace(/\\/g,"/"),C=t=>U.relative(process.cwd(),t);import Pt from"fs";import Yt from"path";var rt=["Query","OptionalQuery"],O=" ",E=`
3
+ `,S=";",H=";",j="Endpoint",X="QueryKey",K="OptionalQueryKey",Q="ParamsKey",ot=[j,K,Q,X],nt="rpc4next/client";import Tt from"fs";import b from"path";import G from"path";var h=new Map,N=new Map,st=(t,r)=>{let e=G.resolve(r);[...t.keys()].forEach(o=>{let n=G.resolve(o);(n===e||e.startsWith(n+G.sep))&&t.delete(o)})},it=t=>{st(h,t)},at=t=>{st(N,t)};import vt from"fs";import bt from"crypto";var pt=(t,r)=>{let e=bt.createHash("md5").update(`${t}::${r}`).digest("hex").slice(0,16);return`${r}_${e}`};var I=(t,r)=>!t||!r?"":`Record<${t}, ${r}>`,L=t=>t.length===0||t.some(({name:r,type:e})=>!r||!e)?"":`{ ${t.map(({name:r,type:e})=>`"${r}": ${e}`).join(`${H} `)}${t.length>1?H:""} }`,D=(t,r,e)=>!t||!r?"":e?`import type { ${t} as ${e} } from "${r}"${S}`:`import type { ${t} } from "${r}"${S}`;var ct=(t,r,e,o)=>{let n=vt.readFileSync(r,"utf8"),i=e(n);if(!i)return;let s=et(t,r),p=pt(s,i);return{importName:p,importPath:s,importStatement:D(i,s,p),type:o(i,p)}},mt=(t,r)=>ct(t,r,e=>rt.find(o=>new RegExp(`export (interface ${o} ?{|type ${o} ?=)`).test(e)),(e,o)=>e==="Query"?I(X,o):I(K,o)),lt=(t,r,e)=>ct(t,r,o=>[e].find(n=>new RegExp(`export (async )?(function ${n} ?\\(|const ${n} ?=|\\{[^}]*\\b${n}\\b[^}]*\\} ?=|const \\{[^}]*\\b${n}\\b[^}]*\\} ?=|\\{[^}]*\\b${n}\\b[^}]*\\} from)`).test(o)),(o,n)=>L([{name:`$${o.toLowerCase()}`,type:`typeof ${n}`}]));var Ft=["GET","HEAD","OPTIONS","POST","PUT","DELETE","PATCH"],ut="_____",ft="___",Et="_",k=Ft.filter(t=>t!=="OPTIONS"),oe=k.map(t=>`$${t.toLowerCase()}`);var gt=new Set(R),ht=t=>{if(h.has(t))return h.get(t);let r=Tt.readdirSync(t,{withFileTypes:!0});for(let e of r){let{name:o}=e,n=b.join(t,o);if(o==="node_modules"||o.startsWith("_")||o.startsWith("(.)")||o.startsWith("(..)")||o.startsWith("(...)"))return h.set(t,!1),!1;if(e.isFile()&&gt.has(o))return h.set(t,!0),!0;if(e.isDirectory()&&ht(n))return h.set(t,!0),!0}return h.set(t,!1),!1},wt=(t,{isDynamic:r,isCatchAll:e,isOptionalCatchAll:o})=>{let n=t;return r&&(n=n.replace(/^\[+|\]+$/g,"")),(e||o)&&(n=n.replace(/^\.{3}/,"")),{paramName:n,keyName:`${o?ut:e?ft:r?Et:""}${n}`}},V=(t,r,e="",o=[])=>{if(N.has(r))return N.get(r);let n=e,i=e+O,s=[],p=[],a=[],m=[],c=[...o],x=Tt.readdirSync(r,{withFileTypes:!0}).filter(y=>{if(y.isDirectory()){let P=b.join(r,y.name);return ht(P)}return gt.has(y.name)}).sort();for(let y of x){let P=_(b.join(r,y.name));if(y.isDirectory()){let l=y.name,T=l.startsWith("(")&&l.endsWith(")"),u=l.startsWith("@"),f=l.startsWith("[[...")&&l.endsWith("]]"),g=l.startsWith("[...")&&l.endsWith("]"),d=l.startsWith("[")&&l.endsWith("]"),{paramName:At,keyName:Rt}=wt(l,{isDynamic:d,isCatchAll:g,isOptionalCatchAll:f}),Ot=d||g||f?[...c,{paramName:At,routeType:{isDynamic:d,isCatchAll:g,isOptionalCatchAll:f,isGroup:T,isParallel:u}}]:c,J=T||u,{pathStructure:Z,imports:Lt,paramsTypes:Dt}=V(t,P,J?n:i,Ot);if(p.push(...Lt),m.push(...Dt),J){let tt=Z.match(/^\s*\{([\s\S]*)\}\s*$/);tt&&s.push(`${i}${tt[1].trim()}`)}else s.push(`${i}"${Rt}": ${Z}`)}else{let l=mt(t,P);if(l){let{importStatement:T,importPath:u,type:f}=l;p.push({statement:T,path:u}),a.push(f)}if(k.forEach(T=>{let u=lt(t,P,T);if(u){let{importStatement:f,importPath:g,type:d}=u;p.push({statement:f,path:g}),a.push(d)}}),a.push(j),c.length>0){let T=c.map(({paramName:f,routeType:g})=>{let d=g.isCatchAll?"string[]":g.isOptionalCatchAll?"string[] | undefined":"string";return{name:f,type:d}}),u=L(T);m.push({paramsType:u,dirPath:b.dirname(P)}),a.push(I(Q,u))}}}let A=a.join(" & "),F=s.length>0?`{${E}${s.join(`,${E}`)}${E}${n}}`:"",z={pathStructure:A&&F?`${A} & ${F}`:A||F,imports:p,paramsTypes:m};return N.set(r,z),z};var yt=(t,r)=>{let{pathStructure:e,imports:o,paramsTypes:n}=V(t,r),i=`export type PathStructure = ${e}${S}`,s=o.length?`${o.sort((c,x)=>c.path.localeCompare(x.path,void 0,{numeric:!0})).map(c=>c.statement).join(E)}`:"",p=ot.filter(c=>e.includes(c)),a=D(p.join(" ,"),nt),m=n.map(({paramsType:c,dirPath:x})=>({paramsType:`export type Params = ${c}${S}`,dirPath:x}));return{pathStructure:`${a}${E}${s}${E}${E}${i}`,paramsTypes:m}};import v from"chalk";var q=(t,r,e="\u2192",o=24)=>t.padEnd(o)+` ${e} ${r}`,B=(t=0)=>O.repeat(t),dt=()=>({info:(t,r={})=>{let{indentLevel:e=0,event:o}=r,n=o?`${v.cyan(`[${o}]`)} `:"";console.log(`${B(e)}${n}${t}`)},success:(t,r={})=>{let{indentLevel:e=0}=r;console.log(`${B(e)}${v.green("\u2713")} ${t}`)},error:(t,r={})=>{let{indentLevel:e=0}=r;console.error(`${B(e)}${v.red("\u2717")} ${v.red(t)}`)}});var _t=({baseDir:t,outputPath:r,paramsFileName:e,logger:o})=>{o.info("Generating types...",{event:"generate"});let{pathStructure:n,paramsTypes:i}=yt(r,t);Pt.writeFileSync(r,n),o.success(q("Path structure type",C(r),W,M),{indentLevel:Y}),e&&(i.forEach(({paramsType:s,dirPath:p})=>{let a=Yt.join(p,e);Pt.writeFileSync(a,s)}),o.success(q("Params types",e,W,M),{indentLevel:Y}))};import Mt from"chokidar";var St=(t,r)=>{let e=null,o=!1,n=null,i=async(...s)=>{o=!0;try{await t(...s)}finally{if(o=!1,n){let p=n;n=null,i(...p)}}};return(...s)=>{e&&clearTimeout(e),e=setTimeout(()=>{if(o){n=s;return}i(...s)},r)}};var xt=(t,r,e)=>{e.info(`${C(t)}`,{event:"watch"});let o=a=>R.some(m=>a.endsWith(m)),n=new Set,i=St(()=>{n.forEach(a=>{it(a),at(a)}),n.clear(),r()},300),s=Mt.watch(t,{ignoreInitial:!0,ignored:(a,m)=>!!m?.isFile()&&!o(a)});s.on("ready",()=>{i(),s.on("all",(a,m)=>{if(o(m)){let c=C(m);e.info(c,{event:a}),n.add(m),i()}})}),s.on("error",a=>{a instanceof Error?e.error(`Watcher error: ${a.message}`):e.error(`Unknown watcher error: ${String(a)}`)});let p=()=>{s.close().then(()=>{e.info("Watcher closed.",{event:"watch"})}).catch(a=>{e.error(`Failed to close watcher: ${a.message}`)})};process.on("SIGINT",p),process.on("SIGTERM",p)};var Ct=(t,r,e,o)=>{try{return _t({baseDir:t,outputPath:r,paramsFileName:e,logger:o}),w}catch(n){return n instanceof Error?o.error(`Failed to generate: ${n.message}`):o.error(`Unknown error occurred during generate: ${String(n)}`),$}},Nt=(t,r,e,o)=>{let n=_($t.resolve(t)),i=_($t.resolve(r)),s=typeof e.paramsFile=="string"?e.paramsFile:null;return e.paramsFile!==void 0&&!s?(o.error("Error: --params-file requires a filename."),$):e.watch?(xt(n,()=>{Ct(n,i,s,o)},o),w):Ct(n,i,s,o)};var It=(t,r=dt())=>{let e=new Wt;e.description("Generate RPC client type definitions based on the Next.js path structure.").argument("<baseDir>","Base directory containing Next.js paths for type generation").argument("<outputPath>","Output path for the generated type definitions").option("-w, --watch","Watch mode: regenerate on file changes").option("-p, --params-file [filename]","Generate params types file with specified filename").action(async(o,n,i)=>{try{let s=await Nt(o,n,i,r);i.watch||process.exit(s)}catch(s){r.error(`Unexpected error occurred:${s instanceof Error?s.message:String(s)}`),process.exit($)}}),e.parse(t)};It(process.argv);
4
4
  /*!
5
5
  * Inspired by pathpida (https://github.com/aspida/pathpida),
6
6
  * especially the design and UX of its CLI.
@@ -1,5 +1,6 @@
1
+ export declare const HTTP_METHODS: readonly ["GET", "HEAD", "OPTIONS", "POST", "PUT", "DELETE", "PATCH"];
1
2
  export declare const OPTIONAL_CATCH_ALL_PREFIX = "_____";
2
3
  export declare const CATCH_ALL_PREFIX = "___";
3
4
  export declare const DYNAMIC_PREFIX = "_";
4
5
  export declare const HTTP_METHODS_EXCLUDE_OPTIONS: ("GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "PATCH")[];
5
- export declare const HTTP_METHOD_FUNC_KEYS: ("$delete" | "$get" | "$head" | "$post" | "$put" | "$patch")[];
6
+ export declare const HTTP_METHOD_FUNC_KEYS: ("$get" | "$head" | "$post" | "$put" | "$delete" | "$patch")[];
@@ -1 +1 @@
1
- import{HTTP_METHODS as o}from"next/dist/server/web/http";const e="_____",r="___",E="_",t=o.filter(_=>_!=="OPTIONS"),O=t.map(_=>`$${_.toLowerCase()}`);export{r as CATCH_ALL_PREFIX,E as DYNAMIC_PREFIX,t as HTTP_METHODS_EXCLUDE_OPTIONS,O as HTTP_METHOD_FUNC_KEYS,e as OPTIONAL_CATCH_ALL_PREFIX};
1
+ const T=["GET","HEAD","OPTIONS","POST","PUT","DELETE","PATCH"],t="_____",E="___",e="_",o=T.filter(_=>_!=="OPTIONS"),P=o.map(_=>`$${_.toLowerCase()}`);export{E as CATCH_ALL_PREFIX,e as DYNAMIC_PREFIX,T as HTTP_METHODS,o as HTTP_METHODS_EXCLUDE_OPTIONS,P as HTTP_METHOD_FUNC_KEYS,t as OPTIONAL_CATCH_ALL_PREFIX};
@@ -1 +1,2 @@
1
- export type { HTTP_METHOD as HttpMethod } from "next/dist/server/web/http";
1
+ import type { HTTP_METHODS } from "./constants";
2
+ export type HttpMethod = (typeof HTTP_METHODS)[number];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rpc4next",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Inspired by Hono RPC and Pathpida, rpc4next brings a lightweight and intuitive RPC solution to Next.js, making server-client communication seamless",
5
5
  "author": "watanabe-1",
6
6
  "license": "MIT",