@lpdjs/firestore-repo-service 2.6.9 → 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.
|
@@ -989,6 +989,67 @@ declare function buildOpenApiDocument(routes: AnyRouteDef[], basePath: string, c
|
|
|
989
989
|
*/
|
|
990
990
|
declare function renderDocsHtml(specUrl: string, title: string): string;
|
|
991
991
|
|
|
992
|
+
/**
|
|
993
|
+
* Build a deep link to the GCP Cloud Logging "Logs Explorer", pre-filtered on a
|
|
994
|
+
* correlation id, so a developer can jump straight from an HTTP error response
|
|
995
|
+
* to the matching structured log.
|
|
996
|
+
*
|
|
997
|
+
* Designed as a dev ergonomic: keep it **disabled in production** (the link is
|
|
998
|
+
* meant for engineers, not end users) and enable it locally / in staging. The
|
|
999
|
+
* `errorId` returned by {@link BaseLogger.error} and carried by your `AppError`
|
|
1000
|
+
* is the same value used both in the response body and in the link's query.
|
|
1001
|
+
*
|
|
1002
|
+
* @example
|
|
1003
|
+
* ```ts
|
|
1004
|
+
* // package-level helper
|
|
1005
|
+
* const url = gcpLogsUrl(error.errorId, {
|
|
1006
|
+
* enabled: process.env.NODE_ENV !== "production",
|
|
1007
|
+
* projectId: "my-gcp-project", // or omit to read it from the environment
|
|
1008
|
+
* });
|
|
1009
|
+
*
|
|
1010
|
+
* // inside BaseErrorHandler.mapError
|
|
1011
|
+
* return c.json({ error: msg, errorId, ...(url ? { logsUrl: url } : {}) }, 412);
|
|
1012
|
+
* ```
|
|
1013
|
+
*/
|
|
1014
|
+
/** Options controlling {@link gcpLogsUrl}. */
|
|
1015
|
+
interface GcpLogsLinkOptions {
|
|
1016
|
+
/**
|
|
1017
|
+
* Master switch — when falsy, {@link gcpLogsUrl} returns `undefined` and no
|
|
1018
|
+
* link is produced. Default: `false` (opt-in). Wire it to e.g.
|
|
1019
|
+
* `process.env.NODE_ENV !== "production"`.
|
|
1020
|
+
*/
|
|
1021
|
+
enabled?: boolean;
|
|
1022
|
+
/**
|
|
1023
|
+
* GCP project id. Defaults to the first non-empty of
|
|
1024
|
+
* `GOOGLE_CLOUD_PROJECT`, `GCLOUD_PROJECT`, `GCP_PROJECT` (all auto-set on
|
|
1025
|
+
* Cloud Functions / Cloud Run). When none is resolvable, no link is built.
|
|
1026
|
+
*/
|
|
1027
|
+
projectId?: string;
|
|
1028
|
+
/**
|
|
1029
|
+
* Structured-log field that carries the correlation id. Must match what your
|
|
1030
|
+
* logger writes (the package's {@link BaseLogger} writes `errorId`).
|
|
1031
|
+
* Default: `"errorId"`.
|
|
1032
|
+
*/
|
|
1033
|
+
field?: string;
|
|
1034
|
+
/**
|
|
1035
|
+
* Optional lookback window appended to the query as an ISO-8601 duration
|
|
1036
|
+
* (e.g. `"PT1H"`, `"PT30M"`, `"P1D"`). Omit to let the Logs Explorer use its
|
|
1037
|
+
* default range.
|
|
1038
|
+
*/
|
|
1039
|
+
duration?: string;
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Resolve the GCP project id from an explicit value, falling back to the
|
|
1043
|
+
* standard environment variables. Returns `undefined` when none is set.
|
|
1044
|
+
*/
|
|
1045
|
+
declare function resolveGcpProjectId(explicit?: string): string | undefined;
|
|
1046
|
+
/**
|
|
1047
|
+
* Build the Logs Explorer URL filtered on `<field>="<errorId>"`, or return
|
|
1048
|
+
* `undefined` when the feature is disabled, the `errorId` is missing, or no
|
|
1049
|
+
* project id can be resolved (so callers can spread it safely).
|
|
1050
|
+
*/
|
|
1051
|
+
declare function gcpLogsUrl(errorId: string | undefined, options?: GcpLogsLinkOptions): string | undefined;
|
|
1052
|
+
|
|
992
1053
|
/**
|
|
993
1054
|
* `BaseErrorHandler` — the package's ready-to-use {@link ErrorHandler}.
|
|
994
1055
|
*
|
|
@@ -1024,7 +1085,29 @@ declare function renderDocsHtml(specUrl: string, title: string): string;
|
|
|
1024
1085
|
* ```
|
|
1025
1086
|
*/
|
|
1026
1087
|
|
|
1088
|
+
/** Construction options shared by every {@link BaseErrorHandler}. */
|
|
1089
|
+
interface BaseErrorHandlerOptions {
|
|
1090
|
+
/**
|
|
1091
|
+
* Enable building a GCP Logs Explorer deep link from an error's correlation
|
|
1092
|
+
* id (see {@link BaseErrorHandler.gcpLogsUrl}). Disabled by default — turn it
|
|
1093
|
+
* on in dev/staging to let engineers jump from a response to its log.
|
|
1094
|
+
*/
|
|
1095
|
+
gcpLogs?: GcpLogsLinkOptions;
|
|
1096
|
+
}
|
|
1027
1097
|
declare class BaseErrorHandler<TEnv extends Env = Env, TServices extends AnyServicesContainer = AnyServicesContainer> implements ErrorHandler<TEnv, TServices> {
|
|
1098
|
+
protected readonly options: BaseErrorHandlerOptions;
|
|
1099
|
+
constructor(options?: BaseErrorHandlerOptions);
|
|
1100
|
+
/**
|
|
1101
|
+
* Build a GCP Logs Explorer link for `errorId`, or `undefined` when the
|
|
1102
|
+
* `gcpLogs` option is disabled / unresolved. Spread it into a mapped
|
|
1103
|
+
* response to give developers a one-click jump to the matching log:
|
|
1104
|
+
*
|
|
1105
|
+
* ```ts
|
|
1106
|
+
* const logsUrl = this.gcpLogsUrl(error.errorId);
|
|
1107
|
+
* return c.json({ error, errorId, ...(logsUrl ? { logsUrl } : {}) }, status);
|
|
1108
|
+
* ```
|
|
1109
|
+
*/
|
|
1110
|
+
protected gcpLogsUrl(errorId?: string): string | undefined;
|
|
1028
1111
|
/**
|
|
1029
1112
|
* Orchestration — not meant to be overridden. Tries the user mapping first,
|
|
1030
1113
|
* logs it when matched, then falls back to the built-in mapping.
|
|
@@ -1287,4 +1370,4 @@ declare function generateRoutesManifest(routes: ScannedRoute[], opts: GeneratorO
|
|
|
1287
1370
|
/** Convenience helper used by the CLI — combines scan + generate in one call. */
|
|
1288
1371
|
declare function generateFromRoot(rootAbs: string, outFileRel: string, derive: PathDeriveOptions, importExtension: string, scan: (root: string) => ScannedRoute[]): GenerationResult;
|
|
1289
1372
|
|
|
1290
|
-
export { type AnyRouteDef, type AnyServicesContainer, type ApiConfig, type ApiConfigMap, type ApiKeySecurityScheme, type ApiRegistry, type ApiRegistryOptions, BadRequestError, BaseErrorHandler, BaseLogger, type BasicAuthOptions, DEFAULT_DERIVE, DEFAULT_GENERATOR_BANNER, DEFAULT_SCANNER, type DecodedBearerToken, type ErrorHandler, type ErrorHandlerContext, type FirebaseBearerAuthLike, type FirebaseBearerAuthOptions, type GenerationResult, type GeneratorOptions, HonoServer, type HonoServerOptions, type HttpMethod, type HttpSecurityScheme, type InterceptorConfig, type InterceptorErrorResponse, type InterceptorOption, type InterceptorOutput, type LogSeverity, type Logger, type MutualTlsSecurityScheme, type OAuth2SecurityScheme, type OAuthFlowObject, type OAuthFlowsObject, type OpenAPIConfig, type OpenAPIInfo, type OpenIdConnectSecurityScheme, OutputValidationError, type PathDeriveOptions, type PayloadSource, type RequestContext, type RouteDef, type RouteHandler, type RouteInput, type RouteInterceptor, type RouteModuleDefault, type RouteOutput, type RoutesUnion, type ScannedRoute, type ScannerOptions, type SecurityRequirement, type SecurityScheme, type SecuritySchemeBase, type ServiceProvider, type ServiceProviderMap, type ServicesContainer, type ServicesOf, UseCase, type UseCaseClass, type UseCaseRouteMeta, ValidationError, basicAuth, buildOpenApiDocument, createApiRegistry, createRequestContextMiddleware, createServices, defaultErrorResponse, defineRoutes, derivePath, firebaseBearerAuth, generateFromRoot, generateRoutesManifest, renderDocsHtml, scanRoutes, toImportSpecifier, useCaseRoute, withRequestContext };
|
|
1373
|
+
export { type AnyRouteDef, type AnyServicesContainer, type ApiConfig, type ApiConfigMap, type ApiKeySecurityScheme, type ApiRegistry, type ApiRegistryOptions, BadRequestError, BaseErrorHandler, type BaseErrorHandlerOptions, BaseLogger, type BasicAuthOptions, DEFAULT_DERIVE, DEFAULT_GENERATOR_BANNER, DEFAULT_SCANNER, type DecodedBearerToken, type ErrorHandler, type ErrorHandlerContext, type FirebaseBearerAuthLike, type FirebaseBearerAuthOptions, type GcpLogsLinkOptions, type GenerationResult, type GeneratorOptions, HonoServer, type HonoServerOptions, type HttpMethod, type HttpSecurityScheme, type InterceptorConfig, type InterceptorErrorResponse, type InterceptorOption, type InterceptorOutput, type LogSeverity, type Logger, type MutualTlsSecurityScheme, type OAuth2SecurityScheme, type OAuthFlowObject, type OAuthFlowsObject, type OpenAPIConfig, type OpenAPIInfo, type OpenIdConnectSecurityScheme, OutputValidationError, type PathDeriveOptions, type PayloadSource, type RequestContext, type RouteDef, type RouteHandler, type RouteInput, type RouteInterceptor, type RouteModuleDefault, type RouteOutput, type RoutesUnion, type ScannedRoute, type ScannerOptions, type SecurityRequirement, type SecurityScheme, type SecuritySchemeBase, type ServiceProvider, type ServiceProviderMap, type ServicesContainer, type ServicesOf, UseCase, type UseCaseClass, type UseCaseRouteMeta, ValidationError, basicAuth, buildOpenApiDocument, createApiRegistry, createRequestContextMiddleware, createServices, defaultErrorResponse, defineRoutes, derivePath, firebaseBearerAuth, gcpLogsUrl, generateFromRoot, generateRoutesManifest, renderDocsHtml, resolveGcpProjectId, scanRoutes, toImportSpecifier, useCaseRoute, withRequestContext };
|
|
@@ -989,6 +989,67 @@ declare function buildOpenApiDocument(routes: AnyRouteDef[], basePath: string, c
|
|
|
989
989
|
*/
|
|
990
990
|
declare function renderDocsHtml(specUrl: string, title: string): string;
|
|
991
991
|
|
|
992
|
+
/**
|
|
993
|
+
* Build a deep link to the GCP Cloud Logging "Logs Explorer", pre-filtered on a
|
|
994
|
+
* correlation id, so a developer can jump straight from an HTTP error response
|
|
995
|
+
* to the matching structured log.
|
|
996
|
+
*
|
|
997
|
+
* Designed as a dev ergonomic: keep it **disabled in production** (the link is
|
|
998
|
+
* meant for engineers, not end users) and enable it locally / in staging. The
|
|
999
|
+
* `errorId` returned by {@link BaseLogger.error} and carried by your `AppError`
|
|
1000
|
+
* is the same value used both in the response body and in the link's query.
|
|
1001
|
+
*
|
|
1002
|
+
* @example
|
|
1003
|
+
* ```ts
|
|
1004
|
+
* // package-level helper
|
|
1005
|
+
* const url = gcpLogsUrl(error.errorId, {
|
|
1006
|
+
* enabled: process.env.NODE_ENV !== "production",
|
|
1007
|
+
* projectId: "my-gcp-project", // or omit to read it from the environment
|
|
1008
|
+
* });
|
|
1009
|
+
*
|
|
1010
|
+
* // inside BaseErrorHandler.mapError
|
|
1011
|
+
* return c.json({ error: msg, errorId, ...(url ? { logsUrl: url } : {}) }, 412);
|
|
1012
|
+
* ```
|
|
1013
|
+
*/
|
|
1014
|
+
/** Options controlling {@link gcpLogsUrl}. */
|
|
1015
|
+
interface GcpLogsLinkOptions {
|
|
1016
|
+
/**
|
|
1017
|
+
* Master switch — when falsy, {@link gcpLogsUrl} returns `undefined` and no
|
|
1018
|
+
* link is produced. Default: `false` (opt-in). Wire it to e.g.
|
|
1019
|
+
* `process.env.NODE_ENV !== "production"`.
|
|
1020
|
+
*/
|
|
1021
|
+
enabled?: boolean;
|
|
1022
|
+
/**
|
|
1023
|
+
* GCP project id. Defaults to the first non-empty of
|
|
1024
|
+
* `GOOGLE_CLOUD_PROJECT`, `GCLOUD_PROJECT`, `GCP_PROJECT` (all auto-set on
|
|
1025
|
+
* Cloud Functions / Cloud Run). When none is resolvable, no link is built.
|
|
1026
|
+
*/
|
|
1027
|
+
projectId?: string;
|
|
1028
|
+
/**
|
|
1029
|
+
* Structured-log field that carries the correlation id. Must match what your
|
|
1030
|
+
* logger writes (the package's {@link BaseLogger} writes `errorId`).
|
|
1031
|
+
* Default: `"errorId"`.
|
|
1032
|
+
*/
|
|
1033
|
+
field?: string;
|
|
1034
|
+
/**
|
|
1035
|
+
* Optional lookback window appended to the query as an ISO-8601 duration
|
|
1036
|
+
* (e.g. `"PT1H"`, `"PT30M"`, `"P1D"`). Omit to let the Logs Explorer use its
|
|
1037
|
+
* default range.
|
|
1038
|
+
*/
|
|
1039
|
+
duration?: string;
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Resolve the GCP project id from an explicit value, falling back to the
|
|
1043
|
+
* standard environment variables. Returns `undefined` when none is set.
|
|
1044
|
+
*/
|
|
1045
|
+
declare function resolveGcpProjectId(explicit?: string): string | undefined;
|
|
1046
|
+
/**
|
|
1047
|
+
* Build the Logs Explorer URL filtered on `<field>="<errorId>"`, or return
|
|
1048
|
+
* `undefined` when the feature is disabled, the `errorId` is missing, or no
|
|
1049
|
+
* project id can be resolved (so callers can spread it safely).
|
|
1050
|
+
*/
|
|
1051
|
+
declare function gcpLogsUrl(errorId: string | undefined, options?: GcpLogsLinkOptions): string | undefined;
|
|
1052
|
+
|
|
992
1053
|
/**
|
|
993
1054
|
* `BaseErrorHandler` — the package's ready-to-use {@link ErrorHandler}.
|
|
994
1055
|
*
|
|
@@ -1024,7 +1085,29 @@ declare function renderDocsHtml(specUrl: string, title: string): string;
|
|
|
1024
1085
|
* ```
|
|
1025
1086
|
*/
|
|
1026
1087
|
|
|
1088
|
+
/** Construction options shared by every {@link BaseErrorHandler}. */
|
|
1089
|
+
interface BaseErrorHandlerOptions {
|
|
1090
|
+
/**
|
|
1091
|
+
* Enable building a GCP Logs Explorer deep link from an error's correlation
|
|
1092
|
+
* id (see {@link BaseErrorHandler.gcpLogsUrl}). Disabled by default — turn it
|
|
1093
|
+
* on in dev/staging to let engineers jump from a response to its log.
|
|
1094
|
+
*/
|
|
1095
|
+
gcpLogs?: GcpLogsLinkOptions;
|
|
1096
|
+
}
|
|
1027
1097
|
declare class BaseErrorHandler<TEnv extends Env = Env, TServices extends AnyServicesContainer = AnyServicesContainer> implements ErrorHandler<TEnv, TServices> {
|
|
1098
|
+
protected readonly options: BaseErrorHandlerOptions;
|
|
1099
|
+
constructor(options?: BaseErrorHandlerOptions);
|
|
1100
|
+
/**
|
|
1101
|
+
* Build a GCP Logs Explorer link for `errorId`, or `undefined` when the
|
|
1102
|
+
* `gcpLogs` option is disabled / unresolved. Spread it into a mapped
|
|
1103
|
+
* response to give developers a one-click jump to the matching log:
|
|
1104
|
+
*
|
|
1105
|
+
* ```ts
|
|
1106
|
+
* const logsUrl = this.gcpLogsUrl(error.errorId);
|
|
1107
|
+
* return c.json({ error, errorId, ...(logsUrl ? { logsUrl } : {}) }, status);
|
|
1108
|
+
* ```
|
|
1109
|
+
*/
|
|
1110
|
+
protected gcpLogsUrl(errorId?: string): string | undefined;
|
|
1028
1111
|
/**
|
|
1029
1112
|
* Orchestration — not meant to be overridden. Tries the user mapping first,
|
|
1030
1113
|
* logs it when matched, then falls back to the built-in mapping.
|
|
@@ -1287,4 +1370,4 @@ declare function generateRoutesManifest(routes: ScannedRoute[], opts: GeneratorO
|
|
|
1287
1370
|
/** Convenience helper used by the CLI — combines scan + generate in one call. */
|
|
1288
1371
|
declare function generateFromRoot(rootAbs: string, outFileRel: string, derive: PathDeriveOptions, importExtension: string, scan: (root: string) => ScannedRoute[]): GenerationResult;
|
|
1289
1372
|
|
|
1290
|
-
export { type AnyRouteDef, type AnyServicesContainer, type ApiConfig, type ApiConfigMap, type ApiKeySecurityScheme, type ApiRegistry, type ApiRegistryOptions, BadRequestError, BaseErrorHandler, BaseLogger, type BasicAuthOptions, DEFAULT_DERIVE, DEFAULT_GENERATOR_BANNER, DEFAULT_SCANNER, type DecodedBearerToken, type ErrorHandler, type ErrorHandlerContext, type FirebaseBearerAuthLike, type FirebaseBearerAuthOptions, type GenerationResult, type GeneratorOptions, HonoServer, type HonoServerOptions, type HttpMethod, type HttpSecurityScheme, type InterceptorConfig, type InterceptorErrorResponse, type InterceptorOption, type InterceptorOutput, type LogSeverity, type Logger, type MutualTlsSecurityScheme, type OAuth2SecurityScheme, type OAuthFlowObject, type OAuthFlowsObject, type OpenAPIConfig, type OpenAPIInfo, type OpenIdConnectSecurityScheme, OutputValidationError, type PathDeriveOptions, type PayloadSource, type RequestContext, type RouteDef, type RouteHandler, type RouteInput, type RouteInterceptor, type RouteModuleDefault, type RouteOutput, type RoutesUnion, type ScannedRoute, type ScannerOptions, type SecurityRequirement, type SecurityScheme, type SecuritySchemeBase, type ServiceProvider, type ServiceProviderMap, type ServicesContainer, type ServicesOf, UseCase, type UseCaseClass, type UseCaseRouteMeta, ValidationError, basicAuth, buildOpenApiDocument, createApiRegistry, createRequestContextMiddleware, createServices, defaultErrorResponse, defineRoutes, derivePath, firebaseBearerAuth, generateFromRoot, generateRoutesManifest, renderDocsHtml, scanRoutes, toImportSpecifier, useCaseRoute, withRequestContext };
|
|
1373
|
+
export { type AnyRouteDef, type AnyServicesContainer, type ApiConfig, type ApiConfigMap, type ApiKeySecurityScheme, type ApiRegistry, type ApiRegistryOptions, BadRequestError, BaseErrorHandler, type BaseErrorHandlerOptions, BaseLogger, type BasicAuthOptions, DEFAULT_DERIVE, DEFAULT_GENERATOR_BANNER, DEFAULT_SCANNER, type DecodedBearerToken, type ErrorHandler, type ErrorHandlerContext, type FirebaseBearerAuthLike, type FirebaseBearerAuthOptions, type GcpLogsLinkOptions, type GenerationResult, type GeneratorOptions, HonoServer, type HonoServerOptions, type HttpMethod, type HttpSecurityScheme, type InterceptorConfig, type InterceptorErrorResponse, type InterceptorOption, type InterceptorOutput, type LogSeverity, type Logger, type MutualTlsSecurityScheme, type OAuth2SecurityScheme, type OAuthFlowObject, type OAuthFlowsObject, type OpenAPIConfig, type OpenAPIInfo, type OpenIdConnectSecurityScheme, OutputValidationError, type PathDeriveOptions, type PayloadSource, type RequestContext, type RouteDef, type RouteHandler, type RouteInput, type RouteInterceptor, type RouteModuleDefault, type RouteOutput, type RoutesUnion, type ScannedRoute, type ScannerOptions, type SecurityRequirement, type SecurityScheme, type SecuritySchemeBase, type ServiceProvider, type ServiceProviderMap, type ServicesContainer, type ServicesOf, UseCase, type UseCaseClass, type UseCaseRouteMeta, ValidationError, basicAuth, buildOpenApiDocument, createApiRegistry, createRequestContextMiddleware, createServices, defaultErrorResponse, defineRoutes, derivePath, firebaseBearerAuth, gcpLogsUrl, generateFromRoot, generateRoutesManifest, renderDocsHtml, resolveGcpProjectId, scanRoutes, toImportSpecifier, useCaseRoute, withRequestContext };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Hono}from'hono';import {getRequestListener}from'@hono/node-server';import {extendZodWithOpenApi,OpenAPIRegistry,OpenApiGeneratorV31}from'@asteasolutions/zod-to-openapi';import {z as z$1}from'zod';import {AsyncLocalStorage}from'async_hooks';import {readdirSync,statSync,mkdirSync,writeFileSync}from'fs';import {join,relative,sep,dirname}from'path';function
|
|
1
|
+
import {Hono}from'hono';import {getRequestListener}from'@hono/node-server';import {extendZodWithOpenApi,OpenAPIRegistry,OpenApiGeneratorV31}from'@asteasolutions/zod-to-openapi';import {z as z$1}from'zod';import {AsyncLocalStorage}from'async_hooks';import {readdirSync,statSync,mkdirSync,writeFileSync}from'fs';import {join,relative,sep,dirname}from'path';function Q(t){return t}var v=class extends Error{constructor(n,o){super("Request validation failed");this.zodError=n;this.source=o;this.statusCode=400;this.name="ValidationError";}};var T=class extends Error{constructor(n){super(n);this.statusCode=400;this.name="BadRequestError";}},S=class extends Error{constructor(n){super("Output validation failed");this.zodError=n;this.statusCode=500;this.name="OutputValidationError";}};function _(t){return t.issues.map(e=>({path:e.path.join("."),code:e.code,message:e.message}))}function E(t,e){return e instanceof v?t.json({success:false,error:"Validation failed",issues:_(e.zodError)},400):e instanceof T?t.json({success:false,error:"Bad Request",message:e.message},400):e instanceof S?t.json({success:false,error:"Output validation failed",issues:_(e.zodError)},500):null}extendZodWithOpenApi(z$1);var U="Successful response",Z="Error response";function re(t){return t==="get"?"query":"json"}function oe(t,e){let n=e?.output;return n?typeof n=="function"?n(t):n:t}function se(t){if(typeof t.safeParse=="function")return {description:Z,schema:t};let e=t;return {description:e.description??Z,schema:e.schema}}function C(t,e,n,o){let s=new OpenAPIRegistry;if(n.securitySchemes)for(let[i,c]of Object.entries(n.securitySchemes))s.registerComponent("securitySchemes",i,c);for(let i of t){let c=i.method,p=i.source??re(c),u=ce(e,i.path??"/"),d=i.status??200,m=ie(c,p,i.input),g=$(p,i.input,"query"),h=$(p,i.input,"param"),f=pe(c,u),l=oe(i.output,o),y={[d]:l?{description:U,content:{"application/json":{schema:l}}}:{description:U}};if(o?.errors)for(let[x,A]of Object.entries(o.errors)){let{description:q,schema:L}=se(A);y[x]=L?{description:q,content:{"application/json":{schema:L}}}:{description:q};}s.registerPath({method:c,path:ae(u),operationId:f,summary:i.summary,description:i.description,tags:i.tags,deprecated:i.deprecated,security:i.security,request:{...g?{query:g}:{},...h?{params:h}:{},...m?{body:m}:{}},responses:y});}return new OpenApiGeneratorV31(s.definitions).generateDocument({openapi:"3.1.0",info:n.info,servers:n.servers,security:n.security})}function ie(t,e,n){return !n||t==="get"?null:e==="json"?{content:{"application/json":{schema:n}}}:e==="form"?{content:{"application/x-www-form-urlencoded":{schema:n}}}:null}function $(t,e,n){if(e&&(n==="query"&&t==="query"||n==="param"&&t==="param"))return e}function ae(t){return t.replace(/:([A-Za-z0-9_]+)/g,"{$1}")}function ce(t,e){let n=t.endsWith("/")?t.slice(0,-1):t,o=e.startsWith("/")?e:`/${e}`,s=`${n}${o}`;return s===""?"/":s}function pe(t,e){let n=e.replace(/[{}]/g,"").replace(/\/+/g,"_").replace(/[^A-Za-z0-9_]/g,"").replace(/^_+|_+$/g,"");return `${t}_${n||"root"}`}function P(t,e){let n=t.replace(/"/g,""");return `<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
@@ -9,7 +9,7 @@ import {Hono}from'hono';import {getRequestListener}from'@hono/node-server';impor
|
|
|
9
9
|
<script id="api-reference" data-url="${n}"></script>
|
|
10
10
|
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
11
11
|
</body>
|
|
12
|
-
</html>`}var O=new AsyncLocalStorage,pe=Object.freeze({get c(){let t=O.getStore();if(!t)throw new Error("[services] requestContext.c was accessed outside of a request. Wrap non-HTTP code paths (cron, triggers, scripts, tests) in `withRequestContext({ c }, () => ...)` to supply a Hono Context.");return t.c},get maybeC(){return O.getStore()?.c}});function I(){return async(t,e)=>{await O.run({c:t},async()=>{await e();});}}function ue(t,e){return O.run({c:t.c},async()=>e())}var w="ctx";function de(t){let e=new Map,n=[],r=new Proxy({},{get(s,o){if(typeof o!="string")return;if(o===w)return pe;if(e.has(o))return e.get(o);let a=t[o];if(typeof a!="function")throw new Error(`[services] unknown service "${o}". Registered: ${[w,...Object.keys(t)].join(", ")}`);if(n.includes(o))throw new Error(`[services] circular dependency detected: ${[...n,o].join(" \u2192 ")}`);n.push(o);try{let i=le(a)?new a(r):a(r);return e.set(o,i),i}finally{n.pop();}},has(s,o){return typeof o!="string"?false:o===w||o in t},ownKeys(){return [w,...Object.keys(t)]},getOwnPropertyDescriptor(s,o){if(typeof o=="string"&&(o===w||o in t))return {enumerable:true,configurable:true}}});return r}function le(t){return /^class[\s{]/.test(Function.prototype.toString.call(t))}var ge=Object.freeze({}),R=class{constructor(e){this.cachedSpec=null;this.options=e,this.app=new Hono,this.mountedRoutes=ve(e.routes,e.api),e.services&&this.app.use("*",I());let n=[...e.middlewares??[],...e.globalMiddlewares??[]];for(let r of n)this.app.use("*",r);this.mountRoutes(),this.mountOpenApi(),e.notFound&&this.app.notFound(e.notFound),e.onError&&this.app.onError(e.onError);}get hono(){return this.app}get nodeHandler(){return getRequestListener(this.app.fetch,{overrideGlobalObjects:false})}toFunction(e,n){let r=this.nodeHandler;return n?e(n,r):e(r)}buildOpenApiSpec(){if(this.cachedSpec)return this.cachedSpec;if(!this.options.openapi)throw new Error("[HonoServer] openapi config not set");return this.cachedSpec=C(this.mountedRoutes,this.options.basePath??"",this.options.openapi,me(this.options.interceptor)),this.cachedSpec}mountRoutes(){let e=this.options.basePath??"",n=this.options.validateOutput??false,r=this.options.verbose??false;for(let s of this.mountedRoutes){if(!s.path)throw new Error(`[HonoServer] route "${s.method.toUpperCase()} (no path)" \u2014 missing \`path\`. Run the codegen so the path is derived from the file location, or set it explicitly.`);let o=k(e,s.path),a=s.middlewares??[],i=s.source??(s.method==="get"?"query":"json"),c=Se(s,i,n,he(this.options.interceptor),this.options.services,this.options.errorHandler,this.options.logger),p=s.method.toUpperCase();this.app.on(p,[o],...a,c),r&&console.log(`[HonoServer] ${s.method.toUpperCase().padEnd(6)} ${o}`);}}mountOpenApi(){let e=this.options.openapi;if(!e)return;let n=e.path??"/openapi.json",r=e.docsPath===void 0?"/docs":e.docsPath,s=k(this.options.basePath??"",n),o=r===false?null:k(this.options.basePath??"",r),a=e.docsAuth?Array.isArray(e.docsAuth)?e.docsAuth:[e.docsAuth]:[];if(this.app.on("GET",[s],...a,i=>i.json(this.buildOpenApiSpec())),o){let i=Te(o,s);this.app.on("GET",[o],...a,c=>c.html(P(i,e.info.title)));}}};function $(t){return typeof t=="object"&&t!==null&&typeof t.handler=="function"}function he(t){if(t)return $(t)?t.handler:t}function me(t){return $(t)?t:void 0}function ve(t,e){return e?t.filter(n=>Array.isArray(n.api)?n.api.includes(e):n.api===e):t.slice()}function k(t,e){let n=t.endsWith("/")?t.slice(0,-1):t,r=e.startsWith("/")?e:`/${e}`,s=`${n}${r}`;return s===""?"/":s}function Te(t,e){let n=t.split("/").filter(Boolean),r=e.split("/").filter(Boolean);n.pop();let s=0;for(;s<n.length&&s<r.length&&n[s]===r[s];)s++;let o=n.length-s;return [...Array(o).fill(".."),...r.slice(s)].join("/")||"./"}function Se(t,e,n,r,s,o,a){let i=t.input,c=t.output,p=t.status??200,u=s??ge;return async d=>{let m=async f=>{if(o){let l=await o.handle({error:f,c:d,route:t,services:u,logger:a});if(l)return l}return E(d,f)},g=async()=>{let f;if(i){let y;try{y=await Re(d,e,t.method);}catch(A){throw new T(A instanceof Error?A.message:String(A))}let x=i.safeParse(y);if(!x.success)throw new v(x.error,e);f=x.data;}let l=await t.handler({input:f,c:d,services:u,errorHandler:o,logger:a});if(n&&c&&!(l instanceof Response)){let y=c.safeParse(l);if(!y.success)throw new S(y.error);return y.data}return l},h;if(r)try{h=await r({next:g,route:t,c:d,services:u,errorHandler:o,logger:a});}catch(f){let l=await m(f);if(l)return l;throw f}else try{h=await g();}catch(f){let l=await m(f);if(l)return l;throw f}return h instanceof Response?h:d.json(h,p)}}async function Re(t,e,n){switch(e){case "json":{if(n==="get")return t.req.query();let r=await t.req.text();if(!r)return {};try{return JSON.parse(r)}catch(s){throw new Error(`Invalid JSON body: ${s instanceof Error?s.message:String(s)}`)}}case "query":return t.req.query();case "form":return await t.req.parseBody();case "param":return t.req.param();default:return {}}}var b=class{constructor(e){this.services=e;}};function H(t,e){return {...e,input:t.input,output:t.output,handler:({input:n,services:r})=>new t(r).execute(n)}}function xe(t,e){let n=e?.services,r=e?.errorHandler,s=e?.logger;return {configs:t,defineRoute(o){return o},useCaseRoute(o,a){return H(o,a)},serverFor(o,a){let i=t[o];if(!i)throw new Error(`[ApiRegistry] unknown api "${o}". Registered: ${Object.keys(t).join(", ")}`);return new R({...i,api:o,routes:a,services:n,errorHandler:i.errorHandler??r,logger:i.logger??s})},toFunctions(o,a,i){let c={};for(let p of Object.keys(t)){let u={...i?.defaults??{},...i?.per?.[p]??{}},d=new R({...t[p],api:p,routes:o,services:n,errorHandler:t[p].errorHandler??r,logger:t[p].logger??s});c[p]=Object.keys(u).length?d.toFunction(a,u):d.toFunction(a);}return c}}}var M=class{async handle(e){let n=await this.mapError(e);return n?(this.logError(e,n),n):this.handleBuiltin(e)}mapError(e){return null}logError(e,n){}handleBuiltin(e){return E(e.c,e.error)}};var D=class t{info(e,n){this.write("INFO",this.payload(e,n));}warn(e,n){this.write("WARNING",this.payload(e,n));}debug(e,n){this.write("DEBUG",this.payload(e,n));}error(e,n){let r=t.errorId(e);return this.write("ERROR",{errorId:r,message:e instanceof Error?e.message:String(e),...e instanceof Error&&e.stack?{stack:e.stack}:{},...n!==void 0?{meta:n}:{}}),r}payload(e,n){return n!==void 0?{message:e,meta:n}:{message:e}}write(e,n){let r={severity:e,...n};e==="ERROR"?console.error(r):e==="WARNING"?console.warn(r):console.log(r);}static errorId(e){return e&&typeof e=="object"&&"errorId"in e&&typeof e.errorId=="string"?e.errorId:Math.random().toString(36).slice(2,12)}};function Ae(t){let{getAuth:e,allow:n,checkRevoked:r=false,contextKey:s="docsUser"}=t;return async(o,a)=>{let c=(o.req.header("authorization")??o.req.header("Authorization"))?.match(/^Bearer\s+(.+)$/i);if(!c)return o.json({error:"Unauthorized"},401,{"WWW-Authenticate":"Bearer"});let p;try{p=await e().verifyIdToken(c[1],r);}catch{return o.json({error:"Unauthorized"},401,{"WWW-Authenticate":"Bearer"})}if(n){let u=false;try{u=await n(p);}catch{u=false;}if(!u)return o.json({error:"Forbidden"},403)}return o.set(s,p),a()}}function Ee(t){let{username:e,password:n,realm:r="Docs"}=t,s=`Basic ${btoa(`${e}:${n}`)}`;return async(o,a)=>{let i=o.req.header("authorization")??o.req.header("Authorization")??"";return we(i,s)?a():o.text("Unauthorized",401,{"WWW-Authenticate":`Basic realm="${r}"`})}}function we(t,e){if(t.length!==e.length)return false;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}var N={skipSegments:["useCases","useCase","use-cases","use-case"],casing:"preserve"};function z(t,e=N){let n=new Set(e.skipSegments.map(s=>s.toLowerCase()));return "/"+t.split("/").filter(Boolean).filter(s=>!n.has(s.toLowerCase())).map(s=>e.casing==="kebab"?Oe(s):s).join("/")}function Oe(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function F(t,e,n){let r=L(t),s=L(e),o=0;for(;o<r.length&&o<s.length&&r[o]===s[o];)o++;let a=r.length-o,i=s.slice(o),p=(i[i.length-1]??"").replace(/\.[mc]?[tj]sx?$/i,""),u=n===""?p:`${p}${n}`;return i[i.length-1]=u,(a===0?"./":"../".repeat(a))+i.join("/")}function L(t){return t.replace(/\\/g,"/").replace(/\/+$/,"").split("/").filter((n,r)=>!(r===0&&n===""))}var K={routesFile:"routes.ts",excludeSegments:["node_modules","__generated__","tests","__tests__",".turbo","dist","build",".next"]};function He(t,e=K){let n=[];return G(t,t,e,n),n.sort((r,s)=>r.relPath.localeCompare(s.relPath)),n}function G(t,e,n,r){let s;try{s=readdirSync(e);}catch{return}for(let o of s){if(n.excludeSegments.includes(o))continue;let a=join(e,o),i;try{i=statSync(a);}catch{continue}if(i.isDirectory())G(t,a,n,r);else if(i.isFile()&&o===n.routesFile){let c=relative(t,a).split(sep).join("/"),p=c.replace(/\/?[^/]+$/,"");r.push({absPath:a,relPath:c,relDir:p});}}}var W="/**\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 V(t,e){let n=dirname(e.outFile);mkdirSync(n,{recursive:true});let r=e.banner??W,s=(e.now??new Date).toISOString(),o=e.importExtension,a=[],i=[],c=[];t.forEach((u,d)=>{let m=F(n,u.absPath,o),g=z(u.relDir,e.derive);a.push(`import mod${d} from ${JSON.stringify(m)};`),i.push(` { __derivedPath: ${JSON.stringify(g)}, mod: mod${d} },`),c.push({source:u.relPath,url:g});});let p=`${r}// Generated at ${s} \u2014 ${t.length} route file${t.length===1?"":"s"}.
|
|
12
|
+
</html>`}var w=new AsyncLocalStorage,de=Object.freeze({get c(){let t=w.getStore();if(!t)throw new Error("[services] requestContext.c was accessed outside of a request. Wrap non-HTTP code paths (cron, triggers, scripts, tests) in `withRequestContext({ c }, () => ...)` to supply a Hono Context.");return t.c},get maybeC(){return w.getStore()?.c}});function I(){return async(t,e)=>{await w.run({c:t},async()=>{await e();});}}function le(t,e){return w.run({c:t.c},async()=>e())}var O="ctx";function fe(t){let e=new Map,n=[],o=new Proxy({},{get(s,r){if(typeof r!="string")return;if(r===O)return de;if(e.has(r))return e.get(r);let a=t[r];if(typeof a!="function")throw new Error(`[services] unknown service "${r}". Registered: ${[O,...Object.keys(t)].join(", ")}`);if(n.includes(r))throw new Error(`[services] circular dependency detected: ${[...n,r].join(" \u2192 ")}`);n.push(r);try{let i=ye(a)?new a(o):a(o);return e.set(r,i),i}finally{n.pop();}},has(s,r){return typeof r!="string"?false:r===O||r in t},ownKeys(){return [O,...Object.keys(t)]},getOwnPropertyDescriptor(s,r){if(typeof r=="string"&&(r===O||r in t))return {enumerable:true,configurable:true}}});return o}function ye(t){return /^class[\s{]/.test(Function.prototype.toString.call(t))}var me=Object.freeze({}),R=class{constructor(e){this.cachedSpec=null;this.options=e,this.app=new Hono,this.mountedRoutes=Se(e.routes,e.api),e.services&&this.app.use("*",I());let n=[...e.middlewares??[],...e.globalMiddlewares??[]];for(let o of n)this.app.use("*",o);this.mountRoutes(),this.mountOpenApi(),e.notFound&&this.app.notFound(e.notFound),e.onError&&this.app.onError(e.onError);}get hono(){return this.app}get nodeHandler(){return getRequestListener(this.app.fetch,{overrideGlobalObjects:false})}toFunction(e,n){let o=this.nodeHandler;return n?e(n,o):e(o)}buildOpenApiSpec(){if(this.cachedSpec)return this.cachedSpec;if(!this.options.openapi)throw new Error("[HonoServer] openapi config not set");return this.cachedSpec=C(this.mountedRoutes,this.options.basePath??"",this.options.openapi,Te(this.options.interceptor)),this.cachedSpec}mountRoutes(){let e=this.options.basePath??"",n=this.options.validateOutput??false,o=this.options.verbose??false;for(let s of this.mountedRoutes){if(!s.path)throw new Error(`[HonoServer] route "${s.method.toUpperCase()} (no path)" \u2014 missing \`path\`. Run the codegen so the path is derived from the file location, or set it explicitly.`);let r=k(e,s.path),a=s.middlewares??[],i=s.source??(s.method==="get"?"query":"json"),c=xe(s,i,n,ve(this.options.interceptor),this.options.services,this.options.errorHandler,this.options.logger),p=s.method.toUpperCase();this.app.on(p,[r],...a,c),o&&console.log(`[HonoServer] ${s.method.toUpperCase().padEnd(6)} ${r}`);}}mountOpenApi(){let e=this.options.openapi;if(!e)return;let n=e.path??"/openapi.json",o=e.docsPath===void 0?"/docs":e.docsPath,s=k(this.options.basePath??"",n),r=o===false?null:k(this.options.basePath??"",o),a=e.docsAuth?Array.isArray(e.docsAuth)?e.docsAuth:[e.docsAuth]:[];if(this.app.on("GET",[s],...a,i=>i.json(this.buildOpenApiSpec())),r){let i=Re(r,s);this.app.on("GET",[r],...a,c=>c.html(P(i,e.info.title)));}}};function B(t){return typeof t=="object"&&t!==null&&typeof t.handler=="function"}function ve(t){if(t)return B(t)?t.handler:t}function Te(t){return B(t)?t:void 0}function Se(t,e){return e?t.filter(n=>Array.isArray(n.api)?n.api.includes(e):n.api===e):t.slice()}function k(t,e){let n=t.endsWith("/")?t.slice(0,-1):t,o=e.startsWith("/")?e:`/${e}`,s=`${n}${o}`;return s===""?"/":s}function Re(t,e){let n=t.split("/").filter(Boolean),o=e.split("/").filter(Boolean);n.pop();let s=0;for(;s<n.length&&s<o.length&&n[s]===o[s];)s++;let r=n.length-s;return [...Array(r).fill(".."),...o.slice(s)].join("/")||"./"}function xe(t,e,n,o,s,r,a){let i=t.input,c=t.output,p=t.status??200,u=s??me;return async d=>{let m=async f=>{if(r){let l=await r.handle({error:f,c:d,route:t,services:u,logger:a});if(l)return l}return E(d,f)},g=async()=>{let f;if(i){let y;try{y=await Ae(d,e,t.method);}catch(A){throw new T(A instanceof Error?A.message:String(A))}let x=i.safeParse(y);if(!x.success)throw new v(x.error,e);f=x.data;}let l=await t.handler({input:f,c:d,services:u,errorHandler:r,logger:a});if(n&&c&&!(l instanceof Response)){let y=c.safeParse(l);if(!y.success)throw new S(y.error);return y.data}return l},h;if(o)try{h=await o({next:g,route:t,c:d,services:u,errorHandler:r,logger:a});}catch(f){let l=await m(f);if(l)return l;throw f}else try{h=await g();}catch(f){let l=await m(f);if(l)return l;throw f}return h instanceof Response?h:d.json(h,p)}}async function Ae(t,e,n){switch(e){case "json":{if(n==="get")return t.req.query();let o=await t.req.text();if(!o)return {};try{return JSON.parse(o)}catch(s){throw new Error(`Invalid JSON body: ${s instanceof Error?s.message:String(s)}`)}}case "query":return t.req.query();case "form":return await t.req.parseBody();case "param":return t.req.param();default:return {}}}var b=class{constructor(e){this.services=e;}};function H(t,e){return {...e,input:t.input,output:t.output,handler:({input:n,services:o})=>new t(o).execute(n)}}function Ee(t,e){let n=e?.services,o=e?.errorHandler,s=e?.logger;return {configs:t,defineRoute(r){return r},useCaseRoute(r,a){return H(r,a)},serverFor(r,a){let i=t[r];if(!i)throw new Error(`[ApiRegistry] unknown api "${r}". Registered: ${Object.keys(t).join(", ")}`);return new R({...i,api:r,routes:a,services:n,errorHandler:i.errorHandler??o,logger:i.logger??s})},toFunctions(r,a,i){let c={};for(let p of Object.keys(t)){let u={...i?.defaults??{},...i?.per?.[p]??{}},d=new R({...t[p],api:p,routes:r,services:n,errorHandler:t[p].errorHandler??o,logger:t[p].logger??s});c[p]=Object.keys(u).length?d.toFunction(a,u):d.toFunction(a);}return c}}}function G(t){return t||process.env.GOOGLE_CLOUD_PROJECT||process.env.GCLOUD_PROJECT||process.env.GCP_PROJECT||void 0}function M(t,e={}){if(!e.enabled||!t)return;let n=G(e.projectId);if(!n)return;let s=`jsonPayload.${e.field??"errorId"}="${t}"`,r=[`query=${encodeURIComponent(s)}`];return e.duration&&r.push(`duration=${encodeURIComponent(e.duration)}`),`https://console.cloud.google.com/logs/query;${r.join(";")}?project=${encodeURIComponent(n)}`}var D=class{constructor(e={}){this.options=e;}gcpLogsUrl(e){return M(e,this.options.gcpLogs)}async handle(e){let n=await this.mapError(e);return n?(this.logError(e,n),n):this.handleBuiltin(e)}mapError(e){return null}logError(e,n){}handleBuiltin(e){return E(e.c,e.error)}};var z=class t{info(e,n){this.write("INFO",this.payload(e,n));}warn(e,n){this.write("WARNING",this.payload(e,n));}debug(e,n){this.write("DEBUG",this.payload(e,n));}error(e,n){let o=t.errorId(e);return this.write("ERROR",{errorId:o,message:e instanceof Error?e.message:String(e),...e instanceof Error&&e.stack?{stack:e.stack}:{},...n!==void 0?{meta:n}:{}}),o}payload(e,n){return n!==void 0?{message:e,meta:n}:{message:e}}write(e,n){let o={severity:e,...n};e==="ERROR"?console.error(o):e==="WARNING"?console.warn(o):console.log(o);}static errorId(e){return e&&typeof e=="object"&&"errorId"in e&&typeof e.errorId=="string"?e.errorId:Math.random().toString(36).slice(2,12)}};function Oe(t){let{getAuth:e,allow:n,checkRevoked:o=false,contextKey:s="docsUser"}=t;return async(r,a)=>{let c=(r.req.header("authorization")??r.req.header("Authorization"))?.match(/^Bearer\s+(.+)$/i);if(!c)return r.json({error:"Unauthorized"},401,{"WWW-Authenticate":"Bearer"});let p;try{p=await e().verifyIdToken(c[1],o);}catch{return r.json({error:"Unauthorized"},401,{"WWW-Authenticate":"Bearer"})}if(n){let u=false;try{u=await n(p);}catch{u=false;}if(!u)return r.json({error:"Forbidden"},403)}return r.set(s,p),a()}}function we(t){let{username:e,password:n,realm:o="Docs"}=t,s=`Basic ${btoa(`${e}:${n}`)}`;return async(r,a)=>{let i=r.req.header("authorization")??r.req.header("Authorization")??"";return Ce(i,s)?a():r.text("Unauthorized",401,{"WWW-Authenticate":`Basic realm="${o}"`})}}function Ce(t,e){if(t.length!==e.length)return false;let n=0;for(let o=0;o<t.length;o++)n|=t.charCodeAt(o)^e.charCodeAt(o);return n===0}var K={skipSegments:["useCases","useCase","use-cases","use-case"],casing:"preserve"};function F(t,e=K){let n=new Set(e.skipSegments.map(s=>s.toLowerCase()));return "/"+t.split("/").filter(Boolean).filter(s=>!n.has(s.toLowerCase())).map(s=>e.casing==="kebab"?Pe(s):s).join("/")}function Pe(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function j(t,e,n){let o=N(t),s=N(e),r=0;for(;r<o.length&&r<s.length&&o[r]===s[r];)r++;let a=o.length-r,i=s.slice(r),p=(i[i.length-1]??"").replace(/\.[mc]?[tj]sx?$/i,""),u=n===""?p:`${p}${n}`;return i[i.length-1]=u,(a===0?"./":"../".repeat(a))+i.join("/")}function N(t){return t.replace(/\\/g,"/").replace(/\/+$/,"").split("/").filter((n,o)=>!(o===0&&n===""))}var W={routesFile:"routes.ts",excludeSegments:["node_modules","__generated__","tests","__tests__",".turbo","dist","build",".next"]};function De(t,e=W){let n=[];return V(t,t,e,n),n.sort((o,s)=>o.relPath.localeCompare(s.relPath)),n}function V(t,e,n,o){let s;try{s=readdirSync(e);}catch{return}for(let r of s){if(n.excludeSegments.includes(r))continue;let a=join(e,r),i;try{i=statSync(a);}catch{continue}if(i.isDirectory())V(t,a,n,o);else if(i.isFile()&&r===n.routesFile){let c=relative(t,a).split(sep).join("/"),p=c.replace(/\/?[^/]+$/,"");o.push({absPath:a,relPath:c,relDir:p});}}}var J="/**\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 Y(t,e){let n=dirname(e.outFile);mkdirSync(n,{recursive:true});let o=e.banner??J,s=(e.now??new Date).toISOString(),r=e.importExtension,a=[],i=[],c=[];t.forEach((u,d)=>{let m=j(n,u.absPath,r),g=F(u.relDir,e.derive);a.push(`import mod${d} from ${JSON.stringify(m)};`),i.push(` { __derivedPath: ${JSON.stringify(g)}, mod: mod${d} },`),c.push({source:u.relPath,url:g});});let p=`${o}// Generated at ${s} \u2014 ${t.length} route file${t.length===1?"":"s"}.
|
|
13
13
|
|
|
14
14
|
import type { AnyRouteDef, RouteModuleDefault } from "@lpdjs/firestore-repo-service/servers/hono";
|
|
15
15
|
|
|
@@ -26,5 +26,5 @@ export const routes: AnyRouteDef[] = __defs.flatMap(({ __derivedPath, mod }) =>
|
|
|
26
26
|
const list = Array.isArray(mod) ? mod : [mod];
|
|
27
27
|
return list.map((route) => ({ ...route, path: route.path ?? __derivedPath }));
|
|
28
28
|
});
|
|
29
|
-
`;return writeFileSync(e.outFile,p,"utf8"),{outFile:e.outFile,routeCount:t.length,derivedPaths:c}}function
|
|
29
|
+
`;return writeFileSync(e.outFile,p,"utf8"),{outFile:e.outFile,routeCount:t.length,derivedPaths:c}}function Le(t,e,n,o,s){let r=s(t),a=join(t,e);return Y(r,{outFile:a,derive:n,importExtension:o})}export{T as BadRequestError,D as BaseErrorHandler,z as BaseLogger,K as DEFAULT_DERIVE,J as DEFAULT_GENERATOR_BANNER,W as DEFAULT_SCANNER,R as HonoServer,S as OutputValidationError,b as UseCase,v as ValidationError,we as basicAuth,C as buildOpenApiDocument,Ee as createApiRegistry,I as createRequestContextMiddleware,fe as createServices,E as defaultErrorResponse,Q as defineRoutes,F as derivePath,Oe as firebaseBearerAuth,M as gcpLogsUrl,Le as generateFromRoot,Y as generateRoutesManifest,P as renderDocsHtml,G as resolveGcpProjectId,De as scanRoutes,j as toImportSpecifier,H as useCaseRoute,le as withRequestContext};//# sourceMappingURL=index.js.map
|
|
30
30
|
//# sourceMappingURL=index.js.map
|