@lpdjs/firestore-repo-service 2.6.8 → 2.6.10
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/servers/hono/cli.cjs +52 -44
- package/dist/servers/hono/cli.cjs.map +1 -1
- package/dist/servers/hono/cli.js +52 -44
- package/dist/servers/hono/cli.js.map +1 -1
- package/dist/servers/hono/index.cjs +7 -7
- package/dist/servers/hono/index.cjs.map +1 -1
- package/dist/servers/hono/index.d.cts +553 -11
- package/dist/servers/hono/index.d.ts +553 -11
- package/dist/servers/hono/index.js +7 -7
- package/dist/servers/hono/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var fs=require('fs'),path=require('path'),process$1=require('process'),promises=require('readline/promises');var O={skipSegments:["useCases","useCase","use-cases","use-case"],casing:"preserve"};function M(e,t=O){let s=new Set(t.skipSegments.map(o=>o.toLowerCase()));return "/"+e.split("/").filter(Boolean).filter(o=>!s.has(o.toLowerCase())).map(o=>t.casing==="kebab"?
|
|
2
|
+
'use strict';var fs=require('fs'),path=require('path'),process$1=require('process'),promises=require('readline/promises');var O={skipSegments:["useCases","useCase","use-cases","use-case"],casing:"preserve"};function M(e,t=O){let s=new Set(t.skipSegments.map(o=>o.toLowerCase()));return "/"+e.split("/").filter(Boolean).filter(o=>!s.has(o.toLowerCase())).map(o=>t.casing==="kebab"?oe(o):o).join("/")}function oe(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function W(e,t,s){let r=H(e),o=H(t),i=0;for(;i<r.length&&i<o.length&&r[i]===o[i];)i++;let c=r.length-i,n=o.slice(i),d=(n[n.length-1]??"").replace(/\.[mc]?[tj]sx?$/i,""),f=s===""?d:`${d}${s}`;return n[n.length-1]=f,(c===0?"./":"../".repeat(c))+n.join("/")}function H(e){return e.replace(/\\/g,"/").replace(/\/+$/,"").split("/").filter((s,r)=>!(r===0&&s===""))}var ae="/**\n * AUTO-GENERATED by `@lpdjs/firestore-repo-service` Hono codegen.\n * Do not edit by hand \u2014 re-run `hono:gen` after adding / removing route files.\n */\n";function J(e,t){let s=path.dirname(t.outFile);fs.mkdirSync(s,{recursive:true});let r=t.banner??ae,o=(t.now??new Date).toISOString(),i=t.importExtension,c=[],n=[],a=[];e.forEach((f,p)=>{let P=W(s,f.absPath,i),y=M(f.relDir,t.derive);c.push(`import mod${p} from ${JSON.stringify(P)};`),n.push(` { __derivedPath: ${JSON.stringify(y)}, mod: mod${p} },`),a.push({source:f.relPath,url:y});});let d=`${r}// Generated at ${o} \u2014 ${e.length} route file${e.length===1?"":"s"}.
|
|
3
3
|
|
|
4
4
|
import type { AnyRouteDef, RouteModuleDefault } from "@lpdjs/firestore-repo-service/servers/hono";
|
|
5
5
|
|
|
@@ -8,16 +8,16 @@ import type { AnyRouteDef, RouteModuleDefault } from "@lpdjs/firestore-repo-serv
|
|
|
8
8
|
|
|
9
9
|
`:`
|
|
10
10
|
`)+`const __defs: { __derivedPath: string; mod: RouteModuleDefault }[] = [
|
|
11
|
-
`+
|
|
12
|
-
`)+(
|
|
11
|
+
`+n.join(`
|
|
12
|
+
`)+(n.length?`
|
|
13
13
|
`:"")+`];
|
|
14
14
|
|
|
15
15
|
export const routes: AnyRouteDef[] = __defs.flatMap(({ __derivedPath, mod }) => {
|
|
16
16
|
const list = Array.isArray(mod) ? mod : [mod];
|
|
17
17
|
return list.map((route) => ({ ...route, path: route.path ?? __derivedPath }));
|
|
18
18
|
});
|
|
19
|
-
`;return fs.writeFileSync(t.outFile,d,"utf8"),{outFile:t.outFile,routeCount:e.length,derivedPaths:a}}var
|
|
20
|
-
`,"utf8"),s}function
|
|
19
|
+
`;return fs.writeFileSync(t.outFile,d,"utf8"),{outFile:t.outFile,routeCount:e.length,derivedPaths:a}}var E={routesFile:"routes.ts",excludeSegments:["node_modules","__generated__","tests","__tests__",".turbo","dist","build",".next"]};function K(e,t=E){let s=[];return V(e,e,t,s),s.sort((r,o)=>r.relPath.localeCompare(o.relPath)),s}function V(e,t,s,r){let o;try{o=fs.readdirSync(t);}catch{return}for(let i of o){if(s.excludeSegments.includes(i))continue;let c=path.join(t,i),n;try{n=fs.statSync(c);}catch{continue}if(n.isDirectory())V(e,c,s,r);else if(n.isFile()&&i===s.routesFile){let a=path.relative(e,c).split(path.sep).join("/"),d=a.replace(/\/?[^/]+$/,"");r.push({absPath:c,relPath:a,relDir:d});}}}var ee=".frsrc.json";function T(e=process.cwd()){let t=path.resolve(e,ee);if(!fs.existsSync(t))return {};try{return JSON.parse(fs.readFileSync(t,"utf8"))}catch{return {}}}function he(e,t=process.cwd()){let s=path.resolve(t,ee),o={...T(t),...e};return fs.writeFileSync(s,`${JSON.stringify(o,null,2)}
|
|
20
|
+
`,"utf8"),s}function ve(e){let[t,...s]=e,r={};for(let o=0;o<s.length;o++){let i=s[o];if(!i.startsWith("--"))continue;let c=i.slice(2),n=s[o+1];n&&!n.startsWith("--")?(r[c]=n,o++):r[c]=true;}return {command:t??"help",flags:r}}function Z(){console.log(`frs \u2014 Hono file-based codegen
|
|
21
21
|
|
|
22
22
|
Usage:
|
|
23
23
|
frs init [flags]
|
|
@@ -83,7 +83,7 @@ Examples:
|
|
|
83
83
|
frs new createPost --domain posts --method post
|
|
84
84
|
frs new listPosts --domain posts --method get --api v1
|
|
85
85
|
frs add service postRepo
|
|
86
|
-
`);}function
|
|
86
|
+
`);}function Q(e){if(typeof e=="string")return e.split(",").map(t=>t.trim()).filter(Boolean)}function m(e){return typeof e=="string"?e:void 0}function te(e){if(e||!process$1.stdin.isTTY)return {ask:async(s,r)=>r??"",askChoice:async(s,r,o)=>o??"",askBool:async(s,r)=>r,close:()=>{}};let t=promises.createInterface({input:process$1.stdin,output:process$1.stdout});return {async ask(s,r){let o=r?` (${r})`:"";return (await t.question(`? ${s}${o} \u203A `)).trim()||r||""},async askChoice(s,r,o){let i=` [${r.join("/")}${o?`, default: ${o}`:""}]`;for(;;){let c=(await t.question(`? ${s}${i} \u203A `)).trim().toLowerCase();if(!c&&o)return o;if(r.includes(c))return c;console.log(` invalid choice \u2014 pick one of: ${r.join(", ")}`);}},async askBool(s,r){let o=` (${r?"Y/n":"y/N"})`,i=(await t.question(`? ${s}${o} \u203A `)).trim().toLowerCase();return i?i==="y"||i==="yes"||i==="true":r},close:()=>t.close()}}async function ye(e){let t=T(),s=m(e.root)??t.root;s||(console.error("[frs] --root is required (or run `frs init` to write it to .frsrc.json)"),process.exit(2));let r=path.resolve(process.cwd(),s);fs.existsSync(r)||(console.error(`[frs] root not found: ${r}`),process.exit(2));let o=m(e.out)??t.out??"__generated__/routes.ts",i=Q(e.skip)??O.skipSegments,c=m(e.casing)==="kebab"?"kebab":O.casing,n={skipSegments:i,casing:c},a=m(e.ext)??".js",d=Q(e.exclude)??E.excludeSegments,f=m(e["routes-file"])??E.routesFile,P=K(r,{routesFile:f,excludeSegments:d});P.length===0&&console.warn(`[frs] no "${f}" files found under ${r} \u2014 generated an empty manifest.`);let y=J(P,{outFile:path.resolve(r,o),derive:n,importExtension:a});if(!e.silent){console.log(`[frs] wrote ${y.outFile} (${y.routeCount} route${y.routeCount===1?"":"s"})`);for(let{source:S,url:g}of y.derivedPaths)console.log(` ${g.padEnd(48)} \u2190 ${S}`);}}async function $e(e,t){let s=t.yes===true,r=te(s),o=T();try{let i=e&&!e.startsWith("--")?e:void 0;i||(i=(await r.ask("Route name (e.g. createPost)")).trim(),i||(console.error("[frs] route name is required"),process.exit(2)));let c=m(t.domain);c||(c=(await r.ask("Domain name (e.g. posts)")).trim(),c||(console.error("[frs] --domain is required"),process.exit(2)));let n=m(t.root)??o.root??"src/domains",a=m(t.method)?.toLowerCase();a||(a=await r.askChoice("HTTP method",["get","post","put","patch","delete"],"post")),["get","post","put","patch","delete"].includes(a)||(console.error(`[frs] invalid --method: ${a}`),process.exit(2));let d=m(t.api);if(!d){let v=o.apis?.[0]??"v1";d=(await r.ask("API tag",v)).trim()||v;}let f=m(t["usecase-folder"])??o.useCaseFolder??"useCases",p=t["with-usecase"]===void 0?s?!0:await r.askBool("Scaffold useCase.ts?",!0):t["with-usecase"]!==!1,P=t["with-test"]===void 0?s||!p?p:await r.askBool("Scaffold useCase.test.ts (Vitest)?",!0):t["with-test"]!==!1,y=t.force===!0,S=path.resolve(process.cwd(),n),g=path.resolve(S,c,f,i),A=path.resolve(g,"routes.ts"),$=`${c}.${i}.useCase`,R=path.resolve(g,`${$}.ts`),k=path.resolve(g,`${$}.test.ts`);fs.mkdirSync(g,{recursive:!0});let F=v=>v.charAt(0).toUpperCase()+v.slice(1),w=`${F(c)}${F(i)}UseCase`,D="@lpdjs/firestore-repo-service/servers/hono",h=Se(S,g),b=a==="get"?"// GET \u2192 lu depuis les query params":`// ${a.toUpperCase()} \u2192 lu depuis le body JSON`,L=`/**
|
|
87
87
|
* ${w} \u2014 pure business logic, no HTTP awareness.
|
|
88
88
|
*
|
|
89
89
|
* Owns its Zod \`input\` / \`output\` schemas (declared as \`static\` members, the
|
|
@@ -93,11 +93,11 @@ Examples:
|
|
|
93
93
|
*/
|
|
94
94
|
|
|
95
95
|
import { z } from "zod";
|
|
96
|
-
import { UseCase } from "${
|
|
97
|
-
import type { Services } from "${
|
|
96
|
+
import { UseCase } from "${D}";
|
|
97
|
+
import type { Services } from "${h}";
|
|
98
98
|
|
|
99
99
|
const input = z.object({
|
|
100
|
-
${
|
|
100
|
+
${b}
|
|
101
101
|
example: z.string(),
|
|
102
102
|
});
|
|
103
103
|
|
|
@@ -116,22 +116,22 @@ export class ${w} extends UseCase<typeof input, typeof output, Services> {
|
|
|
116
116
|
return { id: payload.example };
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
`,
|
|
120
|
-
source: "query",`:"",
|
|
121
|
-
`:"",
|
|
122
|
-
import { useCaseRoute } from "${
|
|
123
|
-
${
|
|
119
|
+
`,l=a==="get"?`
|
|
120
|
+
source: "query",`:"",_=p?`import { ${w} } from "./${$}.js";
|
|
121
|
+
`:"",U=m(t["apis-import"])??Pe(S,g),se=p?`import { defineRoutes } from "${D}";
|
|
122
|
+
import { useCaseRoute } from "${U}";
|
|
123
|
+
${_}
|
|
124
124
|
export default defineRoutes([
|
|
125
125
|
useCaseRoute(${w}, {
|
|
126
126
|
api: "${d}",
|
|
127
|
-
method: "${a}",${
|
|
128
|
-
summary: "TODO: ${
|
|
127
|
+
method: "${a}",${l}
|
|
128
|
+
summary: "TODO: ${i}",
|
|
129
129
|
tags: ["${c}"],
|
|
130
130
|
}),
|
|
131
131
|
]);
|
|
132
132
|
`:`import { z } from "zod";
|
|
133
|
-
import { defineRoutes } from "${
|
|
134
|
-
import { defineRoute } from "${
|
|
133
|
+
import { defineRoutes } from "${D}";
|
|
134
|
+
import { defineRoute } from "${U}";
|
|
135
135
|
|
|
136
136
|
export default defineRoutes([
|
|
137
137
|
defineRoute({
|
|
@@ -139,7 +139,7 @@ export default defineRoutes([
|
|
|
139
139
|
method: "${a}",
|
|
140
140
|
|
|
141
141
|
input: z.object({
|
|
142
|
-
${
|
|
142
|
+
${b}
|
|
143
143
|
example: z.string(),
|
|
144
144
|
}),
|
|
145
145
|
|
|
@@ -147,7 +147,7 @@ export default defineRoutes([
|
|
|
147
147
|
id: z.string(),
|
|
148
148
|
}),
|
|
149
149
|
|
|
150
|
-
summary: "TODO: ${
|
|
150
|
+
summary: "TODO: ${i}",
|
|
151
151
|
tags: ["${c}"],
|
|
152
152
|
|
|
153
153
|
handler: async ({ input }) => {
|
|
@@ -156,9 +156,9 @@ export default defineRoutes([
|
|
|
156
156
|
},
|
|
157
157
|
}),
|
|
158
158
|
]);
|
|
159
|
-
`,z=[],G=[],
|
|
160
|
-
import type { Services } from "${
|
|
161
|
-
import { ${w} } from "./${
|
|
159
|
+
`,z=[],G=[],N=(v,re)=>{if(fs.existsSync(v)&&!y){G.push(v);return}fs.writeFileSync(v,re,"utf8"),z.push(v);};if(N(A,se),p&&N(R,L),p&&P){let v=`import { describe, it, expect } from "vitest";
|
|
160
|
+
import type { Services } from "${h}";
|
|
161
|
+
import { ${w} } from "./${$}.js";
|
|
162
162
|
|
|
163
163
|
describe("${w}", () => {
|
|
164
164
|
it("returns a response shaped like the output schema", async () => {
|
|
@@ -172,28 +172,36 @@ describe("${w}", () => {
|
|
|
172
172
|
|
|
173
173
|
// TODO: add error-path tests, repository mocks, etc.
|
|
174
174
|
});
|
|
175
|
-
`;
|
|
176
|
-
[frs] reminder: run "frs gen --root ${
|
|
177
|
-
basePath: "${
|
|
175
|
+
`;N(k,v);}for(let v of z)console.log(`[frs] wrote ${v}`);for(let v of G)console.log(`[frs] skipped ${v} (use --force to overwrite)`);console.log(`
|
|
176
|
+
[frs] reminder: run "frs gen --root ${n}" to refresh the manifest.`);}finally{r.close();}}async function we(e){let t=e.yes===true,s=te(t);try{let r=e.force===!0,o=m(e.root);o||(o=(await s.ask("Domain root","src/domains")).trim()||"src/domains");let i=m(e["apis-file"]);i||(i=(await s.ask("apis.ts location","src/apis.ts")).trim()||"src/apis.ts");let c=m(e["services-file"]);if(!c){let l=i.replace(/apis\.ts$/,"services.ts")||"src/services.ts";c=(await s.ask("services.ts location",l)).trim()||l;}let n=m(e.apis);n||(n=(await s.ask("API tags (comma-separated)","v1")).trim()||"v1");let a=n.split(",").map(l=>l.trim()).filter(Boolean);a.length===0&&(console.error("[frs] at least one API tag is required"),process.exit(2));let d=m(e["base-path"]),f=path.resolve(process.cwd(),o),p=path.resolve(process.cwd(),i),P=path.resolve(process.cwd(),c),y=path.resolve(f,"__generated__"),S=path.resolve(y,"routes.ts"),g=[],A=[],$=(l,_)=>{if(fs.mkdirSync(path.dirname(l),{recursive:!0}),fs.existsSync(l)&&!r){A.push(l);return}fs.writeFileSync(l,_,"utf8"),g.push(l);},R=a.map(l=>{let _=d??`/${l}`;return ` ${l}: {
|
|
177
|
+
basePath: "${_}",
|
|
178
178
|
openapi: {
|
|
179
179
|
info: { title: "${l.toUpperCase()} API", version: "1.0.0", description: "" },
|
|
180
180
|
},
|
|
181
|
+
// Built-in error mapping. Extend BaseErrorHandler to map your own
|
|
182
|
+
// domain errors, then swap it in here (per API).
|
|
183
|
+
errorHandler: new BaseErrorHandler(),
|
|
184
|
+
// Structured console logger. Extend BaseLogger (override \`write\`) to
|
|
185
|
+
// route to your sink, then swap it in here (per API).
|
|
186
|
+
logger: new BaseLogger(),
|
|
181
187
|
verbose: process.env["NODE_ENV"] !== "production",
|
|
182
188
|
},`}).join(`
|
|
183
|
-
`),
|
|
184
|
-
import { services } from "${
|
|
189
|
+
`),k=`import { BaseErrorHandler, BaseLogger, createApiRegistry } from "@lpdjs/firestore-repo-service/servers/hono";
|
|
190
|
+
import { services } from "${I(path.dirname(p),P)}";
|
|
185
191
|
|
|
186
192
|
/**
|
|
187
193
|
* Single source of truth for every API exposed by this project.
|
|
188
194
|
* Add per-API middlewares, interceptors, OpenAPI metadata here.
|
|
189
195
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
196
|
+
* Per-API resources injected into every handler / interceptor / error-handler
|
|
197
|
+
* context (override them per API above):
|
|
198
|
+
* - \`services\` \u2014 shared DI container (\`services.ctx.c\` = current request);
|
|
199
|
+
* - \`errorHandler\` \u2014 maps thrown errors \u2192 HTTP (extend \`BaseErrorHandler\`);
|
|
200
|
+
* - \`logger\` \u2014 structured logging (extend \`BaseLogger\`).
|
|
193
201
|
*/
|
|
194
202
|
export const apis = createApiRegistry(
|
|
195
203
|
{
|
|
196
|
-
${
|
|
204
|
+
${R}
|
|
197
205
|
},
|
|
198
206
|
{ services },
|
|
199
207
|
);
|
|
@@ -201,7 +209,7 @@ ${k}
|
|
|
201
209
|
/** Typed helpers used inside every route file. */
|
|
202
210
|
export const defineRoute = apis.defineRoute;
|
|
203
211
|
export const useCaseRoute = apis.useCaseRoute;
|
|
204
|
-
|
|
212
|
+
`;$(p,k),$(P,`import { createServices } from "@lpdjs/firestore-repo-service/servers/hono";
|
|
205
213
|
|
|
206
214
|
/**
|
|
207
215
|
* Global DI container \u2014 declare every singleton (repositories, SDK
|
|
@@ -234,22 +242,22 @@ export const services = createServices({
|
|
|
234
242
|
|
|
235
243
|
/** Convenience type \u2014 \`function fn(svc: Services) { ... }\`. */
|
|
236
244
|
export type Services = typeof services;
|
|
237
|
-
`);let
|
|
245
|
+
`);let w=`// AUTO-GENERATED by frs \u2014 do not edit.
|
|
238
246
|
// Run \`frs gen --root ${o}\` to refresh.
|
|
239
247
|
|
|
240
248
|
import type { AnyRouteDef } from "@lpdjs/firestore-repo-service/servers/hono";
|
|
241
249
|
|
|
242
250
|
export const routes: AnyRouteDef[] = [];
|
|
243
|
-
|
|
251
|
+
`;$(S,w);let D=he({root:o,apisFile:i,servicesFile:c,apis:a});g.push(D);let h=I(path.dirname(p),p),b=I(path.dirname(p),S),L=a.length===1?`export const { ${a[0]} } = apis.toFunctions(routes, onRequest, {`:`export const { ${a.join(", ")} } = apis.toFunctions(routes, onRequest, {`;for(let l of g)console.log(`[frs] wrote ${l}`);for(let l of A)console.log(`[frs] skipped ${l} (use --force to overwrite)`);console.log(`
|
|
244
252
|
Next steps:
|
|
245
253
|
|
|
246
254
|
1. Wire the registry in your Functions entrypoint (e.g. src/index.ts):
|
|
247
255
|
|
|
248
256
|
import { onRequest } from "firebase-functions/v2/https";
|
|
249
257
|
import { apis } from "${h}";
|
|
250
|
-
import { routes } from "${
|
|
258
|
+
import { routes } from "${b}";
|
|
251
259
|
|
|
252
|
-
${
|
|
260
|
+
${L}
|
|
253
261
|
defaults: { region: "us-central1", invoker: "public" },
|
|
254
262
|
});
|
|
255
263
|
|
|
@@ -260,10 +268,10 @@ Next steps:
|
|
|
260
268
|
3. Refresh the manifest before each build:
|
|
261
269
|
|
|
262
270
|
frs gen --root ${o}
|
|
263
|
-
`);}finally{s.close();}}function
|
|
271
|
+
`);}finally{s.close();}}function I(e,t){let s=path.relative(e,t).replace(/\\/g,"/");return s=s.replace(/\.ts$/,".js"),s.startsWith(".")||(s=`./${s}`),s}async function xe(e,t,s){e!=="service"&&(console.error(`[frs] unknown "add" target: ${e??"(missing)"} \u2014 supported: service`),process.exit(2)),t||(console.error("[frs] service name is required: frs add service <name>"),process.exit(2));let r=s.force===true,o=T(),c=[m(s["services-file"]),o.servicesFile,"src/services.ts","services.ts"].filter(h=>typeof h=="string"&&h.length>0),n;for(let h of c){let b=path.resolve(process.cwd(),h);if(fs.existsSync(b)){n=b;break}}if(!n){let h=c.map(b=>path.resolve(process.cwd(),b)).join(`
|
|
264
272
|
`);console.error(`[frs] services file not found. Tried:
|
|
265
273
|
${h}
|
|
266
|
-
Run \`frs init\` first or pass --services-file <path>.`),process.exit(2);}let a=m(s["services-dir"])??o.servicesDir??path.resolve(path.dirname(
|
|
274
|
+
Run \`frs init\` first or pass --services-file <path>.`),process.exit(2);}let a=m(s["services-dir"])??o.servicesDir??path.resolve(path.dirname(n),"services"),d=path.resolve(process.cwd(),a);fs.mkdirSync(d,{recursive:true});let f=`${t.charAt(0).toUpperCase()}${t.slice(1)}Service`,p=path.resolve(d,`${t}.ts`),P=`import type { RequestContext } from "@lpdjs/firestore-repo-service/servers/hono";
|
|
267
275
|
|
|
268
276
|
/**
|
|
269
277
|
* ${f} \u2014 generated by \`frs add service ${t}\`.
|
|
@@ -292,9 +300,9 @@ export class ${f} {
|
|
|
292
300
|
return \`hello from ${t} \u2014 user=\${this.ctx.maybeC?.get("user")?.id ?? "anonymous"}\`;
|
|
293
301
|
}
|
|
294
302
|
}
|
|
295
|
-
`;fs.existsSync(
|
|
296
|
-
`),
|
|
297
|
-
`),
|
|
298
|
-
`+
|
|
299
|
-
`),
|
|
303
|
+
`;fs.existsSync(p)&&!r?console.log(`[frs] skipped ${p} (use --force to overwrite)`):(fs.writeFileSync(p,P,"utf8"),console.log(`[frs] wrote ${p}`));let y=fs.readFileSync(n,"utf8"),S=I(path.dirname(n),p),g=`import { ${f} } from "${S}";`,A=` ${t}: ({ ctx }) => new ${f}(ctx),`;if(y.includes(g)){console.log(`[frs] services.ts already registers "${t}" \u2014 skipping.`);return}let $=y.split(`
|
|
304
|
+
`),R=-1;for(let h=0;h<$.length;h++)/^import\s/.test($[h])&&(R=h);R>=0?$.splice(R+1,0,g):$.unshift(g);let k=$.join(`
|
|
305
|
+
`),F=k.match(/createServices\s*\(\s*\{/);if(!F){console.error(`[frs] could not find \`createServices({\` in ${n} \u2014 register "${t}" manually.`);return}let w=F.index+F[0].length,D=k.slice(0,w)+`
|
|
306
|
+
`+A+k.slice(w);fs.writeFileSync(n,D,"utf8"),console.log(`[frs] updated ${n} (+ ${t})`);}function Pe(e,t){let s=["apis.ts","apis.js","api.ts","api.js"],r=[e,path.dirname(e),path.dirname(path.dirname(e))];for(let o of r)for(let i of s){let c=path.resolve(o,i);if(fs.existsSync(c)){let n=path.relative(t,c).replace(/\\/g,"/");return n=n.replace(/\.ts$/,".js").replace(/\.js$/,".js"),n.startsWith(".")||(n=`./${n}`),n}}return "../../../../apis.js"}function Se(e,t){let s=["services.ts","services.js"],r=[e,path.dirname(e),path.dirname(path.dirname(e))];for(let o of r)for(let i of s){let c=path.resolve(o,i);if(fs.existsSync(c)){let n=path.relative(t,c).replace(/\\/g,"/");return n=n.replace(/\.ts$/,".js"),n.startsWith(".")||(n=`./${n}`),n}}return "../../../../services.js"}async function be(){let e=process.argv.slice(2),{command:t,flags:s}=ve(e);switch(t){case "init":await we(s);return;case "gen":await ye(s);return;case "new":await $e(e[1],s);return;case "add":await xe(e[1],e[2],s);return;case "help":case "--help":case "-h":Z();return;default:console.error(`[frs] unknown command: ${t}
|
|
307
|
+
`),Z(),process.exit(2);}}be().catch(e=>{console.error(e),process.exit(1);});//# sourceMappingURL=cli.cjs.map
|
|
300
308
|
//# sourceMappingURL=cli.cjs.map
|