@venizia/ignis-kernel 0.4.7-0 → 0.4.7-1
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/LICENSE.md +1 -4
- package/dist/esm/base/applications/cors.d.ts +12 -10
- package/dist/esm/base/applications/cors.d.ts.map +1 -1
- package/dist/esm/base/applications/cors.js +37 -35
- package/dist/esm/base/applications/cors.js.map +1 -1
- package/dist/esm/base/applications/rest.js +11 -11
- package/dist/esm/base/applications/rest.js.map +1 -1
- package/dist/esm/base/auth/authenticate/common/codecs.js +2 -2
- package/dist/esm/base/auth/authenticate/common/codecs.js.map +1 -1
- package/dist/esm/base/auth/authenticate/strategies/strategy-registry.d.ts +1 -1
- package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js +1 -1
- package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
- package/dist/esm/base/auth/authorize/providers/authorization.provider.js +7 -7
- package/dist/esm/base/auth/authorize/providers/authorization.provider.js.map +1 -1
- package/dist/esm/base/auth/authorize/providers/request-domain.d.ts +14 -11
- package/dist/esm/base/auth/authorize/providers/request-domain.d.ts.map +1 -1
- package/dist/esm/base/auth/authorize/providers/request-domain.js +42 -39
- package/dist/esm/base/auth/authorize/providers/request-domain.js.map +1 -1
- package/dist/esm/base/auth/base/abstract-auth-registry.js +2 -2
- package/dist/esm/base/auth/base/abstract-auth-registry.js.map +1 -1
- package/dist/esm/base/auth/models/requests/change-password.schema.js +3 -3
- package/dist/esm/base/auth/models/requests/change-password.schema.js.map +1 -1
- package/dist/esm/base/auth/models/requests/sign-in.schema.js +5 -5
- package/dist/esm/base/auth/models/requests/sign-in.schema.js.map +1 -1
- package/dist/esm/base/components/controller/rest/rest.component.js +2 -2
- package/dist/esm/base/components/controller/rest/rest.component.js.map +1 -1
- package/dist/esm/base/controllers/common/index.d.ts +0 -1
- package/dist/esm/base/controllers/common/index.d.ts.map +1 -1
- package/dist/esm/base/controllers/common/index.js +0 -1
- package/dist/esm/base/controllers/common/index.js.map +1 -1
- package/dist/esm/base/controllers/common/schema-builders.d.ts +0 -5
- package/dist/esm/base/controllers/common/schema-builders.d.ts.map +1 -1
- package/dist/esm/base/controllers/common/schema-builders.js +0 -14
- package/dist/esm/base/controllers/common/schema-builders.js.map +1 -1
- package/dist/esm/base/controllers/context.d.ts +7 -2
- package/dist/esm/base/controllers/context.d.ts.map +1 -1
- package/dist/esm/base/controllers/context.js +7 -4
- package/dist/esm/base/controllers/context.js.map +1 -1
- package/dist/esm/base/controllers/factory/controller.d.ts +33 -1
- package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
- package/dist/esm/base/controllers/factory/controller.js +90 -6
- package/dist/esm/base/controllers/factory/controller.js.map +1 -1
- package/dist/esm/base/controllers/factory/definition.d.ts +1 -8
- package/dist/esm/base/controllers/factory/definition.d.ts.map +1 -1
- package/dist/esm/base/controllers/factory/definition.js +17 -24
- package/dist/esm/base/controllers/factory/definition.js.map +1 -1
- package/dist/esm/base/controllers/factory/index.d.ts +0 -1
- package/dist/esm/base/controllers/factory/index.d.ts.map +1 -1
- package/dist/esm/base/controllers/factory/index.js +0 -1
- package/dist/esm/base/controllers/factory/index.js.map +1 -1
- package/dist/esm/base/controllers/rest/abstract.d.ts.map +1 -1
- package/dist/esm/base/controllers/rest/abstract.js +6 -6
- package/dist/esm/base/controllers/rest/abstract.js.map +1 -1
- package/dist/esm/base/controllers/rest/base.d.ts +0 -5
- package/dist/esm/base/controllers/rest/base.d.ts.map +1 -1
- package/dist/esm/base/controllers/rest/base.js +14 -14
- package/dist/esm/base/controllers/rest/base.js.map +1 -1
- package/dist/esm/base/datasources/abstract.js +2 -2
- package/dist/esm/base/datasources/abstract.js.map +1 -1
- package/dist/esm/base/events/event-bus.js +4 -4
- package/dist/esm/base/events/event-bus.js.map +1 -1
- package/dist/esm/base/metadata/injectable.d.ts +7 -4
- package/dist/esm/base/metadata/injectable.d.ts.map +1 -1
- package/dist/esm/base/metadata/injectable.js +26 -23
- package/dist/esm/base/metadata/injectable.js.map +1 -1
- package/dist/esm/base/metadata/model-metadata.d.ts +27 -13
- package/dist/esm/base/metadata/model-metadata.d.ts.map +1 -1
- package/dist/esm/base/metadata/model-metadata.js +56 -26
- package/dist/esm/base/metadata/model-metadata.js.map +1 -1
- package/dist/esm/base/metadata/persistents.d.ts.map +1 -1
- package/dist/esm/base/metadata/persistents.js +21 -13
- package/dist/esm/base/metadata/persistents.js.map +1 -1
- package/dist/esm/base/metadata/routes/controller.d.ts.map +1 -1
- package/dist/esm/base/metadata/routes/controller.js +5 -2
- package/dist/esm/base/metadata/routes/controller.js.map +1 -1
- package/dist/esm/base/middlewares/app-error/app-error.middleware.js +7 -7
- package/dist/esm/base/middlewares/app-error/app-error.middleware.js.map +1 -1
- package/dist/esm/base/middlewares/app-error/database.handler.d.ts +14 -12
- package/dist/esm/base/middlewares/app-error/database.handler.d.ts.map +1 -1
- package/dist/esm/base/middlewares/app-error/database.handler.js +37 -35
- package/dist/esm/base/middlewares/app-error/database.handler.js.map +1 -1
- package/dist/esm/base/middlewares/app-error/zod.handler.d.ts +28 -23
- package/dist/esm/base/middlewares/app-error/zod.handler.d.ts.map +1 -1
- package/dist/esm/base/middlewares/app-error/zod.handler.js +56 -53
- package/dist/esm/base/middlewares/app-error/zod.handler.js.map +1 -1
- package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.d.ts +6 -4
- package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.d.ts.map +1 -1
- package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.js +14 -12
- package/dist/esm/base/middlewares/emoji-favicon/emoji-favicon.middleware.js.map +1 -1
- package/dist/esm/base/middlewares/form-body/form-body.middleware.d.ts +15 -11
- package/dist/esm/base/middlewares/form-body/form-body.middleware.d.ts.map +1 -1
- package/dist/esm/base/middlewares/form-body/form-body.middleware.js +25 -21
- package/dist/esm/base/middlewares/form-body/form-body.middleware.js.map +1 -1
- package/dist/esm/base/models/common/schemas.d.ts +184 -105
- package/dist/esm/base/models/common/schemas.d.ts.map +1 -1
- package/dist/esm/base/models/common/schemas.js +105 -54
- package/dist/esm/base/models/common/schemas.js.map +1 -1
- package/dist/esm/base/models/common/utilities.d.ts +10 -5
- package/dist/esm/base/models/common/utilities.d.ts.map +1 -1
- package/dist/esm/base/models/common/utilities.js +22 -16
- package/dist/esm/base/models/common/utilities.js.map +1 -1
- package/dist/esm/base/repositories/common/types/results.d.ts +15 -7
- package/dist/esm/base/repositories/common/types/results.d.ts.map +1 -1
- package/dist/esm/base/repositories/common/types/results.js +16 -7
- package/dist/esm/base/repositories/common/types/results.js.map +1 -1
- package/dist/esm/base/repositories/core/abstract.d.ts.map +1 -1
- package/dist/esm/base/repositories/core/abstract.js +5 -3
- package/dist/esm/base/repositories/core/abstract.js.map +1 -1
- package/dist/esm/base/repositories/query-schemas/index.d.ts +1 -1
- package/dist/esm/base/repositories/query-schemas/index.d.ts.map +1 -1
- package/dist/esm/base/repositories/query-schemas/index.js +3 -3
- package/dist/esm/base/repositories/query-schemas/index.js.map +1 -1
- package/dist/esm/helpers/inversion/common/relation-builder.js.map +1 -1
- package/dist/esm/helpers/inversion/index.d.ts +1 -1
- package/dist/esm/helpers/inversion/index.d.ts.map +1 -1
- package/dist/esm/helpers/inversion/index.js +1 -1
- package/dist/esm/helpers/inversion/index.js.map +1 -1
- package/dist/esm/helpers/inversion/mixins/repository.mixin.d.ts.map +1 -1
- package/dist/esm/helpers/inversion/mixins/repository.mixin.js +5 -5
- package/dist/esm/helpers/inversion/mixins/repository.mixin.js.map +1 -1
- package/dist/esm/metadata.d.ts +1 -1
- package/dist/esm/metadata.d.ts.map +1 -1
- package/dist/esm/metadata.js +1 -1
- package/dist/esm/metadata.js.map +1 -1
- package/dist/esm/repository.d.ts +2 -2
- package/dist/esm/repository.d.ts.map +1 -1
- package/dist/esm/repository.js +2 -2
- package/dist/esm/repository.js.map +1 -1
- package/dist/esm/utilities/index.d.ts +1 -1
- package/dist/esm/utilities/index.d.ts.map +1 -1
- package/dist/esm/utilities/index.js +1 -1
- package/dist/esm/utilities/index.js.map +1 -1
- package/dist/esm/utilities/not-supported.utility.d.ts +11 -0
- package/dist/esm/utilities/not-supported.utility.d.ts.map +1 -0
- package/dist/esm/utilities/not-supported.utility.js +19 -0
- package/dist/esm/utilities/not-supported.utility.js.map +1 -0
- package/package.json +6 -7
- package/dist/esm/base/controllers/common/html-response.d.ts +0 -70
- package/dist/esm/base/controllers/common/html-response.d.ts.map +0 -1
- package/dist/esm/base/controllers/common/html-response.js +0 -30
- package/dist/esm/base/controllers/common/html-response.js.map +0 -1
- package/dist/esm/base/controllers/factory/authorize-guard.d.ts +0 -19
- package/dist/esm/base/controllers/factory/authorize-guard.d.ts.map +0 -1
- package/dist/esm/base/controllers/factory/authorize-guard.js +0 -56
- package/dist/esm/base/controllers/factory/authorize-guard.js.map +0 -1
- package/dist/esm/base/controllers/factory/helper.d.ts +0 -2
- package/dist/esm/base/controllers/factory/helper.d.ts.map +0 -1
- package/dist/esm/base/controllers/factory/helper.js +0 -2
- package/dist/esm/base/controllers/factory/helper.js.map +0 -1
- package/dist/esm/base/controllers/factory/repository-injection.d.ts +0 -14
- package/dist/esm/base/controllers/factory/repository-injection.d.ts.map +0 -1
- package/dist/esm/base/controllers/factory/repository-injection.js +0 -27
- package/dist/esm/base/controllers/factory/repository-injection.js.map +0 -1
- package/dist/esm/base/metadata/model-settings.d.ts +0 -11
- package/dist/esm/base/metadata/model-settings.d.ts.map +0 -1
- package/dist/esm/base/metadata/model-settings.js +0 -30
- package/dist/esm/base/metadata/model-settings.js.map +0 -1
- package/dist/esm/utilities/error.utility.d.ts +0 -8
- package/dist/esm/utilities/error.utility.d.ts.map +0 -1
- package/dist/esm/utilities/error.utility.js +0 -14
- package/dist/esm/utilities/error.utility.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/definition.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TAuthMode, TAuthStrategy } from '@/base/auth/authenticate/common/constants';\nimport type { IAuthorizationSpec } from '@/base/auth/authorize/common/types';\nimport type { TIdSchemaType } from '@/base/models/common';\nimport { idParamsSchema, jsonContent, jsonResponse } from '@/base/models/common';\nimport { CountSchema } from '@/base/repositories/common';\nimport { FilterQuerySchema, WhereSchema } from '@/base/repositories/query-schemas';\nimport type { TAnyObjectSchema } from '@/base/controllers/common/schema-builders';\nimport { z } from '@hono/zod-openapi';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { ICustomizableRoutes } from '../common';\nimport {\n commonResponseHeaders,\n defaultRequestHeaders,\n findResponseHeaders,\n RestPaths,\n trackableHeaders,\n} from '../common';\n\n/** Picks user-overridden response schema if present (and non-undefined), else the default. */\ntype TResolvedResponseSchema<C, D extends z.ZodType> = C extends {\n response: {\n schema: infer S extends z.ZodType;\n };\n}\n ? S\n : D;\n\n/**\n * Every method here is an unbound static, called from the exported aliases below without a\n * receiver - a method must call another via `RouteConfigResolver.other(...)`, never\n * `this.other(...)`, or `this` is `undefined` at the call site.\n */\nexport class RouteConfigResolver {\n /** Path params always reach the validator as strings, so a number-typed id must be coerced before `z.number()` sees it - `idParamsSchema` alone rejects `/accounts/7`. */\n private static idPathParamsSchema(opts: { idType: TIdSchemaType }) {\n const { idType } = opts;\n\n if (idType !== 'number') {\n return idParamsSchema({ idType });\n }\n\n return z.object({\n id: z.coerce.number().openapi({\n param: { name: 'id', in: 'path', description: 'The unique id of the resource' },\n examples: [1, 2, 3],\n }),\n });\n }\n\n /**\n * The default body of a write route: the entity schema without the keys the entity stamps, and on\n * an update without `id` - the path or `where` names the rows. Zod strips a left-out key a client\n * sends. With nothing to leave out the schema itself is the body, refinements and OpenAPI name kept.\n */\n private static toWriteBodySchema(opts: {\n schema: TAnyObjectSchema;\n route: keyof ICustomizableRoutes;\n serverStampedKeys: string[];\n }): TAnyObjectSchema {\n const { schema, route, serverStampedKeys } = opts;\n const droppedKeys = route === 'create' ? serverStampedKeys : [...serverStampedKeys, 'id'];\n // A `.transform()` pipe has no shape to read, so every key it might hold counts.\n const isObjectSchema = schema instanceof z.ZodObject;\n const omittedKeys = isObjectSchema\n ? droppedKeys.filter((key) => Object.hasOwn(schema.shape, key))\n : droppedKeys;\n\n if (omittedKeys.length === 0) {\n return schema;\n }\n\n if (!isObjectSchema || schema.def.checks?.length) {\n throw getError({\n message: `[defineControllerRouteConfigs] Cannot build the default ${route} body | keys to leave out: ${omittedKeys.join(', ')} | The schema is refined or transformed, so zod cannot remove them | Pass routes.${route}.request.body`,\n });\n }\n\n const mask: Record<string, true> = {};\n for (const key of omittedKeys) {\n mask[key] = true;\n }\n\n return schema.omit(mask);\n }\n\n /** Picks the caller's per-route `request.params` override, else the entity's id path-param schema. */\n private static resolveIdParams<\n C extends { request?: { params?: TAnyObjectSchema } } | undefined,\n >(opts: { config: C; idType: TIdSchemaType }) {\n const { config, idType } = opts;\n return config?.request?.params ?? RouteConfigResolver.idPathParamsSchema({ idType });\n }\n\n /** Creates conditional count response schema. */\n static conditionalCountResponse<T extends z.ZodType>(dataSchema: T) {\n return z.union([\n CountSchema.extend({ data: dataSchema }).openapi({\n description: 'Response with count (when x-request-count header is \"true\" or omitted)',\n }),\n dataSchema.openapi({\n description: 'Data only response (when x-request-count header is \"false\")',\n }),\n ]);\n }\n\n /** Resolves a route's response schema - user override or default. Holds the one cast every `resolve*Config` needs: generic `C` is only known by its wider structural constraint, so it cannot be proven at the value level to collapse to `TResolvedResponseSchema`. */\n private static resolveResponseSchema<\n C extends { response?: { schema?: z.ZodType } } | undefined,\n D extends z.ZodType,\n >(opts: { config: C; defaultSchema: D }): TResolvedResponseSchema<C, D> {\n const { config, defaultSchema } = opts;\n return (config?.response?.schema ?? defaultSchema) as TResolvedResponseSchema<C, D>;\n }\n\n static resolveCountConfig<C extends ICustomizableRoutes['count']>(opts: {\n config: C;\n isStrict: boolean;\n }) {\n const { config, isStrict } = opts;\n const defaultQuery = z\n .object({\n where: isStrict\n ? WhereSchema\n : z.optional(WhereSchema).openapi({ description: 'Filter conditions' }),\n })\n .openapi({ description: 'Count query params' });\n\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? trackableHeaders,\n },\n response: {\n description: 'Total count of matching records',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema: CountSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n static resolveFindConfig<\n C extends ICustomizableRoutes['find'],\n FindSchema extends TAnyObjectSchema,\n >(opts: { config: C; selectSchema: FindSchema }) {\n const { config, selectSchema } = opts;\n const defaultQuery = FilterQuerySchema;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(z.array(selectSchema));\n\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Array of matching records (with optional count)',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? findResponseHeaders,\n },\n };\n }\n\n static resolveFindByIdConfig<\n C extends ICustomizableRoutes['findById'],\n FindByIdSchema extends TAnyObjectSchema,\n >(opts: { idType: TIdSchemaType; config: C; selectSchema: FindByIdSchema }) {\n const { config, selectSchema, idType } = opts;\n const defaultQuery = FilterQuerySchema.openapi({\n description: 'Filter with fields, order, include (where ignored)',\n });\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n\n return {\n request: {\n params: RouteConfigResolver.resolveIdParams({ config, idType }),\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Single record matching ID or null',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n static resolveFindOneConfig<\n C extends ICustomizableRoutes['findOne'],\n FindOneSchema extends TAnyObjectSchema,\n >(opts: { config: C; selectSchema: FindOneSchema }) {\n const { config, selectSchema } = opts;\n const defaultQuery = FilterQuerySchema.openapi({\n description: 'Filter with where, fields, order, include',\n });\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'First matching record or null',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n /** `serverStampedKeys` - what the entity reports from `getServerStampedKeys()`; the default body leaves them out. */\n static resolveCreateConfig<\n C extends ICustomizableRoutes['create'],\n SelectSchema extends TAnyObjectSchema,\n CreateSchema extends TAnyObjectSchema,\n >(opts: {\n config: C;\n selectSchema: SelectSchema;\n createSchema: CreateSchema;\n serverStampedKeys?: string[];\n }) {\n const { config, selectSchema, createSchema, serverStampedKeys = [] } = opts;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n\n return {\n request: {\n body:\n config?.request?.body ??\n RouteConfigResolver.toWriteBodySchema({\n schema: createSchema,\n route: 'create',\n serverStampedKeys,\n }),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Created record with generated fields (id, createdAt, etc.)',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveUpdateByIdConfig<\n C extends ICustomizableRoutes['updateById'],\n SelectSchema extends TAnyObjectSchema,\n UpdateSchema extends TAnyObjectSchema,\n >(opts: {\n idType: TIdSchemaType;\n config: C;\n selectSchema: SelectSchema;\n updateSchema: UpdateSchema;\n serverStampedKeys: string[];\n }) {\n const { config, selectSchema, updateSchema, idType, serverStampedKeys } = opts;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n return {\n request: {\n params: RouteConfigResolver.resolveIdParams({ config, idType }),\n body:\n config?.request?.body ??\n RouteConfigResolver.toWriteBodySchema({\n schema: updateSchema,\n route: 'updateById',\n serverStampedKeys,\n }),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Updated record with all current fields',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveUpdateByConfig<\n C extends ICustomizableRoutes['updateBy'],\n SelectSchema extends TAnyObjectSchema,\n UpdateSchema extends TAnyObjectSchema,\n >(opts: {\n config: C;\n selectSchema: SelectSchema;\n updateSchema: UpdateSchema;\n serverStampedKeys: string[];\n }) {\n const { config, selectSchema, updateSchema, serverStampedKeys } = opts;\n const defaultQuery = z.object({ where: WhereSchema.optional() }).openapi({\n description:\n 'Where condition selecting the records to update - here or in the body, not both',\n });\n // Built only without a custom body: a custom body must not trip the entity schema's checks.\n const buildDefaultBody = () => {\n const writableSchema = RouteConfigResolver.toWriteBodySchema({\n schema: updateSchema,\n route: 'updateBy',\n serverStampedKeys,\n });\n // A model with a real `where` column keeps it: the body reserves the name only when it is\n // free, and the handler then simply finds no `where` there.\n return 'where' in writableSchema.shape\n ? writableSchema\n : writableSchema.extend({ where: WhereSchema.optional() });\n };\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(z.array(selectSchema));\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n body: config?.request?.body ?? buildDefaultBody(),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Array of updated records',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveDeleteByIdConfig<\n C extends ICustomizableRoutes['deleteById'],\n SelectSchema extends TAnyObjectSchema,\n >(opts: { idType: TIdSchemaType; config: C; selectSchema: SelectSchema }) {\n const { config, selectSchema, idType } = opts;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n return {\n request: {\n params: RouteConfigResolver.resolveIdParams({ config, idType }),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Deleted record data',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveDeleteByConfig<\n C extends ICustomizableRoutes['deleteBy'],\n SelectSchema extends TAnyObjectSchema,\n >(opts: { config: C; selectSchema: SelectSchema }) {\n const { config, selectSchema } = opts;\n const defaultQuery = z.object({ where: WhereSchema.optional() }).openapi({\n description:\n 'Where condition selecting the records to delete - here or in the body, not both',\n });\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(z.array(selectSchema));\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n // No DEFAULT body schema. Declaring one makes `@hono/zod-openapi` gate the media type, and a\n // client that sends `content-type: application/json` with no body then gets 400 where it used\n // to get 200. The handler reads the body itself; name one here to get the Swagger editor.\n body: config?.request?.body,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Array of deleted records',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n /**\n * Generates complete route configurations for a CRUD controller. `serverStampedKeys` - what the\n * entity reports from `getServerStampedKeys()`; the default write bodies leave them out.\n */\n static defineControllerRouteConfigs<\n Routes extends ICustomizableRoutes,\n SelectSchema extends TAnyObjectSchema,\n CreateSchema extends TAnyObjectSchema,\n UpdateSchema extends TAnyObjectSchema,\n >(opts: {\n isStrict: boolean;\n idType: TIdSchemaType;\n authenticate?: { strategies?: TAuthStrategy[]; mode?: TAuthMode };\n authorize?: IAuthorizationSpec | IAuthorizationSpec[];\n schema: { select: SelectSchema; create: CreateSchema; update: UpdateSchema };\n serverStampedKeys?: string[];\n routes?: Routes;\n }) {\n const {\n isStrict,\n idType,\n authenticate: controllerAuth = {},\n authorize: controllerAuthorize,\n schema: { select: selectSchema, create: createSchema, update: updateSchema },\n serverStampedKeys = [],\n routes,\n } = opts;\n const { strategies: defaultStrategies = [], mode: defaultMode } = controllerAuth;\n\n // `Routes` is caller-bound but otherwise unconstrained here, so `{}` cannot be proven to satisfy it structurally even though every field ICustomizableRoutes declares is optional.\n const routesConfig = (routes ?? {}) as Routes;\n\n type TAuthenticateConfig = { strategies?: TAuthStrategy[]; mode?: TAuthMode };\n\n /** Priority: endpoint authenticate > controller authenticate. */\n const resolveRouteAuth = (routeKey: keyof ICustomizableRoutes): TAuthenticateConfig => {\n const endpointConfig = routesConfig[routeKey];\n const authConfig = endpointConfig?.authenticate;\n\n if (authConfig == null) {\n return { strategies: defaultStrategies, mode: defaultMode };\n }\n\n if (authConfig.skip === true) {\n return { strategies: [] };\n }\n\n return {\n strategies: authConfig.strategies ?? defaultStrategies,\n mode: authConfig.mode ?? defaultMode,\n };\n };\n\n type TAuthorizeConfig = IAuthorizationSpec | IAuthorizationSpec[] | undefined;\n\n /** Priority: endpoint authenticate.skip > endpoint authorize.skip > endpoint authorize > controller authorize. */\n const resolveRouteAuthorize = (routeKey: keyof ICustomizableRoutes): TAuthorizeConfig => {\n const endpointConfig = routesConfig[routeKey];\n\n if (endpointConfig?.authenticate?.skip === true) {\n return undefined;\n }\n\n const authorize = endpointConfig?.authorize;\n\n if (authorize == null) {\n return controllerAuthorize;\n }\n\n if (Array.isArray(authorize)) {\n return authorize;\n }\n\n if ('skip' in authorize) {\n return undefined;\n }\n\n return authorize;\n };\n\n const count = RouteConfigResolver.resolveCountConfig({ config: routesConfig.count, isStrict });\n const find = RouteConfigResolver.resolveFindConfig({ config: routesConfig.find, selectSchema });\n const findById = RouteConfigResolver.resolveFindByIdConfig({\n config: routesConfig.findById,\n selectSchema,\n idType,\n });\n const findOne = RouteConfigResolver.resolveFindOneConfig({\n config: routesConfig.findOne,\n selectSchema,\n });\n const create = RouteConfigResolver.resolveCreateConfig({\n config: routesConfig.create,\n selectSchema,\n createSchema,\n serverStampedKeys,\n });\n const updateById = RouteConfigResolver.resolveUpdateByIdConfig({\n config: routesConfig.updateById,\n selectSchema,\n updateSchema,\n idType,\n serverStampedKeys,\n });\n const updateBy = RouteConfigResolver.resolveUpdateByConfig({\n config: routesConfig.updateBy,\n selectSchema,\n updateSchema,\n serverStampedKeys,\n });\n const deleteById = RouteConfigResolver.resolveDeleteByIdConfig({\n config: routesConfig.deleteById,\n selectSchema,\n idType,\n });\n const deleteBy = RouteConfigResolver.resolveDeleteByConfig({\n config: routesConfig.deleteBy,\n selectSchema,\n });\n\n const rs = {\n COUNT: {\n method: HTTP.Methods.GET,\n path: RestPaths.COUNT,\n description: 'Count records matching where condition',\n authenticate: resolveRouteAuth('count'),\n authorize: resolveRouteAuthorize('count'),\n request: count.request,\n responses: jsonResponse(count.response),\n },\n\n FIND: {\n method: HTTP.Methods.GET,\n path: RestPaths.ROOT,\n description: 'Find records with filter, pagination, sorting, and relations',\n authenticate: resolveRouteAuth('find'),\n authorize: resolveRouteAuthorize('find'),\n request: find.request,\n responses: jsonResponse(find.response),\n },\n\n FIND_BY_ID: {\n method: HTTP.Methods.GET,\n path: '/{id}',\n description: 'Find single record by ID',\n authenticate: resolveRouteAuth('findById'),\n authorize: resolveRouteAuthorize('findById'),\n request: findById.request,\n responses: jsonResponse(findById.response),\n },\n\n FIND_ONE: {\n method: HTTP.Methods.GET,\n path: RestPaths.FIND_ONE,\n description: 'Find first record matching filter',\n authenticate: resolveRouteAuth('findOne'),\n authorize: resolveRouteAuthorize('findOne'),\n request: findOne.request,\n responses: jsonResponse(findOne.response),\n },\n\n CREATE: {\n method: HTTP.Methods.POST,\n path: RestPaths.ROOT,\n description: 'Create new record',\n authenticate: resolveRouteAuth('create'),\n authorize: resolveRouteAuthorize('create'),\n request: {\n body: jsonContent({\n description: 'Record data (required fields must be provided)',\n schema: create.request.body,\n }),\n headers: create.request.headers,\n },\n responses: jsonResponse(create.response),\n },\n\n UPDATE_BY_ID: {\n method: HTTP.Methods.PATCH,\n path: '/{id}',\n description: 'Partial update record by ID',\n authenticate: resolveRouteAuth('updateById'),\n authorize: resolveRouteAuthorize('updateById'),\n request: {\n params: updateById.request.params,\n body: jsonContent({\n description: 'Partial data (only changed fields)',\n schema: updateById.request.body,\n }),\n headers: updateById.request.headers,\n },\n responses: jsonResponse(updateById.response),\n },\n\n UPDATE_BY: {\n method: HTTP.Methods.PATCH,\n path: RestPaths.ROOT,\n description: 'Bulk update records matching where condition',\n authenticate: resolveRouteAuth('updateBy'),\n authorize: resolveRouteAuthorize('updateBy'),\n request: {\n query: updateBy.request.query,\n body: jsonContent({\n description: 'Partial data to apply to all matches',\n schema: updateBy.request.body,\n }),\n headers: updateBy.request.headers,\n },\n responses: jsonResponse(updateBy.response),\n },\n\n DELETE_BY_ID: {\n method: HTTP.Methods.DELETE,\n path: '/{id}',\n description: 'Delete record by ID (irreversible)',\n authenticate: resolveRouteAuth('deleteById'),\n authorize: resolveRouteAuthorize('deleteById'),\n request: deleteById.request,\n responses: jsonResponse(deleteById.response),\n },\n\n DELETE_BY: {\n method: HTTP.Methods.DELETE,\n path: RestPaths.ROOT,\n description: 'Bulk delete records matching where condition (irreversible)',\n authenticate: resolveRouteAuth('deleteBy'),\n authorize: resolveRouteAuthorize('deleteBy'),\n request: {\n query: deleteBy.request.query,\n ...(deleteBy.request.body\n ? {\n body: jsonContent({\n description: 'Where condition, when it does not fit in the query',\n schema: deleteBy.request.body,\n required: false,\n }),\n }\n : {}),\n headers: deleteBy.request.headers,\n },\n responses: jsonResponse(deleteBy.response),\n },\n } as const;\n\n return rs;\n }\n}\n\nexport const conditionalCountResponse = RouteConfigResolver.conditionalCountResponse;\nexport const resolveCountConfig = RouteConfigResolver.resolveCountConfig;\nexport const resolveFindConfig = RouteConfigResolver.resolveFindConfig;\nexport const resolveFindByIdConfig = RouteConfigResolver.resolveFindByIdConfig;\nexport const resolveFindOneConfig = RouteConfigResolver.resolveFindOneConfig;\nexport const resolveCreateConfig = RouteConfigResolver.resolveCreateConfig;\nexport const defineControllerRouteConfigs = RouteConfigResolver.defineControllerRouteConfigs;\n"]}
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/definition.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAEnF,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,SAAS,EACT,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAWnB;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAC9B,mLAAmL;IAC3K,MAAM,CAAC,kBAAkB,CAAC,IAA+B;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAExB,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,OAAO,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,CAAC,CAAC,MAAM,CAAC;YACd,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,+BAA+B,EAAE;gBAC/E,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aACpB,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,iBAAiB,CAAC,IAIhC;QACC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;QAClD,MAAM,WAAW,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,iBAAiB,EAAE,IAAI,CAAC,CAAC;QAC1F,iFAAiF;QACjF,MAAM,cAAc,GAAG,MAAM,YAAY,CAAC,CAAC,SAAS,CAAC;QACrD,MAAM,WAAW,GAAG,cAAc;YAChC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/D,CAAC,CAAC,WAAW,CAAC;QAEhB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YACjD,MAAM,QAAQ,CAAC;gBACb,OAAO,EAAE,+EAA+E,KAAK,8BAA8B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,oFAAoF,KAAK,eAAe;aAC1P,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,GAAyB,EAAE,CAAC;QACtC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,sGAAsG;IAC9F,MAAM,CAAC,eAAe,CAE5B,IAA0C;QAC1C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAChC,OAAO,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,iDAAiD;IACjD,MAAM,CAAC,wBAAwB,CAAsB,UAAa;QAChE,OAAO,CAAC,CAAC,KAAK,CAAC;YACb,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC;gBAC/C,WAAW,EAAE,wEAAwE;aACtF,CAAC;YACF,UAAU,CAAC,OAAO,CAAC;gBACjB,WAAW,EAAE,6DAA6D;aAC3E,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAED,wQAAwQ;IAChQ,MAAM,CAAC,qBAAqB,CAGlC,IAAqC;QACrC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;QACvC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,aAAa,CAAkC,CAAC;IACtF,CAAC;IAED,MAAM,CAAC,kBAAkB,CAAyC,IAGjE;QACC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAClC,MAAM,YAAY,GAAG,CAAC;aACnB,MAAM,CAAC;YACN,KAAK,EAAE,QAAQ;gBACb,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;SAC1E,CAAC;aACD,OAAO,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAElD,OAAO;YACL,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY;gBAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,gBAAgB;aACtD;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,iCAAiC;gBAC9C,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;gBACzF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,iBAAiB,CAGtB,IAA6C;QAC7C,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QACtC,MAAM,YAAY,GAAG,iBAAiB,CAAC;QACvC,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAE1F,OAAO;YACL,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY;gBAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,iDAAiD;gBAC9D,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,mBAAmB;aAC1D;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,qBAAqB,CAG1B,IAAwE;QACxE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAC9C,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC;YAC7C,WAAW,EAAE,oDAAoD;SAClE,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC;QAEjF,OAAO;YACL,OAAO,EAAE;gBACP,MAAM,EAAE,mBAAmB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;gBAC/D,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY;gBAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,mCAAmC;gBAChD,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,oBAAoB,CAGzB,IAAgD;QAChD,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QACtC,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC;YAC7C,WAAW,EAAE,2CAA2C;SACzD,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC;QAEjF,OAAO;YACL,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY;gBAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,+BAA+B;gBAC5C,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAED,qHAAqH;IACrH,MAAM,CAAC,mBAAmB,CAIxB,IAKD;QACC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;QAC5E,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC;QAEjF,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EACF,MAAM,EAAE,OAAO,EAAE,IAAI;oBACrB,mBAAmB,CAAC,iBAAiB,CAAC;wBACpC,MAAM,EAAE,YAAY;wBACpB,KAAK,EAAE,QAAQ;wBACf,iBAAiB;qBAClB,CAAC;gBACJ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,4DAA4D;gBACzE,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAIpC,IAMD;QACC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;QAC/E,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC;QACjF,OAAO;YACL,OAAO,EAAE;gBACP,MAAM,EAAE,mBAAmB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;gBAC/D,IAAI,EACF,MAAM,EAAE,OAAO,EAAE,IAAI;oBACrB,mBAAmB,CAAC,iBAAiB,CAAC;wBACpC,MAAM,EAAE,YAAY;wBACpB,KAAK,EAAE,YAAY;wBACnB,iBAAiB;qBAClB,CAAC;gBACJ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,wCAAwC;gBACrD,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAIlC,IAKD;QACC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;QACvE,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC;YACvE,WAAW,EACT,iFAAiF;SACpF,CAAC,CAAC;QACH,4FAA4F;QAC5F,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC5B,MAAM,cAAc,GAAG,mBAAmB,CAAC,iBAAiB,CAAC;gBAC3D,MAAM,EAAE,YAAY;gBACpB,KAAK,EAAE,UAAU;gBACjB,iBAAiB;aAClB,CAAC,CAAC;YACH,0FAA0F;YAC1F,4DAA4D;YAC5D,OAAO,OAAO,IAAI,cAAc,CAAC,KAAK;gBACpC,CAAC,CAAC,cAAc;gBAChB,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC;QACF,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAC1F,OAAO;YACL,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY;gBAC7C,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,gBAAgB,EAAE;gBACjD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,0BAA0B;gBACvC,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAGpC,IAAsE;QACtE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAC9C,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC;QACjF,OAAO;YACL,OAAO,EAAE;gBACP,MAAM,EAAE,mBAAmB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;gBAC/D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,qBAAqB;gBAClC,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAGlC,IAA+C;QAC/C,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QACtC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC;YACvE,WAAW,EACT,iFAAiF;SACpF,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAC1F,OAAO;YACL,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY;gBAC7C,6FAA6F;gBAC7F,8FAA8F;gBAC9F,0FAA0F;gBAC1F,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI;gBAC3B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB;aAC3D;YACD,QAAQ,EAAE;gBACR,WAAW,EAAE,0BAA0B;gBACvC,MAAM,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;gBAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,qBAAqB;aAC5D;SACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,4BAA4B,CAKjC,IAQD;QACC,MAAM,EACJ,QAAQ,EACR,MAAM,EACN,YAAY,EAAE,cAAc,GAAG,EAAE,EACjC,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,EAC5E,iBAAiB,GAAG,EAAE,EACtB,MAAM,GACP,GAAG,IAAI,CAAC;QACT,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC;QAEjF,mLAAmL;QACnL,MAAM,YAAY,GAAG,CAAC,MAAM,IAAI,EAAE,CAAW,CAAC;QAI9C,iEAAiE;QACjE,MAAM,gBAAgB,GAAG,CAAC,QAAmC,EAAuB,EAAE;YACpF,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,cAAc,EAAE,YAAY,CAAC;YAEhD,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;gBACvB,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;YAC9D,CAAC;YAED,IAAI,UAAU,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC7B,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAC5B,CAAC;YAED,OAAO;gBACL,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,iBAAiB;gBACtD,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,WAAW;aACrC,CAAC;QACJ,CAAC,CAAC;QAIF,kHAAkH;QAClH,MAAM,qBAAqB,GAAG,CAAC,QAAmC,EAAoB,EAAE;YACtF,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YAE9C,IAAI,cAAc,EAAE,YAAY,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChD,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,MAAM,SAAS,GAAG,cAAc,EAAE,SAAS,CAAC;YAE5C,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;gBACtB,OAAO,mBAAmB,CAAC;YAC7B,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7B,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,MAAM,KAAK,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/F,MAAM,IAAI,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QAChG,MAAM,QAAQ,GAAG,mBAAmB,CAAC,qBAAqB,CAAC;YACzD,MAAM,EAAE,YAAY,CAAC,QAAQ;YAC7B,YAAY;YACZ,MAAM;SACP,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,mBAAmB,CAAC,oBAAoB,CAAC;YACvD,MAAM,EAAE,YAAY,CAAC,OAAO;YAC5B,YAAY;SACb,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,mBAAmB,CAAC;YACrD,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,YAAY;YACZ,YAAY;YACZ,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,mBAAmB,CAAC,uBAAuB,CAAC;YAC7D,MAAM,EAAE,YAAY,CAAC,UAAU;YAC/B,YAAY;YACZ,YAAY;YACZ,MAAM;YACN,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,qBAAqB,CAAC;YACzD,MAAM,EAAE,YAAY,CAAC,QAAQ;YAC7B,YAAY;YACZ,YAAY;YACZ,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,mBAAmB,CAAC,uBAAuB,CAAC;YAC7D,MAAM,EAAE,YAAY,CAAC,UAAU;YAC/B,YAAY;YACZ,MAAM;SACP,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,qBAAqB,CAAC;YACzD,MAAM,EAAE,YAAY,CAAC,QAAQ;YAC7B,YAAY;SACb,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG;YACT,KAAK,EAAE;gBACL,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;gBACxB,IAAI,EAAE,SAAS,CAAC,KAAK;gBACrB,WAAW,EAAE,wCAAwC;gBACrD,YAAY,EAAE,gBAAgB,CAAC,OAAO,CAAC;gBACvC,SAAS,EAAE,qBAAqB,CAAC,OAAO,CAAC;gBACzC,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;aACzD;YAED,IAAI,EAAE;gBACJ,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;gBACxB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,WAAW,EAAE,8DAA8D;gBAC3E,YAAY,EAAE,gBAAgB,CAAC,MAAM,CAAC;gBACtC,SAAS,EAAE,qBAAqB,CAAC,MAAM,CAAC;gBACxC,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;aACxD;YAED,UAAU,EAAE;gBACV,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;gBACxB,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,0BAA0B;gBACvC,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC;gBAC1C,SAAS,EAAE,qBAAqB,CAAC,UAAU,CAAC;gBAC5C,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;aAC5D;YAED,QAAQ,EAAE;gBACR,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;gBACxB,IAAI,EAAE,SAAS,CAAC,QAAQ;gBACxB,WAAW,EAAE,mCAAmC;gBAChD,YAAY,EAAE,gBAAgB,CAAC,SAAS,CAAC;gBACzC,SAAS,EAAE,qBAAqB,CAAC,SAAS,CAAC;gBAC3C,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC;aAC3D;YAED,MAAM,EAAE;gBACN,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;gBACzB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,WAAW,EAAE,mBAAmB;gBAChC,YAAY,EAAE,gBAAgB,CAAC,QAAQ,CAAC;gBACxC,SAAS,EAAE,qBAAqB,CAAC,QAAQ,CAAC;gBAC1C,OAAO,EAAE;oBACP,IAAI,EAAE,gBAAgB,CAAC,WAAW,CAAC;wBACjC,WAAW,EAAE,gDAAgD;wBAC7D,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;qBAC5B,CAAC;oBACF,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;iBAChC;gBACD,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC;aAC1D;YAED,YAAY,EAAE;gBACZ,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;gBAC1B,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,6BAA6B;gBAC1C,YAAY,EAAE,gBAAgB,CAAC,YAAY,CAAC;gBAC5C,SAAS,EAAE,qBAAqB,CAAC,YAAY,CAAC;gBAC9C,OAAO,EAAE;oBACP,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM;oBACjC,IAAI,EAAE,gBAAgB,CAAC,WAAW,CAAC;wBACjC,WAAW,EAAE,oCAAoC;wBACjD,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI;qBAChC,CAAC;oBACF,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,OAAO;iBACpC;gBACD,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;aAC9D;YAED,SAAS,EAAE;gBACT,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;gBAC1B,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,WAAW,EAAE,8CAA8C;gBAC3D,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC;gBAC1C,SAAS,EAAE,qBAAqB,CAAC,UAAU,CAAC;gBAC5C,OAAO,EAAE;oBACP,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK;oBAC7B,IAAI,EAAE,gBAAgB,CAAC,WAAW,CAAC;wBACjC,WAAW,EAAE,sCAAsC;wBACnD,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI;qBAC9B,CAAC;oBACF,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO;iBAClC;gBACD,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;aAC5D;YAED,YAAY,EAAE;gBACZ,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;gBAC3B,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,oCAAoC;gBACjD,YAAY,EAAE,gBAAgB,CAAC,YAAY,CAAC;gBAC5C,SAAS,EAAE,qBAAqB,CAAC,YAAY,CAAC;gBAC9C,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;aAC9D;YAED,SAAS,EAAE;gBACT,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;gBAC3B,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,WAAW,EAAE,6DAA6D;gBAC1E,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC;gBAC1C,SAAS,EAAE,qBAAqB,CAAC,UAAU,CAAC;gBAC5C,OAAO,EAAE;oBACP,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK;oBAC7B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI;wBACvB,CAAC,CAAC;4BACE,IAAI,EAAE,gBAAgB,CAAC,WAAW,CAAC;gCACjC,WAAW,EAAE,oDAAoD;gCACjE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI;gCAC7B,QAAQ,EAAE,KAAK;6BAChB,CAAC;yBACH;wBACH,CAAC,CAAC,EAAE,CAAC;oBACP,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO;iBAClC;gBACD,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;aAC5D;SACO,CAAC;QAEX,OAAO,EAAE,CAAC;IACZ,CAAC;CACF","sourcesContent":["import type { TAuthMode, TAuthStrategy } from '@/base/auth/authenticate/common/constants';\nimport type { IAuthorizationSpec } from '@/base/auth/authorize/common/types';\nimport type { TIdSchemaType } from '@/base/models/common';\nimport { OpenApiResponses, OpenApiSchemas } from '@/base/models/common';\nimport { CountSchema } from '@/base/repositories/common';\nimport { FilterQuerySchema, WhereSchema } from '@/base/repositories/query-schemas';\nimport type { TAnyObjectSchema } from '@/base/controllers/common/schema-builders';\nimport { z } from '@hono/zod-openapi';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { ICustomizableRoutes } from '../common';\nimport {\n commonResponseHeaders,\n defaultRequestHeaders,\n findResponseHeaders,\n RestPaths,\n trackableHeaders,\n} from '../common';\n\n/** Picks user-overridden response schema if present (and non-undefined), else the default. */\ntype TResolvedResponseSchema<C, D extends z.ZodType> = C extends {\n response: {\n schema: infer S extends z.ZodType;\n };\n}\n ? S\n : D;\n\n/**\n * Every method here is an unbound static, called from the exported aliases below without a\n * receiver - a method must call another via `RouteConfigResolver.other(...)`, never\n * `this.other(...)`, or `this` is `undefined` at the call site.\n */\nexport class RouteConfigResolver {\n /** Path params always reach the validator as strings, so a number-typed id must be coerced before `z.number()` sees it - `OpenApiSchemas.idParams` alone rejects `/accounts/7`. */\n private static idPathParamsSchema(opts: { idType: TIdSchemaType }) {\n const { idType } = opts;\n\n if (idType !== 'number') {\n return OpenApiSchemas.idParams({ idType });\n }\n\n return z.object({\n id: z.coerce.number().openapi({\n param: { name: 'id', in: 'path', description: 'The unique id of the resource' },\n examples: [1, 2, 3],\n }),\n });\n }\n\n /**\n * The default body of a write route: the entity schema without the keys the entity stamps, and on\n * an update without `id` - the path or `where` names the rows. Zod strips a left-out key a client\n * sends. With nothing to leave out the schema itself is the body, refinements and OpenAPI name kept.\n */\n private static toWriteBodySchema(opts: {\n schema: TAnyObjectSchema;\n route: keyof ICustomizableRoutes;\n serverStampedKeys: string[];\n }): TAnyObjectSchema {\n const { schema, route, serverStampedKeys } = opts;\n const droppedKeys = route === 'create' ? serverStampedKeys : [...serverStampedKeys, 'id'];\n // A `.transform()` pipe has no shape to read, so every key it might hold counts.\n const isObjectSchema = schema instanceof z.ZodObject;\n const omittedKeys = isObjectSchema\n ? droppedKeys.filter((key) => Object.hasOwn(schema.shape, key))\n : droppedKeys;\n\n if (omittedKeys.length === 0) {\n return schema;\n }\n\n if (!isObjectSchema || schema.def.checks?.length) {\n throw getError({\n message: `[RouteConfigResolver.defineControllerRouteConfigs] Cannot build the default ${route} body | keys to leave out: ${omittedKeys.join(', ')} | The schema is refined or transformed, so zod cannot remove them | Pass routes.${route}.request.body`,\n });\n }\n\n const mask: Record<string, true> = {};\n for (const key of omittedKeys) {\n mask[key] = true;\n }\n\n return schema.omit(mask);\n }\n\n /** Picks the caller's per-route `request.params` override, else the entity's id path-param schema. */\n private static resolveIdParams<\n C extends { request?: { params?: TAnyObjectSchema } } | undefined,\n >(opts: { config: C; idType: TIdSchemaType }) {\n const { config, idType } = opts;\n return config?.request?.params ?? RouteConfigResolver.idPathParamsSchema({ idType });\n }\n\n /** Creates conditional count response schema. */\n static conditionalCountResponse<T extends z.ZodType>(dataSchema: T) {\n return z.union([\n CountSchema.extend({ data: dataSchema }).openapi({\n description: 'Response with count (when x-request-count header is \"true\" or omitted)',\n }),\n dataSchema.openapi({\n description: 'Data only response (when x-request-count header is \"false\")',\n }),\n ]);\n }\n\n /** Resolves a route's response schema - user override or default. Holds the one cast every `resolve*Config` needs: generic `C` is only known by its wider structural constraint, so it cannot be proven at the value level to collapse to `TResolvedResponseSchema`. */\n private static resolveResponseSchema<\n C extends { response?: { schema?: z.ZodType } } | undefined,\n D extends z.ZodType,\n >(opts: { config: C; defaultSchema: D }): TResolvedResponseSchema<C, D> {\n const { config, defaultSchema } = opts;\n return (config?.response?.schema ?? defaultSchema) as TResolvedResponseSchema<C, D>;\n }\n\n static resolveCountConfig<C extends ICustomizableRoutes['count']>(opts: {\n config: C;\n isStrict: boolean;\n }) {\n const { config, isStrict } = opts;\n const defaultQuery = z\n .object({\n where: isStrict\n ? WhereSchema\n : z.optional(WhereSchema).openapi({ description: 'Filter conditions' }),\n })\n .openapi({ description: 'Count query params' });\n\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? trackableHeaders,\n },\n response: {\n description: 'Total count of matching records',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema: CountSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n static resolveFindConfig<\n C extends ICustomizableRoutes['find'],\n FindSchema extends TAnyObjectSchema,\n >(opts: { config: C; selectSchema: FindSchema }) {\n const { config, selectSchema } = opts;\n const defaultQuery = FilterQuerySchema;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(z.array(selectSchema));\n\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Array of matching records (with optional count)',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? findResponseHeaders,\n },\n };\n }\n\n static resolveFindByIdConfig<\n C extends ICustomizableRoutes['findById'],\n FindByIdSchema extends TAnyObjectSchema,\n >(opts: { idType: TIdSchemaType; config: C; selectSchema: FindByIdSchema }) {\n const { config, selectSchema, idType } = opts;\n const defaultQuery = FilterQuerySchema.openapi({\n description: 'Filter with fields, order, include (where ignored)',\n });\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n\n return {\n request: {\n params: RouteConfigResolver.resolveIdParams({ config, idType }),\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Single record matching ID or null',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n static resolveFindOneConfig<\n C extends ICustomizableRoutes['findOne'],\n FindOneSchema extends TAnyObjectSchema,\n >(opts: { config: C; selectSchema: FindOneSchema }) {\n const { config, selectSchema } = opts;\n const defaultQuery = FilterQuerySchema.openapi({\n description: 'Filter with where, fields, order, include',\n });\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'First matching record or null',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n /** `serverStampedKeys` - what the entity reports from `getServerStampedKeys()`; the default body leaves them out. */\n static resolveCreateConfig<\n C extends ICustomizableRoutes['create'],\n SelectSchema extends TAnyObjectSchema,\n CreateSchema extends TAnyObjectSchema,\n >(opts: {\n config: C;\n selectSchema: SelectSchema;\n createSchema: CreateSchema;\n serverStampedKeys?: string[];\n }) {\n const { config, selectSchema, createSchema, serverStampedKeys = [] } = opts;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n\n return {\n request: {\n body:\n config?.request?.body ??\n RouteConfigResolver.toWriteBodySchema({\n schema: createSchema,\n route: 'create',\n serverStampedKeys,\n }),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Created record with generated fields (id, createdAt, etc.)',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveUpdateByIdConfig<\n C extends ICustomizableRoutes['updateById'],\n SelectSchema extends TAnyObjectSchema,\n UpdateSchema extends TAnyObjectSchema,\n >(opts: {\n idType: TIdSchemaType;\n config: C;\n selectSchema: SelectSchema;\n updateSchema: UpdateSchema;\n serverStampedKeys: string[];\n }) {\n const { config, selectSchema, updateSchema, idType, serverStampedKeys } = opts;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n return {\n request: {\n params: RouteConfigResolver.resolveIdParams({ config, idType }),\n body:\n config?.request?.body ??\n RouteConfigResolver.toWriteBodySchema({\n schema: updateSchema,\n route: 'updateById',\n serverStampedKeys,\n }),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Updated record with all current fields',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveUpdateByConfig<\n C extends ICustomizableRoutes['updateBy'],\n SelectSchema extends TAnyObjectSchema,\n UpdateSchema extends TAnyObjectSchema,\n >(opts: {\n config: C;\n selectSchema: SelectSchema;\n updateSchema: UpdateSchema;\n serverStampedKeys: string[];\n }) {\n const { config, selectSchema, updateSchema, serverStampedKeys } = opts;\n const defaultQuery = z.object({ where: WhereSchema.optional() }).openapi({\n description:\n 'Where condition selecting the records to update - here or in the body, not both',\n });\n // Built only without a custom body: a custom body must not trip the entity schema's checks.\n const buildDefaultBody = () => {\n const writableSchema = RouteConfigResolver.toWriteBodySchema({\n schema: updateSchema,\n route: 'updateBy',\n serverStampedKeys,\n });\n // A model with a real `where` column keeps it: the body reserves the name only when it is\n // free, and the handler then simply finds no `where` there.\n return 'where' in writableSchema.shape\n ? writableSchema\n : writableSchema.extend({ where: WhereSchema.optional() });\n };\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(z.array(selectSchema));\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n body: config?.request?.body ?? buildDefaultBody(),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Array of updated records',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveDeleteByIdConfig<\n C extends ICustomizableRoutes['deleteById'],\n SelectSchema extends TAnyObjectSchema,\n >(opts: { idType: TIdSchemaType; config: C; selectSchema: SelectSchema }) {\n const { config, selectSchema, idType } = opts;\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(selectSchema);\n return {\n request: {\n params: RouteConfigResolver.resolveIdParams({ config, idType }),\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Deleted record data',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n private static resolveDeleteByConfig<\n C extends ICustomizableRoutes['deleteBy'],\n SelectSchema extends TAnyObjectSchema,\n >(opts: { config: C; selectSchema: SelectSchema }) {\n const { config, selectSchema } = opts;\n const defaultQuery = z.object({ where: WhereSchema.optional() }).openapi({\n description:\n 'Where condition selecting the records to delete - here or in the body, not both',\n });\n const defaultSchema = RouteConfigResolver.conditionalCountResponse(z.array(selectSchema));\n return {\n request: {\n query: config?.request?.query ?? defaultQuery,\n // No DEFAULT body schema. Declaring one makes `@hono/zod-openapi` gate the media type, and a\n // client that sends `content-type: application/json` with no body then gets 400 where it used\n // to get 200. The handler reads the body itself; name one here to get the Swagger editor.\n body: config?.request?.body,\n headers: config?.request?.headers ?? defaultRequestHeaders,\n },\n response: {\n description: 'Array of deleted records',\n schema: RouteConfigResolver.resolveResponseSchema({ config, defaultSchema }),\n headers: config?.response?.headers ?? commonResponseHeaders,\n },\n };\n }\n\n /**\n * Generates complete route configurations for a CRUD controller. `serverStampedKeys` - what the\n * entity reports from `getServerStampedKeys()`; the default write bodies leave them out.\n */\n static defineControllerRouteConfigs<\n Routes extends ICustomizableRoutes,\n SelectSchema extends TAnyObjectSchema,\n CreateSchema extends TAnyObjectSchema,\n UpdateSchema extends TAnyObjectSchema,\n >(opts: {\n isStrict: boolean;\n idType: TIdSchemaType;\n authenticate?: { strategies?: TAuthStrategy[]; mode?: TAuthMode };\n authorize?: IAuthorizationSpec | IAuthorizationSpec[];\n schema: { select: SelectSchema; create: CreateSchema; update: UpdateSchema };\n serverStampedKeys?: string[];\n routes?: Routes;\n }) {\n const {\n isStrict,\n idType,\n authenticate: controllerAuth = {},\n authorize: controllerAuthorize,\n schema: { select: selectSchema, create: createSchema, update: updateSchema },\n serverStampedKeys = [],\n routes,\n } = opts;\n const { strategies: defaultStrategies = [], mode: defaultMode } = controllerAuth;\n\n // `Routes` is caller-bound but otherwise unconstrained here, so `{}` cannot be proven to satisfy it structurally even though every field ICustomizableRoutes declares is optional.\n const routesConfig = (routes ?? {}) as Routes;\n\n type TAuthenticateConfig = { strategies?: TAuthStrategy[]; mode?: TAuthMode };\n\n /** Priority: endpoint authenticate > controller authenticate. */\n const resolveRouteAuth = (routeKey: keyof ICustomizableRoutes): TAuthenticateConfig => {\n const endpointConfig = routesConfig[routeKey];\n const authConfig = endpointConfig?.authenticate;\n\n if (authConfig == null) {\n return { strategies: defaultStrategies, mode: defaultMode };\n }\n\n if (authConfig.skip === true) {\n return { strategies: [] };\n }\n\n return {\n strategies: authConfig.strategies ?? defaultStrategies,\n mode: authConfig.mode ?? defaultMode,\n };\n };\n\n type TAuthorizeConfig = IAuthorizationSpec | IAuthorizationSpec[] | undefined;\n\n /** Priority: endpoint authenticate.skip > endpoint authorize.skip > endpoint authorize > controller authorize. */\n const resolveRouteAuthorize = (routeKey: keyof ICustomizableRoutes): TAuthorizeConfig => {\n const endpointConfig = routesConfig[routeKey];\n\n if (endpointConfig?.authenticate?.skip === true) {\n return undefined;\n }\n\n const authorize = endpointConfig?.authorize;\n\n if (authorize == null) {\n return controllerAuthorize;\n }\n\n if (Array.isArray(authorize)) {\n return authorize;\n }\n\n if ('skip' in authorize) {\n return undefined;\n }\n\n return authorize;\n };\n\n const count = RouteConfigResolver.resolveCountConfig({ config: routesConfig.count, isStrict });\n const find = RouteConfigResolver.resolveFindConfig({ config: routesConfig.find, selectSchema });\n const findById = RouteConfigResolver.resolveFindByIdConfig({\n config: routesConfig.findById,\n selectSchema,\n idType,\n });\n const findOne = RouteConfigResolver.resolveFindOneConfig({\n config: routesConfig.findOne,\n selectSchema,\n });\n const create = RouteConfigResolver.resolveCreateConfig({\n config: routesConfig.create,\n selectSchema,\n createSchema,\n serverStampedKeys,\n });\n const updateById = RouteConfigResolver.resolveUpdateByIdConfig({\n config: routesConfig.updateById,\n selectSchema,\n updateSchema,\n idType,\n serverStampedKeys,\n });\n const updateBy = RouteConfigResolver.resolveUpdateByConfig({\n config: routesConfig.updateBy,\n selectSchema,\n updateSchema,\n serverStampedKeys,\n });\n const deleteById = RouteConfigResolver.resolveDeleteByIdConfig({\n config: routesConfig.deleteById,\n selectSchema,\n idType,\n });\n const deleteBy = RouteConfigResolver.resolveDeleteByConfig({\n config: routesConfig.deleteBy,\n selectSchema,\n });\n\n const rs = {\n COUNT: {\n method: HTTP.Methods.GET,\n path: RestPaths.COUNT,\n description: 'Count records matching where condition',\n authenticate: resolveRouteAuth('count'),\n authorize: resolveRouteAuthorize('count'),\n request: count.request,\n responses: OpenApiResponses.jsonResponse(count.response),\n },\n\n FIND: {\n method: HTTP.Methods.GET,\n path: RestPaths.ROOT,\n description: 'Find records with filter, pagination, sorting, and relations',\n authenticate: resolveRouteAuth('find'),\n authorize: resolveRouteAuthorize('find'),\n request: find.request,\n responses: OpenApiResponses.jsonResponse(find.response),\n },\n\n FIND_BY_ID: {\n method: HTTP.Methods.GET,\n path: '/{id}',\n description: 'Find single record by ID',\n authenticate: resolveRouteAuth('findById'),\n authorize: resolveRouteAuthorize('findById'),\n request: findById.request,\n responses: OpenApiResponses.jsonResponse(findById.response),\n },\n\n FIND_ONE: {\n method: HTTP.Methods.GET,\n path: RestPaths.FIND_ONE,\n description: 'Find first record matching filter',\n authenticate: resolveRouteAuth('findOne'),\n authorize: resolveRouteAuthorize('findOne'),\n request: findOne.request,\n responses: OpenApiResponses.jsonResponse(findOne.response),\n },\n\n CREATE: {\n method: HTTP.Methods.POST,\n path: RestPaths.ROOT,\n description: 'Create new record',\n authenticate: resolveRouteAuth('create'),\n authorize: resolveRouteAuthorize('create'),\n request: {\n body: OpenApiResponses.jsonContent({\n description: 'Record data (required fields must be provided)',\n schema: create.request.body,\n }),\n headers: create.request.headers,\n },\n responses: OpenApiResponses.jsonResponse(create.response),\n },\n\n UPDATE_BY_ID: {\n method: HTTP.Methods.PATCH,\n path: '/{id}',\n description: 'Partial update record by ID',\n authenticate: resolveRouteAuth('updateById'),\n authorize: resolveRouteAuthorize('updateById'),\n request: {\n params: updateById.request.params,\n body: OpenApiResponses.jsonContent({\n description: 'Partial data (only changed fields)',\n schema: updateById.request.body,\n }),\n headers: updateById.request.headers,\n },\n responses: OpenApiResponses.jsonResponse(updateById.response),\n },\n\n UPDATE_BY: {\n method: HTTP.Methods.PATCH,\n path: RestPaths.ROOT,\n description: 'Bulk update records matching where condition',\n authenticate: resolveRouteAuth('updateBy'),\n authorize: resolveRouteAuthorize('updateBy'),\n request: {\n query: updateBy.request.query,\n body: OpenApiResponses.jsonContent({\n description: 'Partial data to apply to all matches',\n schema: updateBy.request.body,\n }),\n headers: updateBy.request.headers,\n },\n responses: OpenApiResponses.jsonResponse(updateBy.response),\n },\n\n DELETE_BY_ID: {\n method: HTTP.Methods.DELETE,\n path: '/{id}',\n description: 'Delete record by ID (irreversible)',\n authenticate: resolveRouteAuth('deleteById'),\n authorize: resolveRouteAuthorize('deleteById'),\n request: deleteById.request,\n responses: OpenApiResponses.jsonResponse(deleteById.response),\n },\n\n DELETE_BY: {\n method: HTTP.Methods.DELETE,\n path: RestPaths.ROOT,\n description: 'Bulk delete records matching where condition (irreversible)',\n authenticate: resolveRouteAuth('deleteBy'),\n authorize: resolveRouteAuthorize('deleteBy'),\n request: {\n query: deleteBy.request.query,\n ...(deleteBy.request.body\n ? {\n body: OpenApiResponses.jsonContent({\n description: 'Where condition, when it does not fit in the query',\n schema: deleteBy.request.body,\n required: false,\n }),\n }\n : {}),\n headers: deleteBy.request.headers,\n },\n responses: OpenApiResponses.jsonResponse(deleteBy.response),\n },\n } as const;\n\n return rs;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC","sourcesContent":["export * from './controller';\nexport * from './crud';\nexport * from './definition';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/abstract.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAE5F,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAY,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACd,MAAM,iBAAiB,CAAC;AAOzB,kHAAkH;AAClH,8BAAsB,sBAAsB,CAC1C,QAAQ,SAAS,GAAG,GAAG,GAAG,EAC1B,WAAW,SAAS,MAAM,GAAG,EAAE,EAC/B,QAAQ,SAAS,MAAM,GAAG,GAAG,EAC7B,mBAAmB,SAAS,MAAM,GAAG,EAAE,EACvC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAEvF,SAAQ,UACR,YAAW,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IAE5E,YAAY,UAAS;IACrB,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;gBAEb,IAAI,EAAE,kBAAkB;IA2BpC,mEAAmE;IACnE,SAAS;IAIT,kJAAkJ;IAClJ,0BAA0B,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI;IAoCpE,0GAA0G;IACpG,SAAS,CACb,IAAI,CAAC,EAAE,mBAAmB,GACzB,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAqBxD,uFAAuF;IACvF,qBAAqB,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;;;;;;;IAkD1F,oFAAoF;IACpF,eAAe,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;;;IAcpF,4EAA4E;IAC5E,kBAAkB,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;;;
|
|
1
|
+
{"version":3,"file":"abstract.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/abstract.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAE5F,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAY,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACd,MAAM,iBAAiB,CAAC;AAOzB,kHAAkH;AAClH,8BAAsB,sBAAsB,CAC1C,QAAQ,SAAS,GAAG,GAAG,GAAG,EAC1B,WAAW,SAAS,MAAM,GAAG,EAAE,EAC/B,QAAQ,SAAS,MAAM,GAAG,GAAG,EAC7B,mBAAmB,SAAS,MAAM,GAAG,EAAE,EACvC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAEvF,SAAQ,UACR,YAAW,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IAE5E,YAAY,UAAS;IACrB,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;gBAEb,IAAI,EAAE,kBAAkB;IA2BpC,mEAAmE;IACnE,SAAS;IAIT,kJAAkJ;IAClJ,0BAA0B,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI;IAoCpE,0GAA0G;IACpG,SAAS,CACb,IAAI,CAAC,EAAE,mBAAmB,GACzB,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAqBxD,uFAAuF;IACvF,qBAAqB,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;;;;;;;IAkD1F,oFAAoF;IACpF,eAAe,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;;;IAcpF,4EAA4E;IAC5E,kBAAkB,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;;;IAkBvF,kEAAkE;IAClE,QAAQ,CAAC,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC;IAExC,uFAAuF;IACvF,QAAQ,CAAC,SAAS,CAAC,WAAW,SAAS,gBAAgB,EAAE,IAAI,EAAE;QAC7D,OAAO,EAAE,WAAW,CAAC;KACtB,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC;IAEnE,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,WAAW,SAAS,gBAAgB,EAAE,YAAY,GAAG,OAAO,EAAE,IAAI,EAAE;QACvF,OAAO,EAAE,WAAW,CAAC;QACrB,OAAO,EAAE,aAAa,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;KACzD,GAAG,mBAAmB,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC;CACtE"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AuthenticationModes } from '../../auth/authenticate/common/constants/index.js';
|
|
2
2
|
import { authenticate as authenticateFn } from '../../auth/authenticate/middlewares/authenticate.middleware.js';
|
|
3
3
|
import { authorize as authorizeFn } from '../../auth/authorize/middlewares/authorize.middleware.js';
|
|
4
|
-
import {
|
|
4
|
+
import { FormBodyMiddleware } from '../../middlewares/form-body/form-body.middleware.js';
|
|
5
5
|
import { AuthenticationStrategyRegistry } from '../../auth/authenticate/strategies/strategy-registry.js';
|
|
6
6
|
import { DroppedRouteDecorators } from '../../metadata/routes/common.js';
|
|
7
7
|
import { MetadataRegistry } from '../../../helpers/inversion/registry.js';
|
|
8
8
|
import { RoutePathScopes } from '../common/constants.js';
|
|
9
|
-
import {
|
|
9
|
+
import { OpenApiResponses } from '../../models/common/index.js';
|
|
10
10
|
import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
11
11
|
import { BaseHelper, getError } from '@venizia/ignis-helpers/core';
|
|
12
12
|
/** True for a route path carrying a path parameter, in either supported syntax: `/{id}` or `/:id`. */
|
|
@@ -92,7 +92,7 @@ export class AbstractRestController extends BaseHelper {
|
|
|
92
92
|
const { authenticate = {}, authorize, ...restConfig } = opts.configs;
|
|
93
93
|
const { strategies = [], mode = AuthenticationModes.ANY } = authenticate;
|
|
94
94
|
// Boot-time and NON-fatal: names a misspelled strategy at error level instead of leaving it as
|
|
95
|
-
// a 401 nobody can explain. Deliberately not a throw - `
|
|
95
|
+
// a 401 nobody can explain. Deliberately not a throw - `AuthControllerFactory.define` hard-codes `jwt`
|
|
96
96
|
// on four routes, and ANY mode tolerates a strategy that does not resolve, so failing here would
|
|
97
97
|
// stop applications booting that work today. `assertRegistered` is there for an application that
|
|
98
98
|
// does want the hard failure.
|
|
@@ -123,8 +123,8 @@ export class AbstractRestController extends BaseHelper {
|
|
|
123
123
|
mws.push(mw);
|
|
124
124
|
}
|
|
125
125
|
// Last: an application middleware and any size check run before the body is read.
|
|
126
|
-
if (hasFormBody({ content: restConfig.request?.body?.content })) {
|
|
127
|
-
mws.push(
|
|
126
|
+
if (FormBodyMiddleware.hasFormBody({ content: restConfig.request?.body?.content })) {
|
|
127
|
+
mws.push(FormBodyMiddleware.read);
|
|
128
128
|
}
|
|
129
129
|
return { restConfig, security, mws };
|
|
130
130
|
}
|
|
@@ -146,7 +146,7 @@ export class AbstractRestController extends BaseHelper {
|
|
|
146
146
|
// Same reassembled-vs-RouteConfig boundary as getRouteConfigs above.
|
|
147
147
|
return createRoute(Object.assign({}, restConfig, {
|
|
148
148
|
middleware: mws,
|
|
149
|
-
responses: Object.assign({}, htmlResponse({ description: 'HTML page' }), responses),
|
|
149
|
+
responses: Object.assign({}, OpenApiResponses.htmlResponse({ description: 'HTML page' }), responses),
|
|
150
150
|
tags: [...tags, this.scope],
|
|
151
151
|
security,
|
|
152
152
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/abstract.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthenticationModes } from '@/base/auth/authenticate/common/constants';\nimport { authenticate as authenticateFn } from '@/base/auth/authenticate/middlewares/authenticate.middleware';\nimport type { IAuthorizationSpec } from '@/base/auth/authorize/common/types';\nimport { authorize as authorizeFn } from '@/base/auth/authorize/middlewares/authorize.middleware';\nimport { formBodyReader, hasFormBody } from '@/base/middlewares/form-body/form-body.middleware';\nimport { AuthenticationStrategyRegistry } from '@/base/auth/authenticate/strategies/strategy-registry';\nimport { DroppedRouteDecorators } from '@/base/metadata/routes/common';\nimport { MetadataRegistry } from '@/helpers/inversion/registry';\nimport { RoutePathScopes, type TRoutePathScope } from '@/base/controllers/common/constants';\nimport { htmlResponse } from '@/base/controllers/common/html-response';\nimport type { Hook } from '@hono/zod-openapi';\nimport { createRoute, OpenAPIHono } from '@hono/zod-openapi';\nimport type { ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport type { Env, Schema } from 'hono';\nimport type {\n IAuthRouteConfig,\n IBindRouteOptions,\n IController,\n IControllerOptions,\n IDefineRouteOptions,\n TRouteHandler,\n} from '../common/types';\n\n/** True for a route path carrying a path parameter, in either supported syntax: `/{id}` or `/:id`. */\nconst hasPathParam = (opts: { path: string }): boolean => {\n return /\\{[^}]+\\}|:[^/]+/.test(opts.path);\n};\n\n/** Abstract base class for all REST controllers, providing route registration and auth middleware integration. */\nexport abstract class AbstractRestController<\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n Definitions extends Record<string, IAuthRouteConfig> = Record<string, IAuthRouteConfig>,\n>\n extends BaseHelper\n implements IController<RouteEnv, RouteSchema, BasePath, ConfigurableOptions>\n{\n isConfigured = false;\n router: OpenAPIHono<RouteEnv, RouteSchema, BasePath>;\n path: string;\n definitions: Definitions;\n\n constructor(opts: IControllerOptions) {\n super(opts);\n const { isStrict = true } = opts;\n\n const decoratorMetadata = MetadataRegistry.getInstance().getControllerMetadata({\n target: new.target,\n });\n const resolvedPath = decoratorMetadata?.path ?? opts.path;\n\n if (!resolvedPath) {\n throw getError({\n message: `[${new.target.name}] Controller path is required. Provide path via @controller decorator or constructor options.`,\n });\n }\n\n this.path = resolvedPath;\n\n this.router = new OpenAPIHono<RouteEnv, RouteSchema, BasePath>({\n strict: isStrict,\n defaultHook: (result, _context) => {\n if (!result.success) {\n throw result.error;\n }\n },\n });\n }\n\n /** Returns the OpenAPIHono router instance for this controller. */\n getRouter() {\n return this.router;\n }\n\n /** Registers decorator-defined routes from the metadata registry; `paths` selects them by shape - see the two-phase call in {@link configure}. */\n registerRoutesFromRegistry(opts?: { paths?: TRoutePathScope }): void {\n const { paths = RoutePathScopes.ALL } = opts ?? {};\n\n const logger = this.logger.for(this.registerRoutesFromRegistry.name);\n DroppedRouteDecorators.report({ logger });\n\n const routes = MetadataRegistry.getInstance().getRoutes({\n target: Object.getPrototypeOf(this),\n });\n\n if (!routes?.size) {\n return;\n }\n\n const routeDefs = routes.entries();\n for (const [methodName, routeConfigs] of routeDefs) {\n if (\n paths !== RoutePathScopes.ALL &&\n hasPathParam({ path: routeConfigs.path }) !== (paths === RoutePathScopes.PARAM)\n ) {\n continue;\n }\n\n // Dynamic dispatch by decorator-recorded method name - the controller class has no static index signature, so this read cannot be typed narrower than `unknown`.\n const handler = (this as Record<string | symbol, unknown>)[methodName];\n if (typeof handler !== 'function') {\n logger.warn('Route method \"%s\" not found on controller', String(methodName));\n continue;\n }\n\n this.bindRoute({ configs: routeConfigs }).to({\n handler: (handler as TRouteHandler<unknown, RouteEnv>).bind(this),\n });\n }\n }\n\n /** Configures the controller by binding all routes and registering decorator-based routes. Idempotent. */\n async configure(\n opts?: ConfigurableOptions,\n ): Promise<OpenAPIHono<RouteEnv, RouteSchema, BasePath>> {\n if (this.isConfigured) {\n return this.router;\n }\n\n const t = performance.now();\n const logger = this.logger.for(this.configure.name);\n\n const configureOptions = opts ?? {};\n logger.info('START | Binding controller | Options: %j', configureOptions);\n\n // Hono matches in registration order, so registration runs by SHAPE not source: every static path first, then binding()'s routes, then decorator param routes last (`/{id}` early would eat `/count`).\n this.registerRoutesFromRegistry({ paths: RoutePathScopes.STATIC });\n await this.binding();\n this.registerRoutesFromRegistry({ paths: RoutePathScopes.PARAM });\n\n this.isConfigured = true;\n logger.info('DONE | Binding controller | Took: %s (ms)', performance.now() - t);\n return this.router;\n }\n\n /** @internal Builds auth + custom middlewares and security specs from route config. */\n buildRouteMiddlewares<RouteConfig extends IAuthRouteConfig>(opts: { configs: RouteConfig }) {\n const { authenticate = {}, authorize, ...restConfig } = opts.configs;\n const { strategies = [], mode = AuthenticationModes.ANY } = authenticate;\n\n // Boot-time and NON-fatal: names a misspelled strategy at error level instead of leaving it as\n // a 401 nobody can explain. Deliberately not a throw - `defineAuthController` hard-codes `jwt`\n // on four routes, and ANY mode tolerates a strategy that does not resolve, so failing here would\n // stop applications booting that work today. `assertRegistered` is there for an application that\n // does want the hard failure.\n AuthenticationStrategyRegistry.getInstance().reportUnregistered({\n names: strategies,\n scope: this.constructor.name,\n });\n\n const security = strategies.map((strategy: string) => ({ [strategy]: [] }));\n const mws: ReturnType<typeof authenticateFn>[] = [];\n\n if (strategies.length > 0) {\n mws.push(authenticateFn({ strategies, mode }));\n }\n\n // Inject authorize middleware AFTER authenticate\n if (authorize) {\n const specs: IAuthorizationSpec[] = Array.isArray(authorize) ? authorize : [authorize];\n for (const spec of specs) {\n mws.push(authorizeFn({ spec }));\n }\n }\n\n const configuredMiddleware = restConfig.middleware;\n const extraMws = Array.isArray(configuredMiddleware)\n ? configuredMiddleware\n : [configuredMiddleware];\n\n for (const mw of extraMws) {\n if (!mw) {\n continue;\n }\n\n mws.push(mw);\n }\n\n // Last: an application middleware and any size check run before the body is read.\n if (hasFormBody({ content: restConfig.request?.body?.content })) {\n mws.push(formBodyReader);\n }\n\n return { restConfig, security, mws };\n }\n\n /** Processes route config, injecting auth middleware and OpenAPI security specs. */\n getRouteConfigs<RouteConfig extends IAuthRouteConfig>(opts: { configs: RouteConfig }) {\n const { restConfig, security, mws } = this.buildRouteMiddlewares(opts);\n const { tags = [] } = restConfig;\n\n // `restConfig` already omitted `authenticate`/`authorize` (this library's fields, not Hono's `createRoute` ones); reassembled with the injected middleware/tags/security it no longer structurally overlaps RouteConfig enough to assert directly.\n return createRoute<string, RouteConfig>(\n Object.assign({}, restConfig, {\n middleware: mws,\n tags: [...tags, this.scope],\n security,\n }) as any,\n );\n }\n\n /** Like getRouteConfigs but adds HTML response schema for JSX rendering. */\n getJSXRouteConfigs<RouteConfig extends IAuthRouteConfig>(opts: { configs: RouteConfig }) {\n const { restConfig, security, mws } = this.buildRouteMiddlewares(opts);\n const { responses, tags = [] } = restConfig;\n\n // Same reassembled-vs-RouteConfig boundary as getRouteConfigs above.\n return createRoute<string, RouteConfig>(\n Object.assign({}, restConfig, {\n middleware: mws,\n responses: Object.assign({}, htmlResponse({ description: 'HTML page' }), responses),\n tags: [...tags, this.scope],\n security,\n }) as any,\n );\n }\n /** Override to register routes using bindRoute or defineRoute. */\n abstract binding(): ValueOrPromise<void>;\n\n /** Creates a fluent binding for registering a route (call .to() to attach handler). */\n abstract bindRoute<RouteConfig extends IAuthRouteConfig>(opts: {\n configs: RouteConfig;\n }): IBindRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath>;\n\n /** Defines and registers a route with its handler in a single call. */\n abstract defineRoute<RouteConfig extends IAuthRouteConfig, ResponseType = unknown>(opts: {\n configs: RouteConfig;\n handler: TRouteHandler<ResponseType, RouteEnv>;\n hook?: Hook<any, RouteEnv, string, ValueOrPromise<any>>;\n }): IDefineRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/abstract.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthenticationModes } from '@/base/auth/authenticate/common/constants';\nimport { authenticate as authenticateFn } from '@/base/auth/authenticate/middlewares/authenticate.middleware';\nimport type { IAuthorizationSpec } from '@/base/auth/authorize/common/types';\nimport { authorize as authorizeFn } from '@/base/auth/authorize/middlewares/authorize.middleware';\nimport { FormBodyMiddleware } from '@/base/middlewares/form-body/form-body.middleware';\nimport { AuthenticationStrategyRegistry } from '@/base/auth/authenticate/strategies/strategy-registry';\nimport { DroppedRouteDecorators } from '@/base/metadata/routes/common';\nimport { MetadataRegistry } from '@/helpers/inversion/registry';\nimport { RoutePathScopes, type TRoutePathScope } from '@/base/controllers/common/constants';\nimport { OpenApiResponses } from '@/base/models/common';\nimport type { Hook } from '@hono/zod-openapi';\nimport { createRoute, OpenAPIHono } from '@hono/zod-openapi';\nimport type { ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport type { Env, Schema } from 'hono';\nimport type {\n IAuthRouteConfig,\n IBindRouteOptions,\n IController,\n IControllerOptions,\n IDefineRouteOptions,\n TRouteHandler,\n} from '../common/types';\n\n/** True for a route path carrying a path parameter, in either supported syntax: `/{id}` or `/:id`. */\nconst hasPathParam = (opts: { path: string }): boolean => {\n return /\\{[^}]+\\}|:[^/]+/.test(opts.path);\n};\n\n/** Abstract base class for all REST controllers, providing route registration and auth middleware integration. */\nexport abstract class AbstractRestController<\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n Definitions extends Record<string, IAuthRouteConfig> = Record<string, IAuthRouteConfig>,\n>\n extends BaseHelper\n implements IController<RouteEnv, RouteSchema, BasePath, ConfigurableOptions>\n{\n isConfigured = false;\n router: OpenAPIHono<RouteEnv, RouteSchema, BasePath>;\n path: string;\n definitions: Definitions;\n\n constructor(opts: IControllerOptions) {\n super(opts);\n const { isStrict = true } = opts;\n\n const decoratorMetadata = MetadataRegistry.getInstance().getControllerMetadata({\n target: new.target,\n });\n const resolvedPath = decoratorMetadata?.path ?? opts.path;\n\n if (!resolvedPath) {\n throw getError({\n message: `[${new.target.name}] Controller path is required. Provide path via @controller decorator or constructor options.`,\n });\n }\n\n this.path = resolvedPath;\n\n this.router = new OpenAPIHono<RouteEnv, RouteSchema, BasePath>({\n strict: isStrict,\n defaultHook: (result, _context) => {\n if (!result.success) {\n throw result.error;\n }\n },\n });\n }\n\n /** Returns the OpenAPIHono router instance for this controller. */\n getRouter() {\n return this.router;\n }\n\n /** Registers decorator-defined routes from the metadata registry; `paths` selects them by shape - see the two-phase call in {@link configure}. */\n registerRoutesFromRegistry(opts?: { paths?: TRoutePathScope }): void {\n const { paths = RoutePathScopes.ALL } = opts ?? {};\n\n const logger = this.logger.for(this.registerRoutesFromRegistry.name);\n DroppedRouteDecorators.report({ logger });\n\n const routes = MetadataRegistry.getInstance().getRoutes({\n target: Object.getPrototypeOf(this),\n });\n\n if (!routes?.size) {\n return;\n }\n\n const routeDefs = routes.entries();\n for (const [methodName, routeConfigs] of routeDefs) {\n if (\n paths !== RoutePathScopes.ALL &&\n hasPathParam({ path: routeConfigs.path }) !== (paths === RoutePathScopes.PARAM)\n ) {\n continue;\n }\n\n // Dynamic dispatch by decorator-recorded method name - the controller class has no static index signature, so this read cannot be typed narrower than `unknown`.\n const handler = (this as Record<string | symbol, unknown>)[methodName];\n if (typeof handler !== 'function') {\n logger.warn('Route method \"%s\" not found on controller', String(methodName));\n continue;\n }\n\n this.bindRoute({ configs: routeConfigs }).to({\n handler: (handler as TRouteHandler<unknown, RouteEnv>).bind(this),\n });\n }\n }\n\n /** Configures the controller by binding all routes and registering decorator-based routes. Idempotent. */\n async configure(\n opts?: ConfigurableOptions,\n ): Promise<OpenAPIHono<RouteEnv, RouteSchema, BasePath>> {\n if (this.isConfigured) {\n return this.router;\n }\n\n const t = performance.now();\n const logger = this.logger.for(this.configure.name);\n\n const configureOptions = opts ?? {};\n logger.info('START | Binding controller | Options: %j', configureOptions);\n\n // Hono matches in registration order, so registration runs by SHAPE not source: every static path first, then binding()'s routes, then decorator param routes last (`/{id}` early would eat `/count`).\n this.registerRoutesFromRegistry({ paths: RoutePathScopes.STATIC });\n await this.binding();\n this.registerRoutesFromRegistry({ paths: RoutePathScopes.PARAM });\n\n this.isConfigured = true;\n logger.info('DONE | Binding controller | Took: %s (ms)', performance.now() - t);\n return this.router;\n }\n\n /** @internal Builds auth + custom middlewares and security specs from route config. */\n buildRouteMiddlewares<RouteConfig extends IAuthRouteConfig>(opts: { configs: RouteConfig }) {\n const { authenticate = {}, authorize, ...restConfig } = opts.configs;\n const { strategies = [], mode = AuthenticationModes.ANY } = authenticate;\n\n // Boot-time and NON-fatal: names a misspelled strategy at error level instead of leaving it as\n // a 401 nobody can explain. Deliberately not a throw - `AuthControllerFactory.define` hard-codes `jwt`\n // on four routes, and ANY mode tolerates a strategy that does not resolve, so failing here would\n // stop applications booting that work today. `assertRegistered` is there for an application that\n // does want the hard failure.\n AuthenticationStrategyRegistry.getInstance().reportUnregistered({\n names: strategies,\n scope: this.constructor.name,\n });\n\n const security = strategies.map((strategy: string) => ({ [strategy]: [] }));\n const mws: ReturnType<typeof authenticateFn>[] = [];\n\n if (strategies.length > 0) {\n mws.push(authenticateFn({ strategies, mode }));\n }\n\n // Inject authorize middleware AFTER authenticate\n if (authorize) {\n const specs: IAuthorizationSpec[] = Array.isArray(authorize) ? authorize : [authorize];\n for (const spec of specs) {\n mws.push(authorizeFn({ spec }));\n }\n }\n\n const configuredMiddleware = restConfig.middleware;\n const extraMws = Array.isArray(configuredMiddleware)\n ? configuredMiddleware\n : [configuredMiddleware];\n\n for (const mw of extraMws) {\n if (!mw) {\n continue;\n }\n\n mws.push(mw);\n }\n\n // Last: an application middleware and any size check run before the body is read.\n if (FormBodyMiddleware.hasFormBody({ content: restConfig.request?.body?.content })) {\n mws.push(FormBodyMiddleware.read);\n }\n\n return { restConfig, security, mws };\n }\n\n /** Processes route config, injecting auth middleware and OpenAPI security specs. */\n getRouteConfigs<RouteConfig extends IAuthRouteConfig>(opts: { configs: RouteConfig }) {\n const { restConfig, security, mws } = this.buildRouteMiddlewares(opts);\n const { tags = [] } = restConfig;\n\n // `restConfig` already omitted `authenticate`/`authorize` (this library's fields, not Hono's `createRoute` ones); reassembled with the injected middleware/tags/security it no longer structurally overlaps RouteConfig enough to assert directly.\n return createRoute<string, RouteConfig>(\n Object.assign({}, restConfig, {\n middleware: mws,\n tags: [...tags, this.scope],\n security,\n }) as any,\n );\n }\n\n /** Like getRouteConfigs but adds HTML response schema for JSX rendering. */\n getJSXRouteConfigs<RouteConfig extends IAuthRouteConfig>(opts: { configs: RouteConfig }) {\n const { restConfig, security, mws } = this.buildRouteMiddlewares(opts);\n const { responses, tags = [] } = restConfig;\n\n // Same reassembled-vs-RouteConfig boundary as getRouteConfigs above.\n return createRoute<string, RouteConfig>(\n Object.assign({}, restConfig, {\n middleware: mws,\n responses: Object.assign(\n {},\n OpenApiResponses.htmlResponse({ description: 'HTML page' }),\n responses,\n ),\n tags: [...tags, this.scope],\n security,\n }) as any,\n );\n }\n /** Override to register routes using bindRoute or defineRoute. */\n abstract binding(): ValueOrPromise<void>;\n\n /** Creates a fluent binding for registering a route (call .to() to attach handler). */\n abstract bindRoute<RouteConfig extends IAuthRouteConfig>(opts: {\n configs: RouteConfig;\n }): IBindRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath>;\n\n /** Defines and registers a route with its handler in a single call. */\n abstract defineRoute<RouteConfig extends IAuthRouteConfig, ResponseType = unknown>(opts: {\n configs: RouteConfig;\n handler: TRouteHandler<ResponseType, RouteEnv>;\n hook?: Hook<any, RouteEnv, string, ValueOrPromise<any>>;\n }): IDefineRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath>;\n}\n"]}
|
|
@@ -6,11 +6,6 @@ import type { TResponseFormat } from '../common/constants.js';
|
|
|
6
6
|
import type { IAuthRouteConfig, IBindRouteOptions, IDefineRouteOptions, TRouteContext, TRouteHandler } from '../common/types/index.js';
|
|
7
7
|
import { AbstractRestController } from './abstract.js';
|
|
8
8
|
import type { IRequestedExtra, TResponseExtra } from './extras.js';
|
|
9
|
-
/** `Content-Range` of a page: inclusive `end`, and `records * /<total>` (no space) when the page is empty. Exported so a route that writes the header itself uses the one formatter. */
|
|
10
|
-
export declare const toContentRange: (opts: {
|
|
11
|
-
range: TDataRange;
|
|
12
|
-
count: number;
|
|
13
|
-
}) => string;
|
|
14
9
|
/** Recommended base class for REST controllers with concrete bindRoute and defineRoute implementations. */
|
|
15
10
|
export declare abstract class BaseRestController<RouteEnv extends Env = Env, RouteSchema extends Schema = {}, BasePath extends string = '/', ConfigurableOptions extends object = {}, Definitions extends Record<string, IAuthRouteConfig> = Record<string, IAuthRouteConfig>> extends AbstractRestController<RouteEnv, RouteSchema, BasePath, ConfigurableOptions, Definitions> {
|
|
16
11
|
/** Runs a handler task under performance measurement (fixed logger/level/description). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAGxF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAExC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,aAAa,EACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGhE,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataRangeUtility } from '../../repositories/common/types/index.js';
|
|
2
2
|
import { HTTP } from '@venizia/ignis-helpers/common';
|
|
3
|
-
import {
|
|
3
|
+
import { PerformanceUtility, ParseUtility } from '@venizia/ignis-helpers/core';
|
|
4
4
|
import { ResponseFormats } from '../common/constants.js';
|
|
5
5
|
import { AbstractRestController } from './abstract.js';
|
|
6
6
|
import { ResponseExtras } from './extras.js';
|
|
7
|
-
/** `Content-Range` of a page: inclusive `end`, and `records * /<total>` (no space) when the page is empty. Exported so a route that writes the header itself uses the one formatter. */
|
|
8
|
-
export const toContentRange = (opts) => {
|
|
9
|
-
const { range, count } = opts;
|
|
10
|
-
const { start, end, total } = range;
|
|
11
|
-
return count > 0 ? `records ${start}-${end}/${total}` : `records */${total}`;
|
|
12
|
-
};
|
|
13
7
|
/** Recommended base class for REST controllers with concrete bindRoute and defineRoute implementations. */
|
|
14
8
|
export class BaseRestController extends AbstractRestController {
|
|
15
9
|
/** Runs a handler task under performance measurement (fixed logger/level/description). */
|
|
16
10
|
measure(opts) {
|
|
17
|
-
return
|
|
11
|
+
return PerformanceUtility.executeWithMeasure({
|
|
18
12
|
logger: this.logger,
|
|
19
13
|
level: 'debug',
|
|
20
14
|
scope: opts.scope,
|
|
@@ -27,7 +21,7 @@ export class BaseRestController extends AbstractRestController {
|
|
|
27
21
|
normalizeCountData(opts) {
|
|
28
22
|
const { context, payload } = opts;
|
|
29
23
|
const requestCountData = context.req.header(HTTP.Headers.REQUEST_COUNT_DATA) ?? 'true';
|
|
30
|
-
const useCountData = toBoolean(requestCountData);
|
|
24
|
+
const useCountData = ParseUtility.toBoolean({ input: requestCountData });
|
|
31
25
|
context.header(HTTP.Headers.RESPONSE_COUNT_DATA, payload.count.toString());
|
|
32
26
|
if (useCountData) {
|
|
33
27
|
return payload;
|
|
@@ -41,7 +35,7 @@ export class BaseRestController extends AbstractRestController {
|
|
|
41
35
|
respond(opts) {
|
|
42
36
|
const { context, format, payload, range, extra } = opts;
|
|
43
37
|
if (range) {
|
|
44
|
-
context.header(HTTP.Headers.CONTENT_RANGE, toContentRange({ range, count: payload.count }));
|
|
38
|
+
context.header(HTTP.Headers.CONTENT_RANGE, DataRangeUtility.toContentRange({ range, count: payload.count }));
|
|
45
39
|
}
|
|
46
40
|
context.header(HTTP.Headers.RESPONSE_FORMAT, format);
|
|
47
41
|
if (!extra) {
|
|
@@ -64,7 +58,9 @@ export class BaseRestController extends AbstractRestController {
|
|
|
64
58
|
// `x-response-extra` marks it, so a client unwraps `{ data, extra }` only when the server says so.
|
|
65
59
|
context.header(HTTP.Headers.RESPONSE_COUNT_DATA, payload.count.toString());
|
|
66
60
|
context.header(HTTP.Headers.RESPONSE_EXTRA, Object.keys(computed).join(','));
|
|
67
|
-
const useCountData = toBoolean(
|
|
61
|
+
const useCountData = ParseUtility.toBoolean({
|
|
62
|
+
input: context.req.header(HTTP.Headers.REQUEST_COUNT_DATA) ?? 'true',
|
|
63
|
+
});
|
|
68
64
|
return useCountData
|
|
69
65
|
? { count: payload.count, data: payload.data, extra: computed }
|
|
70
66
|
: { data: payload.data, extra: computed };
|
|
@@ -74,8 +70,12 @@ export class BaseRestController extends AbstractRestController {
|
|
|
74
70
|
const { context, count } = opts;
|
|
75
71
|
const range = 'range' in opts
|
|
76
72
|
? opts.range
|
|
77
|
-
: buildDataRange({
|
|
78
|
-
|
|
73
|
+
: DataRangeUtility.buildDataRange({
|
|
74
|
+
offset: opts.offset,
|
|
75
|
+
dataLength: count,
|
|
76
|
+
total: opts.total,
|
|
77
|
+
});
|
|
78
|
+
context.header(HTTP.Headers.CONTENT_RANGE, DataRangeUtility.toContentRange({ range, count }));
|
|
79
79
|
context.header(HTTP.Headers.RESPONSE_COUNT_DATA, count.toString());
|
|
80
80
|
context.header(HTTP.Headers.RESPONSE_FORMAT, ResponseFormats.ARRAY);
|
|
81
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/base.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Hook, OpenAPIHono } from '@hono/zod-openapi';\nimport { buildDataRange } from '@/base/repositories/common/types';\nimport type { TDataRange } from '@/base/repositories/common/types';\nimport type { AnyType, TNullable, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport { executeWithPerformanceMeasure, toBoolean } from '@venizia/ignis-helpers/core';\nimport type { Env, Schema } from 'hono';\nimport { ResponseFormats } from '../common/constants';\nimport type { TResponseFormat } from '../common/constants';\nimport type {\n IAuthRouteConfig,\n IBindRouteOptions,\n IDefineRouteOptions,\n TRouteContext,\n TRouteHandler,\n} from '../common/types';\nimport { AbstractRestController } from './abstract';\nimport type { IRequestedExtra, TResponseExtra } from './extras';\nimport { ResponseExtras } from './extras';\n\n/** `Content-Range` of a page: inclusive `end`, and `records * /<total>` (no space) when the page is empty. Exported so a route that writes the header itself uses the one formatter. */\nexport const toContentRange = (opts: { range: TDataRange; count: number }): string => {\n const { range, count } = opts;\n const { start, end, total } = range;\n return count > 0 ? `records ${start}-${end}/${total}` : `records */${total}`;\n};\n\n/** Recommended base class for REST controllers with concrete bindRoute and defineRoute implementations. */\nexport abstract class BaseRestController<\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n Definitions extends Record<string, IAuthRouteConfig> = Record<string, IAuthRouteConfig>,\n> extends AbstractRestController<\n RouteEnv,\n RouteSchema,\n BasePath,\n ConfigurableOptions,\n Definitions\n> {\n /** Runs a handler task under performance measurement (fixed logger/level/description). */\n measure<R>(opts: { scope: string; args: unknown; task: () => Promise<R> }) {\n return executeWithPerformanceMeasure({\n logger: this.logger,\n level: 'debug',\n scope: opts.scope,\n description: `execute ${opts.scope}`,\n args: opts.args,\n task: opts.task,\n });\n }\n\n /** Returns the full `{ count, data }` envelope, or just `data` when the client sent `x-request-count: false`; `X-Response-Count` is set either way. */\n normalizeCountData<\n ResponseSchema extends AnyType,\n RequestContext extends TRouteContext<RouteEnv> = TRouteContext<RouteEnv>,\n ResponseData extends {\n count: number;\n data?: TNullable<ResponseSchema>;\n } = { count: number; data?: TNullable<ResponseSchema> },\n >(opts: { context: RequestContext; payload: ResponseData }) {\n const { context, payload } = opts;\n const requestCountData = context.req.header(HTTP.Headers.REQUEST_COUNT_DATA) ?? 'true';\n const useCountData = toBoolean(requestCountData);\n\n context.header(HTTP.Headers.RESPONSE_COUNT_DATA, payload.count.toString());\n\n if (useCountData) {\n return payload;\n }\n\n return payload.data;\n }\n\n /** `x-request-extra`, parsed: `name`, `-name` (a default switched off) and `name(key,key)`. */\n getRequestedExtras(opts: { context: TRouteContext<RouteEnv> }): Array<IRequestedExtra> {\n return ResponseExtras.parse({ header: opts.context.req.header(HTTP.Headers.REQUEST_EXTRA) });\n }\n\n /**\n * The one response call. Sets `X-Response-Format`, and with `range` (a list) also `Content-Range` -\n * `payload.count` is the rows of THIS response, never the total - then normalizes count/data per\n * the request-count header.\n *\n * `extra` offers figures beside the rows (see {@link TResponseExtra}): each runs when the client\n * names it in `x-request-extra`, or always when it is a default. When any runs, the body is\n * `{ data, extra }` (with `count` when it is requested); when none does, nothing is computed and the\n * body is what it would be without `extra`. A name the route does not offer is a 400 listing the\n * ones it does.\n */\n respond<R>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra?: never;\n }): R | { count: number; data?: TNullable<R> } | null | undefined;\n respond<R, Extra extends Record<string, TResponseExtra>>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra: Extra;\n }): Promise<\n | R\n | { count: number; data?: TNullable<R> }\n | {\n count?: number;\n data?: TNullable<R>;\n extra: Partial<Record<keyof Extra, unknown>>;\n }\n | null\n | undefined\n >;\n respond<R>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra?: Record<string, TResponseExtra>;\n }): ValueOrPromise<\n R | { count?: number; data?: TNullable<R>; extra?: Record<string, unknown> } | null | undefined\n >;\n respond<R>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra?: Record<string, TResponseExtra>;\n }) {\n const { context, format, payload, range, extra } = opts;\n\n if (range) {\n context.header(HTTP.Headers.CONTENT_RANGE, toContentRange({ range, count: payload.count }));\n }\n context.header(HTTP.Headers.RESPONSE_FORMAT, format);\n\n if (!extra) {\n return this.normalizeCountData<R>({ context, payload });\n }\n\n return this.respondWithExtra<R>({ context, payload, extra });\n }\n\n /** The `extra` half of `respond`: resolves what was asked against what is offered, runs it in parallel. */\n async respondWithExtra<R>(opts: {\n context: TRouteContext<RouteEnv>;\n payload: { count: number; data?: TNullable<R> };\n extra: Record<string, TResponseExtra>;\n }) {\n const { context, payload, extra } = opts;\n const plan = ResponseExtras.resolve({\n requested: this.getRequestedExtras({ context }),\n offered: extra,\n });\n\n if (plan.size === 0) {\n return this.normalizeCountData<R>({ context, payload });\n }\n\n const computed = await ResponseExtras.compute({ plan, offered: extra });\n\n // Rows still counted in the header; the body is an object, since an array cannot carry extras.\n // `x-response-extra` marks it, so a client unwraps `{ data, extra }` only when the server says so.\n context.header(HTTP.Headers.RESPONSE_COUNT_DATA, payload.count.toString());\n context.header(HTTP.Headers.RESPONSE_EXTRA, Object.keys(computed).join(','));\n const useCountData = toBoolean(context.req.header(HTTP.Headers.REQUEST_COUNT_DATA) ?? 'true');\n\n return useCountData\n ? { count: payload.count, data: payload.data, extra: computed }\n : { data: payload.data, extra: computed };\n }\n\n /** The list headers without the body, for a list whose body is not a `{ count, data }` envelope: `Content-Range`, `X-Response-Count` = rows in THIS response, `X-Response-Format: array`. Pass a `range`, or `offset` + `total` for an engine that reports those (a search page): the range is derived with the same inclusive-end rule. */\n setListHeaders(\n opts: { context: TRouteContext<RouteEnv>; count: number } & (\n | { range: TDataRange }\n | { offset: number; total: number }\n ),\n ) {\n const { context, count } = opts;\n const range =\n 'range' in opts\n ? opts.range\n : buildDataRange({ offset: opts.offset, dataLength: count, total: opts.total });\n\n context.header(HTTP.Headers.CONTENT_RANGE, toContentRange({ range, count }));\n context.header(HTTP.Headers.RESPONSE_COUNT_DATA, count.toString());\n context.header(HTTP.Headers.RESPONSE_FORMAT, ResponseFormats.ARRAY);\n }\n\n /** TRouteHandler's TRouteContext is a lightweight custom shape (different `json`/`req.valid` signatures) built on Hono's real Context, not a subtype of the RouteHandler `.openapi()` expects - genuinely different handler types bridged here. */\n toHonoHandler<ResponseType = unknown>(opts: { handler: TRouteHandler<ResponseType, RouteEnv> }) {\n return opts.handler as Parameters<OpenAPIHono<RouteEnv>['openapi']>[1];\n }\n\n /** Creates a fluent binding for registering a route (call .to() to attach handler). */\n bindRoute<RouteConfig extends IAuthRouteConfig>(opts: {\n configs: RouteConfig;\n }): IBindRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath> {\n const routeConfigs = this.getRouteConfigs<RouteConfig>({ configs: opts.configs });\n\n return {\n configs: routeConfigs,\n to: ({ handler }) => {\n return {\n configs: routeConfigs,\n route: this.router.openapi(routeConfigs, this.toHonoHandler({ handler })),\n };\n },\n };\n }\n\n /** Defines and registers a route with its handler in a single call. */\n defineRoute<RouteConfig extends IAuthRouteConfig, ResponseType = unknown>(opts: {\n configs: RouteConfig;\n handler: TRouteHandler<ResponseType, RouteEnv>;\n hook?: Hook<any, RouteEnv, string, ValueOrPromise<any>>;\n }): IDefineRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath> {\n const routeConfigs = this.getRouteConfigs<RouteConfig>({ configs: opts.configs });\n\n return {\n configs: routeConfigs,\n route: this.router.openapi(\n routeConfigs,\n this.toHonoHandler<ResponseType>({ handler: opts.handler }),\n opts.hook,\n ),\n };\n }\n\n /** Defines a JSX route that renders server-side HTML via c.html(). */\n defineJSXRoute<RouteConfig extends IAuthRouteConfig, ResponseType = unknown>(opts: {\n configs: RouteConfig;\n handler: TRouteHandler<ResponseType, RouteEnv>;\n hook?: Hook<any, RouteEnv, string, ValueOrPromise<any>>;\n }): IDefineRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath> {\n const routeConfigs = this.getJSXRouteConfigs<RouteConfig>({ configs: opts.configs });\n\n return {\n configs: routeConfigs,\n route: this.router.openapi(\n routeConfigs,\n this.toHonoHandler<ResponseType>({ handler: opts.handler }),\n opts.hook,\n ),\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/base.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Hook, OpenAPIHono } from '@hono/zod-openapi';\nimport { DataRangeUtility } from '@/base/repositories/common/types';\nimport type { TDataRange } from '@/base/repositories/common/types';\nimport type { AnyType, TNullable, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport { PerformanceUtility, ParseUtility } from '@venizia/ignis-helpers/core';\nimport type { Env, Schema } from 'hono';\nimport { ResponseFormats } from '../common/constants';\nimport type { TResponseFormat } from '../common/constants';\nimport type {\n IAuthRouteConfig,\n IBindRouteOptions,\n IDefineRouteOptions,\n TRouteContext,\n TRouteHandler,\n} from '../common/types';\nimport { AbstractRestController } from './abstract';\nimport type { IRequestedExtra, TResponseExtra } from './extras';\nimport { ResponseExtras } from './extras';\n\n/** Recommended base class for REST controllers with concrete bindRoute and defineRoute implementations. */\nexport abstract class BaseRestController<\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n Definitions extends Record<string, IAuthRouteConfig> = Record<string, IAuthRouteConfig>,\n> extends AbstractRestController<\n RouteEnv,\n RouteSchema,\n BasePath,\n ConfigurableOptions,\n Definitions\n> {\n /** Runs a handler task under performance measurement (fixed logger/level/description). */\n measure<R>(opts: { scope: string; args: unknown; task: () => Promise<R> }) {\n return PerformanceUtility.executeWithMeasure({\n logger: this.logger,\n level: 'debug',\n scope: opts.scope,\n description: `execute ${opts.scope}`,\n args: opts.args,\n task: opts.task,\n });\n }\n\n /** Returns the full `{ count, data }` envelope, or just `data` when the client sent `x-request-count: false`; `X-Response-Count` is set either way. */\n normalizeCountData<\n ResponseSchema extends AnyType,\n RequestContext extends TRouteContext<RouteEnv> = TRouteContext<RouteEnv>,\n ResponseData extends {\n count: number;\n data?: TNullable<ResponseSchema>;\n } = { count: number; data?: TNullable<ResponseSchema> },\n >(opts: { context: RequestContext; payload: ResponseData }) {\n const { context, payload } = opts;\n const requestCountData = context.req.header(HTTP.Headers.REQUEST_COUNT_DATA) ?? 'true';\n const useCountData = ParseUtility.toBoolean({ input: requestCountData });\n\n context.header(HTTP.Headers.RESPONSE_COUNT_DATA, payload.count.toString());\n\n if (useCountData) {\n return payload;\n }\n\n return payload.data;\n }\n\n /** `x-request-extra`, parsed: `name`, `-name` (a default switched off) and `name(key,key)`. */\n getRequestedExtras(opts: { context: TRouteContext<RouteEnv> }): Array<IRequestedExtra> {\n return ResponseExtras.parse({ header: opts.context.req.header(HTTP.Headers.REQUEST_EXTRA) });\n }\n\n /**\n * The one response call. Sets `X-Response-Format`, and with `range` (a list) also `Content-Range` -\n * `payload.count` is the rows of THIS response, never the total - then normalizes count/data per\n * the request-count header.\n *\n * `extra` offers figures beside the rows (see {@link TResponseExtra}): each runs when the client\n * names it in `x-request-extra`, or always when it is a default. When any runs, the body is\n * `{ data, extra }` (with `count` when it is requested); when none does, nothing is computed and the\n * body is what it would be without `extra`. A name the route does not offer is a 400 listing the\n * ones it does.\n */\n respond<R>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra?: never;\n }): R | { count: number; data?: TNullable<R> } | null | undefined;\n respond<R, Extra extends Record<string, TResponseExtra>>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra: Extra;\n }): Promise<\n | R\n | { count: number; data?: TNullable<R> }\n | {\n count?: number;\n data?: TNullable<R>;\n extra: Partial<Record<keyof Extra, unknown>>;\n }\n | null\n | undefined\n >;\n respond<R>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra?: Record<string, TResponseExtra>;\n }): ValueOrPromise<\n R | { count?: number; data?: TNullable<R>; extra?: Record<string, unknown> } | null | undefined\n >;\n respond<R>(opts: {\n context: TRouteContext<RouteEnv>;\n format: TResponseFormat;\n payload: { count: number; data?: TNullable<R> };\n range?: TDataRange;\n extra?: Record<string, TResponseExtra>;\n }) {\n const { context, format, payload, range, extra } = opts;\n\n if (range) {\n context.header(\n HTTP.Headers.CONTENT_RANGE,\n DataRangeUtility.toContentRange({ range, count: payload.count }),\n );\n }\n context.header(HTTP.Headers.RESPONSE_FORMAT, format);\n\n if (!extra) {\n return this.normalizeCountData<R>({ context, payload });\n }\n\n return this.respondWithExtra<R>({ context, payload, extra });\n }\n\n /** The `extra` half of `respond`: resolves what was asked against what is offered, runs it in parallel. */\n async respondWithExtra<R>(opts: {\n context: TRouteContext<RouteEnv>;\n payload: { count: number; data?: TNullable<R> };\n extra: Record<string, TResponseExtra>;\n }) {\n const { context, payload, extra } = opts;\n const plan = ResponseExtras.resolve({\n requested: this.getRequestedExtras({ context }),\n offered: extra,\n });\n\n if (plan.size === 0) {\n return this.normalizeCountData<R>({ context, payload });\n }\n\n const computed = await ResponseExtras.compute({ plan, offered: extra });\n\n // Rows still counted in the header; the body is an object, since an array cannot carry extras.\n // `x-response-extra` marks it, so a client unwraps `{ data, extra }` only when the server says so.\n context.header(HTTP.Headers.RESPONSE_COUNT_DATA, payload.count.toString());\n context.header(HTTP.Headers.RESPONSE_EXTRA, Object.keys(computed).join(','));\n const useCountData = ParseUtility.toBoolean({\n input: context.req.header(HTTP.Headers.REQUEST_COUNT_DATA) ?? 'true',\n });\n\n return useCountData\n ? { count: payload.count, data: payload.data, extra: computed }\n : { data: payload.data, extra: computed };\n }\n\n /** The list headers without the body, for a list whose body is not a `{ count, data }` envelope: `Content-Range`, `X-Response-Count` = rows in THIS response, `X-Response-Format: array`. Pass a `range`, or `offset` + `total` for an engine that reports those (a search page): the range is derived with the same inclusive-end rule. */\n setListHeaders(\n opts: { context: TRouteContext<RouteEnv>; count: number } & (\n | { range: TDataRange }\n | { offset: number; total: number }\n ),\n ) {\n const { context, count } = opts;\n const range =\n 'range' in opts\n ? opts.range\n : DataRangeUtility.buildDataRange({\n offset: opts.offset,\n dataLength: count,\n total: opts.total,\n });\n\n context.header(HTTP.Headers.CONTENT_RANGE, DataRangeUtility.toContentRange({ range, count }));\n context.header(HTTP.Headers.RESPONSE_COUNT_DATA, count.toString());\n context.header(HTTP.Headers.RESPONSE_FORMAT, ResponseFormats.ARRAY);\n }\n\n /** TRouteHandler's TRouteContext is a lightweight custom shape (different `json`/`req.valid` signatures) built on Hono's real Context, not a subtype of the RouteHandler `.openapi()` expects - genuinely different handler types bridged here. */\n toHonoHandler<ResponseType = unknown>(opts: { handler: TRouteHandler<ResponseType, RouteEnv> }) {\n return opts.handler as Parameters<OpenAPIHono<RouteEnv>['openapi']>[1];\n }\n\n /** Creates a fluent binding for registering a route (call .to() to attach handler). */\n bindRoute<RouteConfig extends IAuthRouteConfig>(opts: {\n configs: RouteConfig;\n }): IBindRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath> {\n const routeConfigs = this.getRouteConfigs<RouteConfig>({ configs: opts.configs });\n\n return {\n configs: routeConfigs,\n to: ({ handler }) => {\n return {\n configs: routeConfigs,\n route: this.router.openapi(routeConfigs, this.toHonoHandler({ handler })),\n };\n },\n };\n }\n\n /** Defines and registers a route with its handler in a single call. */\n defineRoute<RouteConfig extends IAuthRouteConfig, ResponseType = unknown>(opts: {\n configs: RouteConfig;\n handler: TRouteHandler<ResponseType, RouteEnv>;\n hook?: Hook<any, RouteEnv, string, ValueOrPromise<any>>;\n }): IDefineRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath> {\n const routeConfigs = this.getRouteConfigs<RouteConfig>({ configs: opts.configs });\n\n return {\n configs: routeConfigs,\n route: this.router.openapi(\n routeConfigs,\n this.toHonoHandler<ResponseType>({ handler: opts.handler }),\n opts.hook,\n ),\n };\n }\n\n /** Defines a JSX route that renders server-side HTML via c.html(). */\n defineJSXRoute<RouteConfig extends IAuthRouteConfig, ResponseType = unknown>(opts: {\n configs: RouteConfig;\n handler: TRouteHandler<ResponseType, RouteEnv>;\n hook?: Hook<any, RouteEnv, string, ValueOrPromise<any>>;\n }): IDefineRouteOptions<RouteConfig, RouteEnv, RouteSchema, BasePath> {\n const routeConfigs = this.getJSXRouteConfigs<RouteConfig>({ configs: opts.configs });\n\n return {\n configs: routeConfigs,\n route: this.router.openapi(\n routeConfigs,\n this.toHonoHandler<ResponseType>({ handler: opts.handler }),\n opts.hook,\n ),\n };\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { MetadataRegistry } from '../../helpers/inversion/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { NotSupportedUtility } from '../../utilities/index.js';
|
|
4
4
|
import { BaseHelper, getError } from '@venizia/ignis-helpers/core';
|
|
5
5
|
/**
|
|
6
6
|
* Brands the datasource root so `@repository` can recognise a subclass WITHOUT `instanceof`.
|
|
@@ -41,7 +41,7 @@ export class AbstractDataSource extends BaseHelper {
|
|
|
41
41
|
}
|
|
42
42
|
/** Defaults to throwing NotSupported - only connectors with real transaction support override this; async so callers get a rejected promise, not a synchronous throw that skips try/catch. */
|
|
43
43
|
async beginTransaction(_opts) {
|
|
44
|
-
return throwNotSupported({
|
|
44
|
+
return NotSupportedUtility.throwNotSupported({
|
|
45
45
|
scope: this.constructor.name,
|
|
46
46
|
feature: 'Transactions',
|
|
47
47
|
logger: this.logger,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../src/base/datasources/abstract.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../src/base/datasources/abstract.ts"],"names":[],"mappings":"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","sourcesContent":["import { MetadataRegistry } from '@/helpers/inversion';\nimport { NotSupportedUtility } from '@/utilities';\nimport type { AnyType, TClass, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport type {\n IDataSource,\n IDataSourceCapabilities,\n ITransaction,\n ITransactionOptions,\n TAnyDataSourceSchema,\n} from './common';\n\n/**\n * Brands the datasource root so `@repository` can recognise a subclass WITHOUT `instanceof`.\n *\n * Two copies of this package give two `AbstractDataSource` classes, and `instanceof` across them is\n * false - the same trap `isApplicationError` exists to avoid for `ApplicationError`. `Symbol.for` is\n * realm-keyed, so both copies produce this exact symbol, and a static is inherited by every\n * subclass however deep.\n */\nexport const DATA_SOURCE_BRAND = Symbol.for('@venizia/ignis-kernel:abstract-data-source');\n\n/** True for `AbstractDataSource` itself and for any class extending it, across package copies. */\nexport const isDataSourceClass = (value: unknown): value is TClass<AnyType> => {\n return typeof value === 'function' && DATA_SOURCE_BRAND in value;\n};\n\n/** Engine-neutral datasource root - NO SQL members. Every connector family extends this. */\nexport abstract class AbstractDataSource<\n Settings extends object = {},\n Schema extends TAnyDataSourceSchema = TAnyDataSourceSchema,\n ConfigurableOptions extends object = {},\n>\n extends BaseHelper\n implements IDataSource<Settings, Schema, ConfigurableOptions>\n{\n /** Read by {@link isDataSourceClass}. Static, so every subclass inherits it. */\n static readonly [DATA_SOURCE_BRAND] = true;\n\n name: string;\n settings: Settings;\n schema: Schema;\n\n abstract configure(opts?: ConfigurableOptions): ValueOrPromise<void>;\n\n getSettings() {\n return this.settings;\n }\n\n getSchema(): Schema {\n if (!this.schema) {\n throw getError({\n message: `[${this.constructor.name}] Schema not initialized. Override getSchema() or provide schema in constructor.`,\n });\n }\n return this.schema;\n }\n\n /** Capability probe, overridden by connectors that support it (e.g. postgres reports `{ transactions: true }`). */\n getCapabilities(): IDataSourceCapabilities {\n return { transactions: false };\n }\n\n /** Nothing to release at this root; a family that holds a connection overrides it. */\n close(): Promise<void> {\n return Promise.resolve();\n }\n\n /** Defaults to throwing NotSupported - only connectors with real transaction support override this; async so callers get a rejected promise, not a synchronous throw that skips try/catch. */\n async beginTransaction(_opts?: ITransactionOptions): Promise<ITransaction> {\n return NotSupportedUtility.throwNotSupported({\n scope: this.constructor.name,\n feature: 'Transactions',\n logger: this.logger,\n });\n }\n\n /** Model classes bound to this datasource via `@repository` metadata - paradigm-free (no schema/relation resolution). */\n protected getBoundModelClasses(): Array<TClass<unknown>> {\n return MetadataRegistry.getInstance().getModelClasses({\n dataSource: this.constructor as TClass<IDataSource>,\n });\n }\n\n /** Walks model classes bound to this datasource, reads a connector-specific artifact via `read`, and returns a name-keyed registry - skips undefined reads, throws on duplicate names, honors `autoDiscovery: false`. */\n protected discoverDefinitions<TDefinition extends { name: string }>(opts: {\n read: (modelClass: TClass<unknown>) => TDefinition | undefined;\n kind: string;\n }): Record<string, TDefinition> {\n const { read, kind } = opts;\n const logger = this.logger.for(this.discoverDefinitions.name);\n const registry = MetadataRegistry.getInstance();\n\n const metadata = registry.getDataSourceMetadata({ target: this.constructor });\n if (metadata?.autoDiscovery === false) {\n logger.debug('Auto-discovery disabled for %s', this.name);\n return {};\n }\n\n const modelClasses = this.getBoundModelClasses();\n\n const definitions: Record<string, TDefinition> = {};\n const definitionOwners = new Map<string, string>();\n\n for (const modelClass of modelClasses) {\n const definition = read(modelClass);\n\n if (!definition) {\n logger.warn(\n 'Model has no %s definition | Skipping | Name: %s | Model: %s',\n kind,\n this.name,\n modelClass.name,\n );\n continue;\n }\n\n const existingOwner = definitionOwners.get(definition.name);\n if (existingOwner !== undefined && existingOwner !== modelClass.name) {\n throw getError({\n message: `[${this.constructor.name}][discoverDefinitions] Duplicate ${kind} name '${definition.name}' | Name: ${this.name} | Classes: ${existingOwner}, ${modelClass.name}`,\n });\n }\n\n definitionOwners.set(definition.name, modelClass.name);\n definitions[definition.name] = definition;\n }\n\n const names = Object.keys(definitions);\n logger.debug(\n 'Detected %s(s) | Name: %s | Count: %s | Names: %j',\n kind,\n this.name,\n names.length,\n names,\n );\n\n return definitions;\n }\n}\n"]}
|