@venizia/ignis-kernel 0.3.6 → 0.4.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.
Files changed (140) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/cjs/base/applications/abstract.js +2 -2
  3. package/dist/cjs/base/applications/abstract.js.map +1 -1
  4. package/dist/cjs/base/applications/artifact-group.js +1 -1
  5. package/dist/cjs/base/applications/artifact-group.js.map +1 -1
  6. package/dist/cjs/base/applications/artifact-index.js +11 -11
  7. package/dist/cjs/base/applications/artifact-index.js.map +1 -1
  8. package/dist/cjs/base/applications/boot-sequence.js +1 -1
  9. package/dist/cjs/base/applications/boot-sequence.js.map +1 -1
  10. package/dist/cjs/base/applications/rest.js +5 -5
  11. package/dist/cjs/base/applications/rest.js.map +1 -1
  12. package/dist/cjs/base/auth/authenticate/common/codecs.js +2 -2
  13. package/dist/cjs/base/auth/authenticate/common/codecs.js.map +1 -1
  14. package/dist/cjs/base/auth/authenticate/providers/authentication.provider.js +1 -1
  15. package/dist/cjs/base/auth/authenticate/providers/authentication.provider.js.map +1 -1
  16. package/dist/cjs/base/auth/authenticate/strategies/strategy-registry.js +1 -1
  17. package/dist/cjs/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
  18. package/dist/cjs/base/auth/authorize/builders/grant.builder.js +12 -12
  19. package/dist/cjs/base/auth/authorize/builders/grant.builder.js.map +1 -1
  20. package/dist/cjs/base/auth/authorize/builders/permission.builder.js +1 -1
  21. package/dist/cjs/base/auth/authorize/builders/permission.builder.js.map +1 -1
  22. package/dist/cjs/base/auth/authorize/builders/policy.builder.js +1 -1
  23. package/dist/cjs/base/auth/authorize/builders/policy.builder.js.map +1 -1
  24. package/dist/cjs/base/auth/authorize/common/constants/authorization.d.ts.map +1 -1
  25. package/dist/cjs/base/auth/authorize/common/constants/authorization.js +2 -2
  26. package/dist/cjs/base/auth/authorize/common/constants/authorization.js.map +1 -1
  27. package/dist/cjs/base/auth/authorize/enforcers/enforcer-registry.js +1 -1
  28. package/dist/cjs/base/auth/authorize/enforcers/enforcer-registry.js.map +1 -1
  29. package/dist/cjs/base/auth/authorize/providers/authorization.provider.js +3 -3
  30. package/dist/cjs/base/auth/authorize/providers/authorization.provider.js.map +1 -1
  31. package/dist/cjs/base/controllers/factory/controller.d.ts +2 -2
  32. package/dist/cjs/base/controllers/factory/controller.d.ts.map +1 -1
  33. package/dist/cjs/base/controllers/factory/controller.js +1 -0
  34. package/dist/cjs/base/controllers/factory/controller.js.map +1 -1
  35. package/dist/cjs/base/controllers/factory/crud/abstract.d.ts +1 -1
  36. package/dist/cjs/base/controllers/factory/crud/abstract.d.ts.map +1 -1
  37. package/dist/cjs/base/controllers/factory/crud/abstract.js.map +1 -1
  38. package/dist/cjs/base/controllers/factory/definition.js +1 -1
  39. package/dist/cjs/base/controllers/factory/definition.js.map +1 -1
  40. package/dist/cjs/base/controllers/rest/extras.js +5 -5
  41. package/dist/cjs/base/controllers/rest/extras.js.map +1 -1
  42. package/dist/cjs/base/metadata/injectable.js +1 -1
  43. package/dist/cjs/base/metadata/injectable.js.map +1 -1
  44. package/dist/cjs/base/metadata/persistents.js +4 -4
  45. package/dist/cjs/base/metadata/persistents.js.map +1 -1
  46. package/dist/cjs/base/metadata/routes/controller.js +1 -1
  47. package/dist/cjs/base/metadata/routes/controller.js.map +1 -1
  48. package/dist/cjs/base/middlewares/app-error/app-error.middleware.js +3 -3
  49. package/dist/cjs/base/middlewares/app-error/app-error.middleware.js.map +1 -1
  50. package/dist/cjs/base/middlewares/app-error/zod.handler.js +2 -2
  51. package/dist/cjs/base/middlewares/app-error/zod.handler.js.map +1 -1
  52. package/dist/cjs/base/middlewares/form-body/form-body.middleware.js +2 -2
  53. package/dist/cjs/base/middlewares/form-body/form-body.middleware.js.map +1 -1
  54. package/dist/cjs/base/middlewares/not-found/not-found.middleware.js.map +1 -1
  55. package/dist/cjs/base/models/common/utilities.js +1 -1
  56. package/dist/cjs/base/models/common/utilities.js.map +1 -1
  57. package/dist/cjs/base/repositories/common/types/contracts.d.ts +17 -17
  58. package/dist/cjs/base/repositories/common/types/contracts.d.ts.map +1 -1
  59. package/dist/cjs/base/repositories/common/types/contracts.js.map +1 -1
  60. package/dist/cjs/base/repositories/core/abstract.d.ts +17 -17
  61. package/dist/cjs/base/repositories/core/abstract.d.ts.map +1 -1
  62. package/dist/cjs/base/repositories/core/abstract.js +4 -3
  63. package/dist/cjs/base/repositories/core/abstract.js.map +1 -1
  64. package/dist/cjs/helpers/inversion/mixins/model.mixin.js +1 -1
  65. package/dist/cjs/helpers/inversion/mixins/model.mixin.js.map +1 -1
  66. package/dist/cjs/helpers/inversion/mixins/repository.mixin.js +1 -1
  67. package/dist/cjs/helpers/inversion/mixins/repository.mixin.js.map +1 -1
  68. package/dist/cjs/repository.d.ts +1 -1
  69. package/dist/cjs/repository.d.ts.map +1 -1
  70. package/dist/cjs/repository.js.map +1 -1
  71. package/dist/esm/base/applications/abstract.js +2 -2
  72. package/dist/esm/base/applications/abstract.js.map +1 -1
  73. package/dist/esm/base/applications/artifact-group.js +1 -1
  74. package/dist/esm/base/applications/artifact-group.js.map +1 -1
  75. package/dist/esm/base/applications/artifact-index.js +11 -11
  76. package/dist/esm/base/applications/artifact-index.js.map +1 -1
  77. package/dist/esm/base/applications/boot-sequence.js +1 -1
  78. package/dist/esm/base/applications/boot-sequence.js.map +1 -1
  79. package/dist/esm/base/applications/rest.js +5 -5
  80. package/dist/esm/base/applications/rest.js.map +1 -1
  81. package/dist/esm/base/auth/authenticate/common/codecs.js +2 -2
  82. package/dist/esm/base/auth/authenticate/common/codecs.js.map +1 -1
  83. package/dist/esm/base/auth/authenticate/providers/authentication.provider.js +1 -1
  84. package/dist/esm/base/auth/authenticate/providers/authentication.provider.js.map +1 -1
  85. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js +1 -1
  86. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
  87. package/dist/esm/base/auth/authorize/builders/grant.builder.js +12 -12
  88. package/dist/esm/base/auth/authorize/builders/grant.builder.js.map +1 -1
  89. package/dist/esm/base/auth/authorize/builders/permission.builder.js +1 -1
  90. package/dist/esm/base/auth/authorize/builders/permission.builder.js.map +1 -1
  91. package/dist/esm/base/auth/authorize/builders/policy.builder.js +1 -1
  92. package/dist/esm/base/auth/authorize/builders/policy.builder.js.map +1 -1
  93. package/dist/esm/base/auth/authorize/common/constants/authorization.d.ts.map +1 -1
  94. package/dist/esm/base/auth/authorize/common/constants/authorization.js +2 -2
  95. package/dist/esm/base/auth/authorize/common/constants/authorization.js.map +1 -1
  96. package/dist/esm/base/auth/authorize/enforcers/enforcer-registry.js +1 -1
  97. package/dist/esm/base/auth/authorize/enforcers/enforcer-registry.js.map +1 -1
  98. package/dist/esm/base/auth/authorize/providers/authorization.provider.js +3 -3
  99. package/dist/esm/base/auth/authorize/providers/authorization.provider.js.map +1 -1
  100. package/dist/esm/base/controllers/factory/controller.d.ts +2 -2
  101. package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
  102. package/dist/esm/base/controllers/factory/controller.js +1 -0
  103. package/dist/esm/base/controllers/factory/controller.js.map +1 -1
  104. package/dist/esm/base/controllers/factory/crud/abstract.d.ts +1 -1
  105. package/dist/esm/base/controllers/factory/crud/abstract.d.ts.map +1 -1
  106. package/dist/esm/base/controllers/factory/crud/abstract.js.map +1 -1
  107. package/dist/esm/base/controllers/factory/definition.js +1 -1
  108. package/dist/esm/base/controllers/factory/definition.js.map +1 -1
  109. package/dist/esm/base/controllers/rest/extras.js +5 -5
  110. package/dist/esm/base/controllers/rest/extras.js.map +1 -1
  111. package/dist/esm/base/metadata/injectable.js +1 -1
  112. package/dist/esm/base/metadata/injectable.js.map +1 -1
  113. package/dist/esm/base/metadata/persistents.js +4 -4
  114. package/dist/esm/base/metadata/persistents.js.map +1 -1
  115. package/dist/esm/base/metadata/routes/controller.js +1 -1
  116. package/dist/esm/base/metadata/routes/controller.js.map +1 -1
  117. package/dist/esm/base/middlewares/app-error/app-error.middleware.js +3 -3
  118. package/dist/esm/base/middlewares/app-error/app-error.middleware.js.map +1 -1
  119. package/dist/esm/base/middlewares/app-error/zod.handler.js +2 -2
  120. package/dist/esm/base/middlewares/app-error/zod.handler.js.map +1 -1
  121. package/dist/esm/base/middlewares/form-body/form-body.middleware.js +2 -2
  122. package/dist/esm/base/middlewares/form-body/form-body.middleware.js.map +1 -1
  123. package/dist/esm/base/middlewares/not-found/not-found.middleware.js.map +1 -1
  124. package/dist/esm/base/models/common/utilities.js +1 -1
  125. package/dist/esm/base/models/common/utilities.js.map +1 -1
  126. package/dist/esm/base/repositories/common/types/contracts.d.ts +17 -17
  127. package/dist/esm/base/repositories/common/types/contracts.d.ts.map +1 -1
  128. package/dist/esm/base/repositories/common/types/contracts.js.map +1 -1
  129. package/dist/esm/base/repositories/core/abstract.d.ts +17 -17
  130. package/dist/esm/base/repositories/core/abstract.d.ts.map +1 -1
  131. package/dist/esm/base/repositories/core/abstract.js +4 -3
  132. package/dist/esm/base/repositories/core/abstract.js.map +1 -1
  133. package/dist/esm/helpers/inversion/mixins/model.mixin.js +1 -1
  134. package/dist/esm/helpers/inversion/mixins/model.mixin.js.map +1 -1
  135. package/dist/esm/helpers/inversion/mixins/repository.mixin.js +1 -1
  136. package/dist/esm/helpers/inversion/mixins/repository.mixin.js.map +1 -1
  137. package/dist/esm/repository.d.ts +1 -1
  138. package/dist/esm/repository.d.ts.map +1 -1
  139. package/dist/esm/repository.js.map +1 -1
  140. package/package.json +33 -34
@@ -1 +1 @@
1
- {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractEntity } from '@/base/models';\nimport { SchemaTypes } from '@/base/models/common/constants';\nimport type { AbstractRepository } from '@/base/repositories';\nimport type { TAnyObjectSchema } from '@/base/controllers/common/schema-builders';\nimport type { ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { isClass } from '@venizia/ignis-inversion';\nimport type { Env, Schema } from 'hono';\nimport type {\n ICrudControllerOptions,\n ICustomizableRoutes,\n TEntityDataObject,\n TEntityPersistObject,\n} from '../common';\nimport { PersistableCrudController } from './crud';\nimport { defineControllerRouteConfigs } from './definition';\nimport { registerFactoryRepositoryInjection } from './repository-injection';\n\n/** Factory for generating typed CRUD controllers from entity definitions. */\nexport class ControllerFactory extends BaseHelper {\n constructor() {\n super({ scope: ControllerFactory.name });\n }\n\n static defineCrudController<\n TEntity extends AbstractEntity<TAnyObjectSchema> = AbstractEntity<TAnyObjectSchema>,\n Routes extends ICustomizableRoutes = ICustomizableRoutes,\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n TDataObject extends object = TEntityDataObject<TEntity>,\n TPersistObject extends object = TEntityPersistObject<TEntity>,\n >(defOpts: ICrudControllerOptions<TEntity, Routes>) {\n const { controller, entity, authenticate, authorize, routes } = defOpts;\n\n const {\n name,\n basePath = 'unknown_path',\n isStrict = { path: true, requestSchema: true },\n } = controller;\n if (!basePath || basePath === 'unknown_path') {\n throw getError({\n message: `[defineCrudController] Invalid controller basePath | name: ${name} | basePath: ${basePath}`,\n });\n }\n\n const entityClass = isClass(entity) ? entity : entity();\n const entityInstance = new entityClass();\n\n const routeDefinitions = defineControllerRouteConfigs({\n isStrict: isStrict.requestSchema ?? true,\n idType: entityInstance.getIdType(),\n authenticate,\n authorize,\n routes,\n schema: {\n select: entityInstance.getSchema({ type: SchemaTypes.SELECT }),\n create: entityInstance.getSchema({ type: SchemaTypes.CREATE }),\n update: entityInstance.getSchema({ type: SchemaTypes.UPDATE }),\n },\n serverStampedKeys: entityInstance.getServerStampedKeys(),\n });\n\n const controllerClass = class extends PersistableCrudController<\n TEntity,\n RouteEnv,\n RouteSchema,\n BasePath,\n ConfigurableOptions,\n TDataObject,\n TPersistObject\n > {\n constructor(repository: AbstractRepository<TDataObject, TPersistObject>) {\n super({\n scope: name,\n path: basePath,\n isStrict: isStrict.path ?? true,\n repository,\n definitions: routeDefinitions,\n });\n }\n\n /** Registers each CRUD route whose handler tier supplies it, honoring enabledRoutes/readonly. */\n override binding(): ValueOrPromise<void> {\n const isEnabled = (routeKey: keyof ICustomizableRoutes) => {\n if (controller.enabledRoutes) {\n return controller.enabledRoutes.includes(routeKey);\n }\n return routes?.[routeKey]?.enabled !== false;\n };\n\n // Read routes - always registered (unless explicitly disabled)\n if (isEnabled('count')) {\n this.defineRoute({\n configs: routeDefinitions.COUNT,\n handler: async context => this.count({ context }),\n });\n }\n\n if (isEnabled('find')) {\n this.defineRoute({\n configs: routeDefinitions.FIND,\n handler: async context => this.find({ context }),\n });\n }\n\n if (isEnabled('findOne')) {\n this.defineRoute({\n configs: routeDefinitions.FIND_ONE,\n handler: async context => this.findOne({ context }),\n });\n }\n\n if (isEnabled('findById')) {\n this.defineRoute({\n configs: routeDefinitions.FIND_BY_ID,\n handler: async context => this.findById({ context }),\n });\n }\n\n // Write routes - skipped when readonly\n if (controller.readonly) {\n return;\n }\n\n if (isEnabled('create')) {\n this.defineRoute({\n configs: routeDefinitions.CREATE,\n handler: async context => this.create({ context }),\n });\n }\n\n if (isEnabled('updateById')) {\n this.defineRoute({\n configs: routeDefinitions.UPDATE_BY_ID,\n handler: async context => this.updateById({ context }),\n });\n }\n\n if (isEnabled('updateBy')) {\n this.defineRoute({\n configs: routeDefinitions.UPDATE_BY,\n handler: async context => this.updateBy({ context }),\n });\n }\n\n if (isEnabled('deleteById')) {\n this.defineRoute({\n configs: routeDefinitions.DELETE_BY_ID,\n handler: async context => this.deleteById({ context }),\n });\n }\n\n if (isEnabled('deleteBy')) {\n this.defineRoute({\n configs: routeDefinitions.DELETE_BY,\n handler: async context => this.deleteBy({ context }),\n });\n }\n }\n };\n\n Object.defineProperty(controllerClass, 'name', { value: name, configurable: true });\n registerFactoryRepositoryInjection({\n target: controllerClass,\n factoryName: 'defineCrudController',\n controllerName: name,\n repositoryName: defOpts.repository.name,\n });\n return controllerClass;\n }\n}\n"]}
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../../../src/base/controllers/factory/controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractEntity } from '@/base/models';\nimport { SchemaTypes } from '@/base/models/common/constants';\nimport type { AbstractRepository } from '@/base/repositories';\nimport type { TAnyObjectSchema } from '@/base/controllers/common/schema-builders';\nimport type { AnyType, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { isClass } from '@venizia/ignis-inversion';\nimport type { Env, Schema } from 'hono';\nimport type {\n ICrudControllerOptions,\n ICustomizableRoutes,\n TEntityDataObject,\n TEntityPersistObject,\n} from '../common';\nimport { PersistableCrudController } from './crud';\nimport { defineControllerRouteConfigs } from './definition';\nimport { registerFactoryRepositoryInjection } from './repository-injection';\n\n/** Factory for generating typed CRUD controllers from entity definitions. */\nexport class ControllerFactory extends BaseHelper {\n constructor() {\n super({ scope: ControllerFactory.name });\n }\n\n static defineCrudController<\n TEntity extends AbstractEntity<TAnyObjectSchema> = AbstractEntity<TAnyObjectSchema>,\n Routes extends ICustomizableRoutes = ICustomizableRoutes,\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n TDataObject extends object = TEntityDataObject<TEntity>,\n TPersistObject extends object = TEntityPersistObject<TEntity>,\n >(defOpts: ICrudControllerOptions<TEntity, Routes>) {\n const { controller, entity, authenticate, authorize, routes } = defOpts;\n\n const {\n name,\n basePath = 'unknown_path',\n isStrict = { path: true, requestSchema: true },\n } = controller;\n if (!basePath || basePath === 'unknown_path') {\n throw getError({\n message: `[defineCrudController] Invalid controller basePath | name: ${name} | basePath: ${basePath}`,\n });\n }\n\n const entityClass = isClass(entity) ? entity : entity();\n const entityInstance = new entityClass();\n\n const routeDefinitions = defineControllerRouteConfigs({\n isStrict: isStrict.requestSchema ?? true,\n idType: entityInstance.getIdType(),\n authenticate,\n authorize,\n routes,\n schema: {\n select: entityInstance.getSchema({ type: SchemaTypes.SELECT }),\n create: entityInstance.getSchema({ type: SchemaTypes.CREATE }),\n update: entityInstance.getSchema({ type: SchemaTypes.UPDATE }),\n },\n serverStampedKeys: entityInstance.getServerStampedKeys(),\n });\n\n const controllerClass = class extends PersistableCrudController<\n TEntity,\n RouteEnv,\n RouteSchema,\n BasePath,\n ConfigurableOptions,\n TDataObject,\n TPersistObject\n > {\n // Any extra options: a repository whose options narrow `IExtraOptions` (a typed transaction) must fit.\n constructor(repository: AbstractRepository<TDataObject, TPersistObject, AnyType>) {\n super({\n scope: name,\n path: basePath,\n isStrict: isStrict.path ?? true,\n repository,\n definitions: routeDefinitions,\n });\n }\n\n /** Registers each CRUD route whose handler tier supplies it, honoring enabledRoutes/readonly. */\n override binding(): ValueOrPromise<void> {\n const isEnabled = (routeKey: keyof ICustomizableRoutes) => {\n if (controller.enabledRoutes) {\n return controller.enabledRoutes.includes(routeKey);\n }\n return routes?.[routeKey]?.enabled !== false;\n };\n\n // Read routes - always registered (unless explicitly disabled)\n if (isEnabled('count')) {\n this.defineRoute({\n configs: routeDefinitions.COUNT,\n handler: async (context) => this.count({ context }),\n });\n }\n\n if (isEnabled('find')) {\n this.defineRoute({\n configs: routeDefinitions.FIND,\n handler: async (context) => this.find({ context }),\n });\n }\n\n if (isEnabled('findOne')) {\n this.defineRoute({\n configs: routeDefinitions.FIND_ONE,\n handler: async (context) => this.findOne({ context }),\n });\n }\n\n if (isEnabled('findById')) {\n this.defineRoute({\n configs: routeDefinitions.FIND_BY_ID,\n handler: async (context) => this.findById({ context }),\n });\n }\n\n // Write routes - skipped when readonly\n if (controller.readonly) {\n return;\n }\n\n if (isEnabled('create')) {\n this.defineRoute({\n configs: routeDefinitions.CREATE,\n handler: async (context) => this.create({ context }),\n });\n }\n\n if (isEnabled('updateById')) {\n this.defineRoute({\n configs: routeDefinitions.UPDATE_BY_ID,\n handler: async (context) => this.updateById({ context }),\n });\n }\n\n if (isEnabled('updateBy')) {\n this.defineRoute({\n configs: routeDefinitions.UPDATE_BY,\n handler: async (context) => this.updateBy({ context }),\n });\n }\n\n if (isEnabled('deleteById')) {\n this.defineRoute({\n configs: routeDefinitions.DELETE_BY_ID,\n handler: async (context) => this.deleteById({ context }),\n });\n }\n\n if (isEnabled('deleteBy')) {\n this.defineRoute({\n configs: routeDefinitions.DELETE_BY,\n handler: async (context) => this.deleteBy({ context }),\n });\n }\n }\n };\n\n Object.defineProperty(controllerClass, 'name', { value: name, configurable: true });\n registerFactoryRepositoryInjection({\n target: controllerClass,\n factoryName: 'defineCrudController',\n controllerName: name,\n repositoryName: defOpts.repository.name,\n });\n return controllerClass;\n }\n}\n"]}
@@ -19,7 +19,7 @@ export declare abstract class AbstractCrudController<TEntity extends AbstractEnt
19
19
  scope: string;
20
20
  path: string;
21
21
  isStrict?: boolean;
22
- repository: AbstractRepository<TDataObject, TPersistObject>;
22
+ repository: AbstractRepository<TDataObject, TPersistObject, AnyType>;
23
23
  definitions: AnyType;
24
24
  });
25
25
  /** 400 when a bulk operation is missing its `where` filter; undefined when it is present. */
@@ -1 +1 @@
1
- {"version":3,"file":"abstract.d.ts","sourceRoot":"","sources":["../../../../../../src/base/controllers/factory/crud/abstract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,KAAK,oBAAoB,CAAC,SAAS,IAC/B;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,GACvC;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE3C,yRAAyR;AACzR,8BAAsB,sBAAsB,CAC1C,OAAO,SAAS,cAAc,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,gBAAgB,CAAC,EACnF,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,GAAG,iBAAiB,CAAC,OAAO,CAAC,EACvD,cAAc,SAAS,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAC7D,SAAQ,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IAChF,UAAU,EAAE,kBAAkB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;gBAEhD,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,kBAAkB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC5D,WAAW,EAAE,OAAO,CAAC;KACtB;IAMD,6FAA6F;IAC7F,cAAc,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAWzE,2GAA2G;IAC3G,gBAAgB,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI,EAAE;QAC/C,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE;YACN,SAAS,CAAC,EAAE,SAAS,CAAC;YACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;SACtB,CAAC;KACH,GAAG,oBAAoB,CAAC,SAAS,CAAC;CAyBpC"}
1
+ {"version":3,"file":"abstract.d.ts","sourceRoot":"","sources":["../../../../../../src/base/controllers/factory/crud/abstract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,KAAK,oBAAoB,CAAC,SAAS,IAC/B;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,GACvC;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE3C,yRAAyR;AACzR,8BAAsB,sBAAsB,CAC1C,OAAO,SAAS,cAAc,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,gBAAgB,CAAC,EACnF,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,GAAG,iBAAiB,CAAC,OAAO,CAAC,EACvD,cAAc,SAAS,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAC7D,SAAQ,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IAChF,UAAU,EAAE,kBAAkB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;gBAEhD,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,kBAAkB,CAAC,WAAW,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QACrE,WAAW,EAAE,OAAO,CAAC;KACtB;IAMD,6FAA6F;IAC7F,cAAc,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAWzE,2GAA2G;IAC3G,gBAAgB,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI,EAAE;QAC/C,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE;YACN,SAAS,CAAC,EAAE,SAAS,CAAC;YACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;SACtB,CAAC;KACH,GAAG,oBAAoB,CAAC,SAAS,CAAC;CAyBpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../../../src/base/controllers/factory/crud/abstract.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAMrD,yRAAyR;AACzR,MAAM,OAAgB,sBAQpB,SAAQ,kBAAwE;IAGhF,YAAY,IAMX;QACC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACtC,CAAC;IAED,6FAA6F;IAC7F,cAAc,CAAC,IAA0D;QACvE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,OAAO,CAAC,IAAI,CACjB,EAAE,OAAO,EAAE,8CAA8C,EAAE,EAC3D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CACjC,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,2GAA2G;IAC3G,gBAAgB,CAA2B,IAM1C;QACC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QAC9C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,YAAY,IAAI,EAAE,CAAC;QAEnD,IAAI,SAAS,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACtD,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,IAAI,CACjB,EAAE,OAAO,EAAE,6DAA6D,EAAE,EAC1E,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CACjC;aACF,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,IAAI,QAAQ,CAAC;QACpC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,IAAI,CACjB,EAAE,OAAO,EAAE,8CAA8C,EAAE,EAC3D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CACjC;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;CACF","sourcesContent":["import type { AbstractEntity } from '@/base/models/base';\nimport type { AbstractRepository } from '@/base/repositories';\nimport type { TAnyObjectSchema } from '@/base/controllers/common/schema-builders';\nimport type { AnyType } from '@venizia/ignis-helpers/common';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport type { Env, Schema } from 'hono';\nimport type { TEntityDataObject, TEntityPersistObject, TRouteContext } from '../../common';\nimport { BaseRestController } from '../../rest/base';\n\ntype TBulkWhereResolution<WhereType> =\n | { where: WhereType; error?: undefined }\n | { where?: undefined; error: Response };\n\n/** Base tier of a generated CRUD controller - the repository handle; the response helpers (`respond`, `setListHeaders`) live on BaseRestController so hand-written controllers share them. Read and write verbs are layered on by ReadableCrudController / PersistableCrudController. */\nexport abstract class AbstractCrudController<\n TEntity extends AbstractEntity<TAnyObjectSchema> = AbstractEntity<TAnyObjectSchema>,\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n TDataObject extends object = TEntityDataObject<TEntity>,\n TPersistObject extends object = TEntityPersistObject<TEntity>,\n> extends BaseRestController<RouteEnv, RouteSchema, BasePath, ConfigurableOptions> {\n repository: AbstractRepository<TDataObject, TPersistObject>;\n\n constructor(opts: {\n scope: string;\n path: string;\n isStrict?: boolean;\n repository: AbstractRepository<TDataObject, TPersistObject>;\n definitions: AnyType;\n }) {\n super({ scope: opts.scope, path: opts.path, isStrict: opts.isStrict });\n this.repository = opts.repository;\n this.definitions = opts.definitions;\n }\n\n /** 400 when a bulk operation is missing its `where` filter; undefined when it is present. */\n bulkWhereError(opts: { context: TRouteContext<RouteEnv>; where?: object }) {\n const { context, where } = opts;\n if (!where || Object.keys(where).length === 0) {\n return context.json(\n { message: 'where filter is required for bulk operations' },\n HTTP.ResultCodes.RS_4.BadRequest,\n );\n }\n return undefined;\n }\n\n /** Bulk `where` from the query or the JSON body (long id lists outgrow a URL). Both, or none, is a 400. */\n resolveBulkWhere<WhereType extends object>(opts: {\n context: TRouteContext<RouteEnv>;\n where?: {\n fromQuery?: WhereType;\n fromBody?: WhereType;\n };\n }): TBulkWhereResolution<WhereType> {\n const { context, where: whereSources } = opts;\n const { fromQuery, fromBody } = whereSources ?? {};\n\n if (fromQuery !== undefined && fromBody !== undefined) {\n return {\n error: context.json(\n { message: 'where given in both the query and the body - send it in one' },\n HTTP.ResultCodes.RS_4.BadRequest,\n ),\n };\n }\n\n const where = fromQuery ?? fromBody;\n if (!where || Object.keys(where).length === 0) {\n return {\n error: context.json(\n { message: 'where filter is required for bulk operations' },\n HTTP.ResultCodes.RS_4.BadRequest,\n ),\n };\n }\n\n return { where };\n }\n}\n"]}
1
+ {"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../../../src/base/controllers/factory/crud/abstract.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAMrD,yRAAyR;AACzR,MAAM,OAAgB,sBAQpB,SAAQ,kBAAwE;IAGhF,YAAY,IAMX;QACC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACtC,CAAC;IAED,6FAA6F;IAC7F,cAAc,CAAC,IAA0D;QACvE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,OAAO,CAAC,IAAI,CACjB,EAAE,OAAO,EAAE,8CAA8C,EAAE,EAC3D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CACjC,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,2GAA2G;IAC3G,gBAAgB,CAA2B,IAM1C;QACC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QAC9C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,YAAY,IAAI,EAAE,CAAC;QAEnD,IAAI,SAAS,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACtD,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,IAAI,CACjB,EAAE,OAAO,EAAE,6DAA6D,EAAE,EAC1E,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CACjC;aACF,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,IAAI,QAAQ,CAAC;QACpC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,IAAI,CACjB,EAAE,OAAO,EAAE,8CAA8C,EAAE,EAC3D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CACjC;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;CACF","sourcesContent":["import type { AbstractEntity } from '@/base/models/base';\nimport type { AbstractRepository } from '@/base/repositories';\nimport type { TAnyObjectSchema } from '@/base/controllers/common/schema-builders';\nimport type { AnyType } from '@venizia/ignis-helpers/common';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport type { Env, Schema } from 'hono';\nimport type { TEntityDataObject, TEntityPersistObject, TRouteContext } from '../../common';\nimport { BaseRestController } from '../../rest/base';\n\ntype TBulkWhereResolution<WhereType> =\n | { where: WhereType; error?: undefined }\n | { where?: undefined; error: Response };\n\n/** Base tier of a generated CRUD controller - the repository handle; the response helpers (`respond`, `setListHeaders`) live on BaseRestController so hand-written controllers share them. Read and write verbs are layered on by ReadableCrudController / PersistableCrudController. */\nexport abstract class AbstractCrudController<\n TEntity extends AbstractEntity<TAnyObjectSchema> = AbstractEntity<TAnyObjectSchema>,\n RouteEnv extends Env = Env,\n RouteSchema extends Schema = {},\n BasePath extends string = '/',\n ConfigurableOptions extends object = {},\n TDataObject extends object = TEntityDataObject<TEntity>,\n TPersistObject extends object = TEntityPersistObject<TEntity>,\n> extends BaseRestController<RouteEnv, RouteSchema, BasePath, ConfigurableOptions> {\n repository: AbstractRepository<TDataObject, TPersistObject>;\n\n constructor(opts: {\n scope: string;\n path: string;\n isStrict?: boolean;\n repository: AbstractRepository<TDataObject, TPersistObject, AnyType>;\n definitions: AnyType;\n }) {\n super({ scope: opts.scope, path: opts.path, isStrict: opts.isStrict });\n this.repository = opts.repository;\n this.definitions = opts.definitions;\n }\n\n /** 400 when a bulk operation is missing its `where` filter; undefined when it is present. */\n bulkWhereError(opts: { context: TRouteContext<RouteEnv>; where?: object }) {\n const { context, where } = opts;\n if (!where || Object.keys(where).length === 0) {\n return context.json(\n { message: 'where filter is required for bulk operations' },\n HTTP.ResultCodes.RS_4.BadRequest,\n );\n }\n return undefined;\n }\n\n /** Bulk `where` from the query or the JSON body (long id lists outgrow a URL). Both, or none, is a 400. */\n resolveBulkWhere<WhereType extends object>(opts: {\n context: TRouteContext<RouteEnv>;\n where?: {\n fromQuery?: WhereType;\n fromBody?: WhereType;\n };\n }): TBulkWhereResolution<WhereType> {\n const { context, where: whereSources } = opts;\n const { fromQuery, fromBody } = whereSources ?? {};\n\n if (fromQuery !== undefined && fromBody !== undefined) {\n return {\n error: context.json(\n { message: 'where given in both the query and the body - send it in one' },\n HTTP.ResultCodes.RS_4.BadRequest,\n ),\n };\n }\n\n const where = fromQuery ?? fromBody;\n if (!where || Object.keys(where).length === 0) {\n return {\n error: context.json(\n { message: 'where filter is required for bulk operations' },\n HTTP.ResultCodes.RS_4.BadRequest,\n ),\n };\n }\n\n return { where };\n }\n}\n"]}
@@ -35,7 +35,7 @@ export class RouteConfigResolver {
35
35
  // A `.transform()` pipe has no shape to read, so every key it might hold counts.
36
36
  const isObjectSchema = schema instanceof z.ZodObject;
37
37
  const omittedKeys = isObjectSchema
38
- ? droppedKeys.filter(key => Object.hasOwn(schema.shape, key))
38
+ ? droppedKeys.filter((key) => Object.hasOwn(schema.shape, key))
39
39
  : droppedKeys;
40
40
  if (omittedKeys.length === 0) {
41
41
  return schema;
@@ -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":"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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"]}
@@ -25,9 +25,9 @@ export class ResponseExtras {
25
25
  ? undefined
26
26
  : match[3]
27
27
  .split(',')
28
- .map(key => key.trim())
29
- .filter(key => key.length > 0);
30
- if (keys?.some(key => !IDENTIFIER.test(key))) {
28
+ .map((key) => key.trim())
29
+ .filter((key) => key.length > 0);
30
+ if (keys?.some((key) => !IDENTIFIER.test(key))) {
31
31
  throw ResponseExtras.badRequest({ message: `Malformed key in extra '${raw.trim()}'` });
32
32
  }
33
33
  entries.push({ name, isExcluded: match[1] === '-', keys });
@@ -77,7 +77,7 @@ export class ResponseExtras {
77
77
  message: `Extra '${entry.name}' needs keys: ${definition.keys.join(', ')} | Name them as ${entry.name}(key,key)`,
78
78
  });
79
79
  }
80
- const unknown = entry.keys.filter(key => !definition.keys.includes(key));
80
+ const unknown = entry.keys.filter((key) => !definition.keys.includes(key));
81
81
  if (unknown.length > 0) {
82
82
  throw ResponseExtras.badRequest({
83
83
  message: `Unknown key for extra '${entry.name}': ${unknown.join(', ')} | It offers: ${definition.keys.join(', ')}`,
@@ -137,7 +137,7 @@ export class ResponseExtras {
137
137
  current += character;
138
138
  }
139
139
  parts.push(current);
140
- return parts.filter(part => part.trim().length > 0);
140
+ return parts.filter((part) => part.trim().length > 0);
141
141
  }
142
142
  static badRequest(opts) {
143
143
  return getError({
@@ -1 +1 @@
1
- {"version":3,"file":"extras.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/extras.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/**\n * A figure a list route offers beside its rows:\n * - a function runs when the client names it;\n * - `{ isDefault: true, compute }` always runs, unless the client switches it off with `-name`;\n * - `{ keys, compute }` is a group - the client names the keys it wants (`facets(status,tag)`), and\n * `compute` receives exactly those, so one aggregate pass serves them all.\n */\nexport type TResponseExtra =\n | (() => ValueOrPromise<unknown>)\n | { isDefault: boolean; compute: () => ValueOrPromise<unknown>; keys?: never }\n | {\n keys: ReadonlyArray<string>;\n compute: (opts: { keys: Array<string> }) => ValueOrPromise<unknown>;\n isDefault?: never;\n };\n\n/** One entry of `x-request-extra`: `name`, `-name` (a default switched off), `-*` (every default off) or `name(key,key)`. */\nexport interface IRequestedExtra {\n name: string;\n isExcluded: boolean;\n keys?: Array<string>;\n}\n\n/** A name or a key: letters, digits, `_`, `.` and `-` inside. Anything else is refused, never evaluated. */\nconst IDENTIFIER = /^[A-Za-z_][\\w.-]*$/;\nconst ENTRY = /^(-?)([^()\\s]+)(?:\\(([^()]*)\\))?$/;\n\n/** `-*`: every default off - for a read that wants the rows alone. */\nconst ALL_DEFAULTS = '*';\n\n/** Parses `x-request-extra` and resolves it against what a route offers. */\nexport class ResponseExtras {\n /** The entries of the header, in the order written. Malformed input is a 400 naming it. */\n static parse(opts: { header?: string | null }): Array<IRequestedExtra> {\n const header = opts.header?.trim() ?? '';\n if (header === '') {\n return [];\n }\n\n const entries: Array<IRequestedExtra> = [];\n for (const raw of ResponseExtras.splitTopLevel({ header })) {\n const match = raw.trim().match(ENTRY);\n const name = match?.[2];\n\n const isAllDefaultsOff =\n match?.[1] === '-' && name === ALL_DEFAULTS && match[3] === undefined;\n if (!match || !name || (!isAllDefaultsOff && !IDENTIFIER.test(name))) {\n throw ResponseExtras.badRequest({ message: `Malformed extra '${raw.trim()}'` });\n }\n\n const keys =\n match[3] === undefined\n ? undefined\n : match[3]\n .split(',')\n .map(key => key.trim())\n .filter(key => key.length > 0);\n\n if (keys?.some(key => !IDENTIFIER.test(key))) {\n throw ResponseExtras.badRequest({ message: `Malformed key in extra '${raw.trim()}'` });\n }\n\n entries.push({ name, isExcluded: match[1] === '-', keys });\n }\n\n return entries;\n }\n\n /**\n * What to compute: the asked-for extras and the defaults, minus the ones switched off - each with the\n * keys asked for, de-duplicated in the order asked. Every name and key is checked against `offered`.\n */\n static resolve(opts: {\n requested: Array<IRequestedExtra>;\n offered: Record<string, TResponseExtra>;\n }): Map<string, Array<string> | undefined> {\n const { requested, offered } = opts;\n const offeredNames = Object.keys(offered).join(', ') || 'none';\n const plan = new Map<string, Array<string> | undefined>();\n const excluded = new Set<string>();\n\n let isEveryDefaultOff = false;\n\n for (const entry of requested) {\n if (entry.isExcluded && entry.name === ALL_DEFAULTS) {\n isEveryDefaultOff = true;\n continue;\n }\n\n if (!Object.hasOwn(offered, entry.name)) {\n throw ResponseExtras.badRequest({\n message: `Unknown extra requested: ${entry.name} | This route offers: ${offeredNames}`,\n });\n }\n\n if (entry.isExcluded) {\n if (entry.keys !== undefined) {\n throw ResponseExtras.badRequest({\n message: `Switching '${entry.name}' off takes no keys`,\n });\n }\n\n excluded.add(entry.name);\n continue;\n }\n\n const definition = offered[entry.name];\n const isGroup = typeof definition !== 'function' && definition.keys !== undefined;\n\n if (!isGroup) {\n if (entry.keys !== undefined) {\n throw ResponseExtras.badRequest({ message: `Extra '${entry.name}' takes no keys` });\n }\n\n plan.set(entry.name, undefined);\n continue;\n }\n\n if (!entry.keys?.length) {\n throw ResponseExtras.badRequest({\n message: `Extra '${entry.name}' needs keys: ${definition.keys.join(', ')} | Name them as ${entry.name}(key,key)`,\n });\n }\n\n const unknown = entry.keys.filter(key => !definition.keys.includes(key));\n if (unknown.length > 0) {\n throw ResponseExtras.badRequest({\n message: `Unknown key for extra '${entry.name}': ${unknown.join(', ')} | It offers: ${definition.keys.join(', ')}`,\n });\n }\n\n plan.set(entry.name, [...new Set([...(plan.get(entry.name) ?? []), ...entry.keys])]);\n }\n\n for (const [name, definition] of Object.entries(offered)) {\n // A group needs keys, so it never runs unasked, whatever its declaration claims.\n const isDefault =\n typeof definition !== 'function' &&\n definition.keys === undefined &&\n definition.isDefault === true;\n if (isDefault && !isEveryDefaultOff && !plan.has(name)) {\n plan.set(name, undefined);\n }\n }\n\n for (const name of excluded) {\n plan.delete(name);\n }\n\n return plan;\n }\n\n /** Runs the plan in parallel; each value under its name. */\n static async compute(opts: {\n plan: Map<string, Array<string> | undefined>;\n offered: Record<string, TResponseExtra>;\n }): Promise<Record<string, unknown>> {\n const { plan, offered } = opts;\n const names = [...plan.keys()];\n\n // Async, so an extra that throws synchronously becomes a rejection Promise.all owns, never an\n // unhandled one left behind by a sibling already running.\n const values = await Promise.all(\n names.map(async name => {\n const definition = offered[name];\n\n if (typeof definition === 'function') {\n return definition();\n }\n\n if (definition.keys !== undefined) {\n return definition.compute({ keys: plan.get(name) ?? [] });\n }\n\n return definition.compute();\n }),\n );\n\n return Object.fromEntries(names.map((name, index) => [name, values[index]]));\n }\n\n /** Commas inside `( )` belong to the keys, not to the list of extras. */\n private static splitTopLevel(opts: { header: string }): Array<string> {\n const parts: Array<string> = [];\n let depth = 0;\n let current = '';\n\n for (const character of opts.header) {\n if (character === '(') {\n depth++;\n } else if (character === ')') {\n depth--;\n }\n\n if (character === ',' && depth === 0) {\n parts.push(current);\n current = '';\n continue;\n }\n\n current += character;\n }\n\n parts.push(current);\n return parts.filter(part => part.trim().length > 0);\n }\n\n private static badRequest(opts: { message: string }) {\n return getError({\n statusCode: HTTP.ResultCodes.RS_4.BadRequest,\n message: `[x-request-extra] ${opts.message}`,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"extras.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/extras.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/**\n * A figure a list route offers beside its rows:\n * - a function runs when the client names it;\n * - `{ isDefault: true, compute }` always runs, unless the client switches it off with `-name`;\n * - `{ keys, compute }` is a group - the client names the keys it wants (`facets(status,tag)`), and\n * `compute` receives exactly those, so one aggregate pass serves them all.\n */\nexport type TResponseExtra =\n | (() => ValueOrPromise<unknown>)\n | { isDefault: boolean; compute: () => ValueOrPromise<unknown>; keys?: never }\n | {\n keys: ReadonlyArray<string>;\n compute: (opts: { keys: Array<string> }) => ValueOrPromise<unknown>;\n isDefault?: never;\n };\n\n/** One entry of `x-request-extra`: `name`, `-name` (a default switched off), `-*` (every default off) or `name(key,key)`. */\nexport interface IRequestedExtra {\n name: string;\n isExcluded: boolean;\n keys?: Array<string>;\n}\n\n/** A name or a key: letters, digits, `_`, `.` and `-` inside. Anything else is refused, never evaluated. */\nconst IDENTIFIER = /^[A-Za-z_][\\w.-]*$/;\nconst ENTRY = /^(-?)([^()\\s]+)(?:\\(([^()]*)\\))?$/;\n\n/** `-*`: every default off - for a read that wants the rows alone. */\nconst ALL_DEFAULTS = '*';\n\n/** Parses `x-request-extra` and resolves it against what a route offers. */\nexport class ResponseExtras {\n /** The entries of the header, in the order written. Malformed input is a 400 naming it. */\n static parse(opts: { header?: string | null }): Array<IRequestedExtra> {\n const header = opts.header?.trim() ?? '';\n if (header === '') {\n return [];\n }\n\n const entries: Array<IRequestedExtra> = [];\n for (const raw of ResponseExtras.splitTopLevel({ header })) {\n const match = raw.trim().match(ENTRY);\n const name = match?.[2];\n\n const isAllDefaultsOff =\n match?.[1] === '-' && name === ALL_DEFAULTS && match[3] === undefined;\n if (!match || !name || (!isAllDefaultsOff && !IDENTIFIER.test(name))) {\n throw ResponseExtras.badRequest({ message: `Malformed extra '${raw.trim()}'` });\n }\n\n const keys =\n match[3] === undefined\n ? undefined\n : match[3]\n .split(',')\n .map((key) => key.trim())\n .filter((key) => key.length > 0);\n\n if (keys?.some((key) => !IDENTIFIER.test(key))) {\n throw ResponseExtras.badRequest({ message: `Malformed key in extra '${raw.trim()}'` });\n }\n\n entries.push({ name, isExcluded: match[1] === '-', keys });\n }\n\n return entries;\n }\n\n /**\n * What to compute: the asked-for extras and the defaults, minus the ones switched off - each with the\n * keys asked for, de-duplicated in the order asked. Every name and key is checked against `offered`.\n */\n static resolve(opts: {\n requested: Array<IRequestedExtra>;\n offered: Record<string, TResponseExtra>;\n }): Map<string, Array<string> | undefined> {\n const { requested, offered } = opts;\n const offeredNames = Object.keys(offered).join(', ') || 'none';\n const plan = new Map<string, Array<string> | undefined>();\n const excluded = new Set<string>();\n\n let isEveryDefaultOff = false;\n\n for (const entry of requested) {\n if (entry.isExcluded && entry.name === ALL_DEFAULTS) {\n isEveryDefaultOff = true;\n continue;\n }\n\n if (!Object.hasOwn(offered, entry.name)) {\n throw ResponseExtras.badRequest({\n message: `Unknown extra requested: ${entry.name} | This route offers: ${offeredNames}`,\n });\n }\n\n if (entry.isExcluded) {\n if (entry.keys !== undefined) {\n throw ResponseExtras.badRequest({\n message: `Switching '${entry.name}' off takes no keys`,\n });\n }\n\n excluded.add(entry.name);\n continue;\n }\n\n const definition = offered[entry.name];\n const isGroup = typeof definition !== 'function' && definition.keys !== undefined;\n\n if (!isGroup) {\n if (entry.keys !== undefined) {\n throw ResponseExtras.badRequest({ message: `Extra '${entry.name}' takes no keys` });\n }\n\n plan.set(entry.name, undefined);\n continue;\n }\n\n if (!entry.keys?.length) {\n throw ResponseExtras.badRequest({\n message: `Extra '${entry.name}' needs keys: ${definition.keys.join(', ')} | Name them as ${entry.name}(key,key)`,\n });\n }\n\n const unknown = entry.keys.filter((key) => !definition.keys.includes(key));\n if (unknown.length > 0) {\n throw ResponseExtras.badRequest({\n message: `Unknown key for extra '${entry.name}': ${unknown.join(', ')} | It offers: ${definition.keys.join(', ')}`,\n });\n }\n\n plan.set(entry.name, [...new Set([...(plan.get(entry.name) ?? []), ...entry.keys])]);\n }\n\n for (const [name, definition] of Object.entries(offered)) {\n // A group needs keys, so it never runs unasked, whatever its declaration claims.\n const isDefault =\n typeof definition !== 'function' &&\n definition.keys === undefined &&\n definition.isDefault === true;\n if (isDefault && !isEveryDefaultOff && !plan.has(name)) {\n plan.set(name, undefined);\n }\n }\n\n for (const name of excluded) {\n plan.delete(name);\n }\n\n return plan;\n }\n\n /** Runs the plan in parallel; each value under its name. */\n static async compute(opts: {\n plan: Map<string, Array<string> | undefined>;\n offered: Record<string, TResponseExtra>;\n }): Promise<Record<string, unknown>> {\n const { plan, offered } = opts;\n const names = [...plan.keys()];\n\n // Async, so an extra that throws synchronously becomes a rejection Promise.all owns, never an\n // unhandled one left behind by a sibling already running.\n const values = await Promise.all(\n names.map(async (name) => {\n const definition = offered[name];\n\n if (typeof definition === 'function') {\n return definition();\n }\n\n if (definition.keys !== undefined) {\n return definition.compute({ keys: plan.get(name) ?? [] });\n }\n\n return definition.compute();\n }),\n );\n\n return Object.fromEntries(names.map((name, index) => [name, values[index]]));\n }\n\n /** Commas inside `( )` belong to the keys, not to the list of extras. */\n private static splitTopLevel(opts: { header: string }): Array<string> {\n const parts: Array<string> = [];\n let depth = 0;\n let current = '';\n\n for (const character of opts.header) {\n if (character === '(') {\n depth++;\n } else if (character === ')') {\n depth--;\n }\n\n if (character === ',' && depth === 0) {\n parts.push(current);\n current = '';\n continue;\n }\n\n current += character;\n }\n\n parts.push(current);\n return parts.filter((part) => part.trim().length > 0);\n }\n\n private static badRequest(opts: { message: string }) {\n return getError({\n statusCode: HTTP.ResultCodes.RS_4.BadRequest,\n message: `[x-request-extra] ${opts.message}`,\n });\n }\n}\n"]}
@@ -4,7 +4,7 @@ import { ArtifactBindingKeys } from './artifact-keys.js';
4
4
  import { getError } from '@venizia/ignis-helpers/core';
5
5
  /** The root stereotype: marks a class as an artifact the application registers, with its registration defaults. Every other stereotype calls it. */
6
6
  export const injectable = (opts) => {
7
- return target => {
7
+ return (target) => {
8
8
  if (!ArtifactTypes.isValid(opts.type)) {
9
9
  throw getError({
10
10
  message: `[injectable][${target.name}] Invalid artifact type: '${opts.type}' | Expected one of: ${[...ArtifactTypes.SCHEME_SET].join(', ')}`,
@@ -1 +1 @@
1
- {"version":3,"file":"injectable.js","sourceRoot":"","sources":["../../../../src/base/metadata/injectable.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IArtifactMetadata,\n IArtifactRegistrationOptions,\n TBindingScope,\n} from '@/helpers/inversion';\nimport { ArtifactNamespaces, BindingNamespaces } from '@/common/bindings';\nimport { ArtifactTypes, MetadataRegistry } from '@/helpers/inversion';\nimport { ArtifactBindingKeys } from './artifact-keys';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/** The root stereotype: marks a class as an artifact the application registers, with its registration defaults. Every other stereotype calls it. */\nexport const injectable = <ApplicationType = unknown>(\n opts: IArtifactMetadata<ApplicationType>,\n): ClassDecorator => {\n return target => {\n if (!ArtifactTypes.isValid(opts.type)) {\n throw getError({\n message: `[injectable][${target.name}] Invalid artifact type: '${opts.type}' | Expected one of: ${[...ArtifactTypes.SCHEME_SET].join(', ')}`,\n });\n }\n\n // At import time, so the failure lands where the binding is written, not at boot.\n if (opts.binding) {\n BindingNamespaces.assertArtifactNamespace({\n namespace: opts.binding.namespace,\n artifact: target.name,\n caller: 'injectable',\n });\n }\n\n const registry = MetadataRegistry.getInstance();\n registry.setArtifactMetadata({ target, metadata: opts });\n\n // Discovery happens HERE, at import time. A boot-time filesystem scan cannot see a compiled\n // single-file binary, and a class exists at run time only because something imported it.\n registry.addDiscoveredArtifact({ target });\n\n // The key this class WOULD get; `registerArtifact` overwrites it with the one actually bound.\n registry.setBindingKey({\n target,\n key: ArtifactBindingKeys.resolve({\n target,\n namespace: ArtifactNamespaces.resolve({ type: opts.type }),\n binding: opts.binding,\n }).key,\n isProvisional: true,\n });\n };\n};\n\nexport const service = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.SERVICE, ...opts });\n};\n\nexport const component = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.COMPONENT, ...opts });\n};\n\nexport const configuration = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.CONFIGURATION, ...opts });\n};\n/** Marks a component method as the provider of `key`. `registerArtifacts` binds the key to a lazy provider that resolves the component and calls the method; SINGLETON unless `scope` says otherwise. */\nexport const provide = (opts: { key: string; scope?: TBindingScope }): MethodDecorator => {\n return (target, propertyKey) => {\n MetadataRegistry.getInstance().addProvideMetadata({\n target: target.constructor,\n metadata: {\n methodName: propertyKey,\n key: opts.key,\n ...(opts.scope ? { scope: opts.scope } : {}),\n },\n });\n };\n};\n\n/** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */\nexport const pickRegistrationOptions = <ApplicationType = unknown>(opts: {\n metadata: IArtifactRegistrationOptions<ApplicationType>;\n}): IArtifactRegistrationOptions<ApplicationType> => {\n const { binding, allowOverride, scope, order, when, after } = opts.metadata;\n const registration: IArtifactRegistrationOptions<ApplicationType> = {};\n\n if (binding !== undefined) {\n registration.binding = binding;\n }\n\n if (allowOverride !== undefined) {\n registration.allowOverride = allowOverride;\n }\n\n if (scope !== undefined) {\n registration.scope = scope;\n }\n\n if (order !== undefined) {\n registration.order = order;\n }\n\n if (when !== undefined) {\n registration.when = when;\n }\n\n if (after !== undefined) {\n registration.after = after;\n }\n\n return registration;\n};\n"]}
1
+ {"version":3,"file":"injectable.js","sourceRoot":"","sources":["../../../../src/base/metadata/injectable.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IArtifactMetadata,\n IArtifactRegistrationOptions,\n TBindingScope,\n} from '@/helpers/inversion';\nimport { ArtifactNamespaces, BindingNamespaces } from '@/common/bindings';\nimport { ArtifactTypes, MetadataRegistry } from '@/helpers/inversion';\nimport { ArtifactBindingKeys } from './artifact-keys';\nimport { getError } from '@venizia/ignis-helpers/core';\n\n/** The root stereotype: marks a class as an artifact the application registers, with its registration defaults. Every other stereotype calls it. */\nexport const injectable = <ApplicationType = unknown>(\n opts: IArtifactMetadata<ApplicationType>,\n): ClassDecorator => {\n return (target) => {\n if (!ArtifactTypes.isValid(opts.type)) {\n throw getError({\n message: `[injectable][${target.name}] Invalid artifact type: '${opts.type}' | Expected one of: ${[...ArtifactTypes.SCHEME_SET].join(', ')}`,\n });\n }\n\n // At import time, so the failure lands where the binding is written, not at boot.\n if (opts.binding) {\n BindingNamespaces.assertArtifactNamespace({\n namespace: opts.binding.namespace,\n artifact: target.name,\n caller: 'injectable',\n });\n }\n\n const registry = MetadataRegistry.getInstance();\n registry.setArtifactMetadata({ target, metadata: opts });\n\n // Discovery happens HERE, at import time. A boot-time filesystem scan cannot see a compiled\n // single-file binary, and a class exists at run time only because something imported it.\n registry.addDiscoveredArtifact({ target });\n\n // The key this class WOULD get; `registerArtifact` overwrites it with the one actually bound.\n registry.setBindingKey({\n target,\n key: ArtifactBindingKeys.resolve({\n target,\n namespace: ArtifactNamespaces.resolve({ type: opts.type }),\n binding: opts.binding,\n }).key,\n isProvisional: true,\n });\n };\n};\n\nexport const service = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.SERVICE, ...opts });\n};\n\nexport const component = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.COMPONENT, ...opts });\n};\n\nexport const configuration = <ApplicationType = unknown>(\n opts?: IArtifactRegistrationOptions<ApplicationType>,\n): ClassDecorator => {\n return injectable<ApplicationType>({ type: ArtifactTypes.CONFIGURATION, ...opts });\n};\n/** Marks a component method as the provider of `key`. `registerArtifacts` binds the key to a lazy provider that resolves the component and calls the method; SINGLETON unless `scope` says otherwise. */\nexport const provide = (opts: { key: string; scope?: TBindingScope }): MethodDecorator => {\n return (target, propertyKey) => {\n MetadataRegistry.getInstance().addProvideMetadata({\n target: target.constructor,\n metadata: {\n methodName: propertyKey,\n key: opts.key,\n ...(opts.scope ? { scope: opts.scope } : {}),\n },\n });\n };\n};\n\n/** The registration defaults a stereotype forwards to `@injectable`, copied field by field so an absent option stays absent. */\nexport const pickRegistrationOptions = <ApplicationType = unknown>(opts: {\n metadata: IArtifactRegistrationOptions<ApplicationType>;\n}): IArtifactRegistrationOptions<ApplicationType> => {\n const { binding, allowOverride, scope, order, when, after } = opts.metadata;\n const registration: IArtifactRegistrationOptions<ApplicationType> = {};\n\n if (binding !== undefined) {\n registration.binding = binding;\n }\n\n if (allowOverride !== undefined) {\n registration.allowOverride = allowOverride;\n }\n\n if (scope !== undefined) {\n registration.scope = scope;\n }\n\n if (order !== undefined) {\n registration.order = order;\n }\n\n if (when !== undefined) {\n registration.when = when;\n }\n\n if (after !== undefined) {\n registration.after = after;\n }\n\n return registration;\n};\n"]}
@@ -7,7 +7,7 @@ import { RepositoryTypes } from '../repositories/common/constants.js';
7
7
  import { injectable, pickRegistrationOptions } from './injectable.js';
8
8
  /** Registers a model class with its static schema and relations. */
9
9
  export const model = (metadata) => {
10
- return target => {
10
+ return (target) => {
11
11
  injectable({ type: ArtifactTypes.MODEL, ...pickRegistrationOptions({ metadata }) })(target);
12
12
  const defaultLimit = metadata.settings?.defaultLimit;
13
13
  if (defaultLimit !== undefined && (!Number.isInteger(defaultLimit) || defaultLimit <= 0)) {
@@ -33,7 +33,7 @@ export const model = (metadata) => {
33
33
  };
34
34
  /** Registers a datasource with driver and auto-discovery settings. */
35
35
  export const datasource = (metadata) => {
36
- return target => {
36
+ return (target) => {
37
37
  injectable({
38
38
  type: ArtifactTypes.DATASOURCE,
39
39
  ...pickRegistrationOptions({ metadata: metadata ?? {} }),
@@ -96,7 +96,7 @@ const registerDataSourceInjection = (opts) => {
96
96
  const { target, registry, dataSourceRef, resolvedDataSource } = opts;
97
97
  // Own metadata only: `getInjectMetadata` walks the prototype chain, so a repository extending another @repository class would see the BASE's injection at param[0] and silently resolve the base's dataSource.
98
98
  const ownInjects = Reflect.getOwnMetadata(MetadataKeys.INJECT, target);
99
- const injectAtIndex0 = ownInjects?.find(entry => entry?.index === 0);
99
+ const injectAtIndex0 = ownInjects?.find((entry) => entry?.index === 0);
100
100
  if (injectAtIndex0) {
101
101
  // `@inject({ target })` carries no key; read the one recorded on the class. The function form
102
102
  // resolves through the same helper the container uses, so both paths read one class.
@@ -212,7 +212,7 @@ const applyRepositoryMetadata = (opts) => {
212
212
  registry.setRepositoryMetadata({ target, metadata: { ...metadata, _resolved: resolved } });
213
213
  };
214
214
  export const repository = (metadata) => {
215
- return target => {
215
+ return (target) => {
216
216
  const registry = MetadataRegistry.getInstance();
217
217
  if (!metadata) {
218
218
  applyRepositoryMetadata({
@@ -1 +1 @@
1
- {"version":3,"file":"persistents.js","sourceRoot":"","sources":["../../../../src/base/metadata/persistents.ts"],"names":[],"mappings":"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","sourcesContent":["import { BindingNamespaces } from '@/common/bindings';\nimport type {\n IArtifactRegistrationOptions,\n IDataSourceMetadata,\n IInjectMetadata,\n IModelMetadata,\n IResolvedRepositoryMetadata,\n TRepositoryMetadata,\n} from '@/helpers/inversion';\nimport {\n ArtifactTypes,\n BindingKeys,\n MetadataKeys,\n MetadataRegistry,\n resolveInjectTarget,\n} from '@/helpers/inversion';\nimport { resolveClass, resolveValue } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { IDataSource } from '../datasources';\nimport { isDataSourceClass } from '../datasources';\nimport type { AbstractEntity } from '../models';\nimport { RepositoryTypes } from '../repositories/common/constants';\nimport { injectable, pickRegistrationOptions } from './injectable';\n\n/** Registers a model class with its static schema and relations. */\nexport const model = (metadata: IModelMetadata): ClassDecorator => {\n return target => {\n injectable({ type: ArtifactTypes.MODEL, ...pickRegistrationOptions({ metadata }) })(target);\n\n const defaultLimit = metadata.settings?.defaultLimit;\n if (defaultLimit !== undefined && (!Number.isInteger(defaultLimit) || defaultLimit <= 0)) {\n throw getError({\n message: `[model][${target.name}] Invalid 'defaultLimit' | Expected a positive integer | Got: ${defaultLimit}`,\n });\n }\n\n // Validated at DECORATION time, like defaultLimit: a bad ceiling is a wiring mistake, and\n // catching it at boot beats catching it on the one request that happens to reach the limit.\n const maxLimit = metadata.settings?.maxLimit;\n if (maxLimit !== undefined && (!Number.isInteger(maxLimit) || maxLimit <= 0)) {\n throw getError({\n message: `[model][${target.name}] Invalid 'maxLimit' | Expected a positive integer | Got: ${maxLimit}`,\n });\n }\n\n // Auto-populate AUTHORIZATION_SUBJECT from authorize.principal if not already set\n const principal = metadata.settings?.authorize?.principal;\n if (principal && !Object.hasOwn(target, 'AUTHORIZATION_SUBJECT')) {\n (target as Record<string, unknown>).AUTHORIZATION_SUBJECT = principal;\n }\n\n MetadataRegistry.getInstance().registerModel({ target, metadata });\n };\n};\n\n/** Registers a datasource with driver and auto-discovery settings. */\nexport const datasource = (metadata?: IDataSourceMetadata): ClassDecorator => {\n return target => {\n injectable({\n type: ArtifactTypes.DATASOURCE,\n ...pickRegistrationOptions({ metadata: metadata ?? {} }),\n })(target);\n MetadataRegistry.getInstance().setDataSourceMetadata({ target, metadata });\n };\n};\n\n/** Mirrors the `TRepositoryMetadata` union for JavaScript callers: a known type, a dataSource always, a model exactly when the type is RepositoryTypes.MODEL. */\nconst validateRepositoryMetadata = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(opts: {\n metadata: TRepositoryMetadata<Model, DataSource>;\n target: Function;\n}): void => {\n const { metadata, target } = opts;\n const type = metadata.type ?? RepositoryTypes.MODEL;\n\n if (!RepositoryTypes.isValid(type)) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | Unknown 'type': ${type} | Expected one of: ${[...RepositoryTypes.SCHEME_SET].join(', ')}`,\n });\n }\n\n if (type === RepositoryTypes.MODEL && !metadata.model) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | Missing 'model'`,\n });\n }\n\n if (type === RepositoryTypes.REMOTE && metadata.model) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | A '${RepositoryTypes.REMOTE}' repository takes no 'model'`,\n });\n }\n\n if (!metadata.dataSource) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | Missing 'dataSource'`,\n });\n }\n};\n\n/** Asserts the constructor's first parameter is an AbstractDataSource compatible with what @repository declared. */\nconst validateFirstConstructorParameter = (opts: {\n target: Function;\n firstParamType: Function;\n resolvedDataSource: string | Function;\n}): void => {\n const { target, firstParamType, resolvedDataSource } = opts;\n\n // NOT `instanceof`: two copies of this package give two `AbstractDataSource` classes and the\n // check would be false across them, rejecting a perfectly valid repository at import time.\n const isDataSourceType = isDataSourceClass(firstParamType);\n\n if (!isDataSourceType) {\n throw getError({\n message: `[@repository][${target.name}] Invalid constructor | First parameter must extend AbstractDataSource | Received: '${firstParamType.name}'`,\n });\n }\n\n if (typeof resolvedDataSource !== 'function') {\n return;\n }\n\n const isCompatible =\n firstParamType === resolvedDataSource || resolvedDataSource.prototype instanceof firstParamType;\n\n if (!isCompatible) {\n throw getError({\n message: `[@repository][${target.name}] Invalid constructor | Type mismatch | Constructor expects '${firstParamType.name}' but @repository specifies '${resolvedDataSource.name}'`,\n });\n }\n};\n\n/**\n * Auto-injects dataSource at constructor param[0] unless explicit @inject exists. A class is injected\n * by the class itself, so the container reads the key its registration recorded: a pinned\n * `binding` and a minified class name both resolve. Only a string reference is a key.\n */\nconst registerDataSourceInjection = (opts: {\n target: Function;\n registry: MetadataRegistry;\n dataSourceRef: TRepositoryMetadata['dataSource'];\n resolvedDataSource: string | Function;\n}): void => {\n const { target, registry, dataSourceRef, resolvedDataSource } = opts;\n\n // Own metadata only: `getInjectMetadata` walks the prototype chain, so a repository extending another @repository class would see the BASE's injection at param[0] and silently resolve the base's dataSource.\n const ownInjects: IInjectMetadata[] | undefined = Reflect.getOwnMetadata(\n MetadataKeys.INJECT,\n target,\n );\n const injectAtIndex0 = ownInjects?.find(entry => entry?.index === 0);\n\n if (injectAtIndex0) {\n // `@inject({ target })` carries no key; read the one recorded on the class. The function form\n // resolves through the same helper the container uses, so both paths read one class.\n const injectedTarget = injectAtIndex0.target\n ? resolveInjectTarget({ target: injectAtIndex0.target })\n : undefined;\n const injectKey =\n injectAtIndex0.key ??\n (injectedTarget ? registry.getBindingKey({ target: injectedTarget }) : undefined);\n\n // A class is judged by its brand: its key may sit under any namespace a `binding` pinned, and\n // a provisional key may still change at registration. Only a bare key is judged by its prefix.\n const isDataSourceTarget = injectedTarget\n ? isDataSourceClass(injectedTarget)\n : typeof injectKey === 'string' && injectKey.startsWith(`${BindingNamespaces.DATASOURCE}.`);\n\n if (!isDataSourceTarget) {\n throw getError({\n message: `[@repository][${target.name}] Invalid constructor | First parameter must be a DataSource | Found @inject with key: '${String(injectKey)}' | Expected a key starting with '${BindingNamespaces.DATASOURCE}.' or a DataSource class`,\n });\n }\n\n return;\n }\n\n // Checked only when this decorator writes the injection: an explicit @inject decides for itself.\n // An interface emits `Object` and a type-only class import emits `Function` under tsc (`Object`\n // under bun); neither names the class, so neither is judged.\n const firstParamType = Reflect.getMetadata('design:paramtypes', target)?.[0];\n if (firstParamType && firstParamType !== Object && firstParamType !== Function) {\n validateFirstConstructorParameter({ target, firstParamType, resolvedDataSource });\n }\n\n // The inherited list is the base repository's own, and setInjectMetadata may write straight into it.\n if (!ownInjects) {\n Reflect.defineMetadata(\n MetadataKeys.INJECT,\n [...(registry.getInjectMetadata({ target }) ?? [])],\n target,\n );\n }\n\n const derivedKey = BindingKeys.build({\n namespace: BindingNamespaces.DATASOURCE,\n key: typeof resolvedDataSource === 'string' ? resolvedDataSource : resolvedDataSource.name,\n });\n\n // The class first, decided when the repository is resolved: by then any registration - decorated,\n // `bindingList()`, or `dataSource(X, { binding })` - has recorded its key on the class. The derived\n // key is the fallback for a class nothing recorded, bound by hand under exactly that key.\n registry.setInjectMetadata({\n target,\n index: 0,\n metadata:\n typeof dataSourceRef === 'string'\n ? { key: derivedKey, index: 0, isOptional: false }\n : { target: dataSourceRef, key: derivedKey, index: 0, isOptional: false },\n });\n};\n\n/** Resolves repository metadata and registers bindings for schema auto-discovery. */\nconst resolveRepositoryMetadata = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(opts: {\n metadata: TRepositoryMetadata<Model, DataSource>;\n target: Function;\n registry: MetadataRegistry;\n}): IResolvedRepositoryMetadata<Model, DataSource> => {\n const { metadata, target, registry } = opts;\n\n validateRepositoryMetadata({ metadata, target });\n\n const resolvedDataSource = resolveClass({ ref: metadata.dataSource });\n if (!resolvedDataSource) {\n throw getError({\n message: `[@repository][${target.name}] The dataSource resolver returned nothing at decoration time | An import cycle leaves the datasource class undefined here; import it without the cycle, or name it as a string`,\n });\n }\n\n // No model, so no binding: the datasource owns no schema through this repository.\n if (metadata.type === RepositoryTypes.REMOTE) {\n registerDataSourceInjection({\n target,\n registry,\n dataSourceRef: metadata.dataSource,\n resolvedDataSource,\n });\n return {\n type: RepositoryTypes.REMOTE,\n dataSource: resolvedDataSource,\n operationScope: metadata.operationScope,\n };\n }\n\n const resolvedModel = resolveValue({ value: metadata.model });\n\n registry.registerRepositoryBinding({\n repository: target,\n model: resolvedModel,\n dataSource: resolvedDataSource,\n });\n\n registerDataSourceInjection({\n target,\n registry,\n dataSourceRef: metadata.dataSource,\n resolvedDataSource,\n });\n\n return {\n type: RepositoryTypes.MODEL,\n model: resolvedModel,\n dataSource: resolvedDataSource,\n operationScope: metadata.operationScope,\n };\n};\n\n/** A bare `@repository()` on a subclass reuses the type, model and datasource its nearest decorated parent declared; the registration options (`binding`, `when`, ...) are never inherited, so the subclass registers under its own name. */\nconst inheritRepositoryMetadata = (opts: {\n target: Function;\n registry: MetadataRegistry;\n}): TRepositoryMetadata => {\n // Own metadata does not exist yet at decoration time, so this read walks the prototype chain.\n const inherited = opts.registry.getRepositoryMetadata({ target: opts.target });\n if (!inherited) {\n throw getError({\n message: `[@repository][${opts.target.name}] No metadata given and no decorated repository above it in the prototype chain | pass { model, dataSource } or decorate the parent`,\n });\n }\n\n if (inherited.type === RepositoryTypes.REMOTE) {\n const { type, dataSource, operationScope } = inherited;\n return { type, dataSource, operationScope };\n }\n\n const { type, model: parentModel, dataSource, operationScope } = inherited;\n return { type, model: parentModel, dataSource, operationScope };\n};\n\nconst applyRepositoryMetadata = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(opts: {\n metadata: TRepositoryMetadata<Model, DataSource>;\n registration: IArtifactRegistrationOptions;\n target: Function;\n registry: MetadataRegistry;\n}): void => {\n const { metadata, registration, target, registry } = opts;\n injectable({\n type: ArtifactTypes.REPOSITORY,\n ...pickRegistrationOptions({ metadata: registration }),\n })(target);\n\n const resolved = resolveRepositoryMetadata({ metadata, target, registry });\n\n registry.setRepositoryMetadata({ target, metadata: { ...metadata, _resolved: resolved } });\n};\n\nexport const repository = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(\n metadata?: TRepositoryMetadata<Model, DataSource>,\n): ClassDecorator => {\n return target => {\n const registry = MetadataRegistry.getInstance();\n if (!metadata) {\n applyRepositoryMetadata({\n metadata: inheritRepositoryMetadata({ target, registry }),\n registration: {},\n target,\n registry,\n });\n return;\n }\n\n applyRepositoryMetadata({ metadata, registration: metadata, target, registry });\n };\n};\n"]}
1
+ {"version":3,"file":"persistents.js","sourceRoot":"","sources":["../../../../src/base/metadata/persistents.ts"],"names":[],"mappings":"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","sourcesContent":["import { BindingNamespaces } from '@/common/bindings';\nimport type {\n IArtifactRegistrationOptions,\n IDataSourceMetadata,\n IInjectMetadata,\n IModelMetadata,\n IResolvedRepositoryMetadata,\n TRepositoryMetadata,\n} from '@/helpers/inversion';\nimport {\n ArtifactTypes,\n BindingKeys,\n MetadataKeys,\n MetadataRegistry,\n resolveInjectTarget,\n} from '@/helpers/inversion';\nimport { resolveClass, resolveValue } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { IDataSource } from '../datasources';\nimport { isDataSourceClass } from '../datasources';\nimport type { AbstractEntity } from '../models';\nimport { RepositoryTypes } from '../repositories/common/constants';\nimport { injectable, pickRegistrationOptions } from './injectable';\n\n/** Registers a model class with its static schema and relations. */\nexport const model = (metadata: IModelMetadata): ClassDecorator => {\n return (target) => {\n injectable({ type: ArtifactTypes.MODEL, ...pickRegistrationOptions({ metadata }) })(target);\n\n const defaultLimit = metadata.settings?.defaultLimit;\n if (defaultLimit !== undefined && (!Number.isInteger(defaultLimit) || defaultLimit <= 0)) {\n throw getError({\n message: `[model][${target.name}] Invalid 'defaultLimit' | Expected a positive integer | Got: ${defaultLimit}`,\n });\n }\n\n // Validated at DECORATION time, like defaultLimit: a bad ceiling is a wiring mistake, and\n // catching it at boot beats catching it on the one request that happens to reach the limit.\n const maxLimit = metadata.settings?.maxLimit;\n if (maxLimit !== undefined && (!Number.isInteger(maxLimit) || maxLimit <= 0)) {\n throw getError({\n message: `[model][${target.name}] Invalid 'maxLimit' | Expected a positive integer | Got: ${maxLimit}`,\n });\n }\n\n // Auto-populate AUTHORIZATION_SUBJECT from authorize.principal if not already set\n const principal = metadata.settings?.authorize?.principal;\n if (principal && !Object.hasOwn(target, 'AUTHORIZATION_SUBJECT')) {\n (target as Record<string, unknown>).AUTHORIZATION_SUBJECT = principal;\n }\n\n MetadataRegistry.getInstance().registerModel({ target, metadata });\n };\n};\n\n/** Registers a datasource with driver and auto-discovery settings. */\nexport const datasource = (metadata?: IDataSourceMetadata): ClassDecorator => {\n return (target) => {\n injectable({\n type: ArtifactTypes.DATASOURCE,\n ...pickRegistrationOptions({ metadata: metadata ?? {} }),\n })(target);\n MetadataRegistry.getInstance().setDataSourceMetadata({ target, metadata });\n };\n};\n\n/** Mirrors the `TRepositoryMetadata` union for JavaScript callers: a known type, a dataSource always, a model exactly when the type is RepositoryTypes.MODEL. */\nconst validateRepositoryMetadata = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(opts: {\n metadata: TRepositoryMetadata<Model, DataSource>;\n target: Function;\n}): void => {\n const { metadata, target } = opts;\n const type = metadata.type ?? RepositoryTypes.MODEL;\n\n if (!RepositoryTypes.isValid(type)) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | Unknown 'type': ${type} | Expected one of: ${[...RepositoryTypes.SCHEME_SET].join(', ')}`,\n });\n }\n\n if (type === RepositoryTypes.MODEL && !metadata.model) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | Missing 'model'`,\n });\n }\n\n if (type === RepositoryTypes.REMOTE && metadata.model) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | A '${RepositoryTypes.REMOTE}' repository takes no 'model'`,\n });\n }\n\n if (!metadata.dataSource) {\n throw getError({\n message: `[validateRepositoryMetadata][@repository][${target.name}] Invalid metadata | Missing 'dataSource'`,\n });\n }\n};\n\n/** Asserts the constructor's first parameter is an AbstractDataSource compatible with what @repository declared. */\nconst validateFirstConstructorParameter = (opts: {\n target: Function;\n firstParamType: Function;\n resolvedDataSource: string | Function;\n}): void => {\n const { target, firstParamType, resolvedDataSource } = opts;\n\n // NOT `instanceof`: two copies of this package give two `AbstractDataSource` classes and the\n // check would be false across them, rejecting a perfectly valid repository at import time.\n const isDataSourceType = isDataSourceClass(firstParamType);\n\n if (!isDataSourceType) {\n throw getError({\n message: `[@repository][${target.name}] Invalid constructor | First parameter must extend AbstractDataSource | Received: '${firstParamType.name}'`,\n });\n }\n\n if (typeof resolvedDataSource !== 'function') {\n return;\n }\n\n const isCompatible =\n firstParamType === resolvedDataSource || resolvedDataSource.prototype instanceof firstParamType;\n\n if (!isCompatible) {\n throw getError({\n message: `[@repository][${target.name}] Invalid constructor | Type mismatch | Constructor expects '${firstParamType.name}' but @repository specifies '${resolvedDataSource.name}'`,\n });\n }\n};\n\n/**\n * Auto-injects dataSource at constructor param[0] unless explicit @inject exists. A class is injected\n * by the class itself, so the container reads the key its registration recorded: a pinned\n * `binding` and a minified class name both resolve. Only a string reference is a key.\n */\nconst registerDataSourceInjection = (opts: {\n target: Function;\n registry: MetadataRegistry;\n dataSourceRef: TRepositoryMetadata['dataSource'];\n resolvedDataSource: string | Function;\n}): void => {\n const { target, registry, dataSourceRef, resolvedDataSource } = opts;\n\n // Own metadata only: `getInjectMetadata` walks the prototype chain, so a repository extending another @repository class would see the BASE's injection at param[0] and silently resolve the base's dataSource.\n const ownInjects: IInjectMetadata[] | undefined = Reflect.getOwnMetadata(\n MetadataKeys.INJECT,\n target,\n );\n const injectAtIndex0 = ownInjects?.find((entry) => entry?.index === 0);\n\n if (injectAtIndex0) {\n // `@inject({ target })` carries no key; read the one recorded on the class. The function form\n // resolves through the same helper the container uses, so both paths read one class.\n const injectedTarget = injectAtIndex0.target\n ? resolveInjectTarget({ target: injectAtIndex0.target })\n : undefined;\n const injectKey =\n injectAtIndex0.key ??\n (injectedTarget ? registry.getBindingKey({ target: injectedTarget }) : undefined);\n\n // A class is judged by its brand: its key may sit under any namespace a `binding` pinned, and\n // a provisional key may still change at registration. Only a bare key is judged by its prefix.\n const isDataSourceTarget = injectedTarget\n ? isDataSourceClass(injectedTarget)\n : typeof injectKey === 'string' && injectKey.startsWith(`${BindingNamespaces.DATASOURCE}.`);\n\n if (!isDataSourceTarget) {\n throw getError({\n message: `[@repository][${target.name}] Invalid constructor | First parameter must be a DataSource | Found @inject with key: '${String(injectKey)}' | Expected a key starting with '${BindingNamespaces.DATASOURCE}.' or a DataSource class`,\n });\n }\n\n return;\n }\n\n // Checked only when this decorator writes the injection: an explicit @inject decides for itself.\n // An interface emits `Object` and a type-only class import emits `Function` under tsc (`Object`\n // under bun); neither names the class, so neither is judged.\n const firstParamType = Reflect.getMetadata('design:paramtypes', target)?.[0];\n if (firstParamType && firstParamType !== Object && firstParamType !== Function) {\n validateFirstConstructorParameter({ target, firstParamType, resolvedDataSource });\n }\n\n // The inherited list is the base repository's own, and setInjectMetadata may write straight into it.\n if (!ownInjects) {\n Reflect.defineMetadata(\n MetadataKeys.INJECT,\n [...(registry.getInjectMetadata({ target }) ?? [])],\n target,\n );\n }\n\n const derivedKey = BindingKeys.build({\n namespace: BindingNamespaces.DATASOURCE,\n key: typeof resolvedDataSource === 'string' ? resolvedDataSource : resolvedDataSource.name,\n });\n\n // The class first, decided when the repository is resolved: by then any registration - decorated,\n // `bindingList()`, or `dataSource(X, { binding })` - has recorded its key on the class. The derived\n // key is the fallback for a class nothing recorded, bound by hand under exactly that key.\n registry.setInjectMetadata({\n target,\n index: 0,\n metadata:\n typeof dataSourceRef === 'string'\n ? { key: derivedKey, index: 0, isOptional: false }\n : { target: dataSourceRef, key: derivedKey, index: 0, isOptional: false },\n });\n};\n\n/** Resolves repository metadata and registers bindings for schema auto-discovery. */\nconst resolveRepositoryMetadata = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(opts: {\n metadata: TRepositoryMetadata<Model, DataSource>;\n target: Function;\n registry: MetadataRegistry;\n}): IResolvedRepositoryMetadata<Model, DataSource> => {\n const { metadata, target, registry } = opts;\n\n validateRepositoryMetadata({ metadata, target });\n\n const resolvedDataSource = resolveClass({ ref: metadata.dataSource });\n if (!resolvedDataSource) {\n throw getError({\n message: `[@repository][${target.name}] The dataSource resolver returned nothing at decoration time | An import cycle leaves the datasource class undefined here; import it without the cycle, or name it as a string`,\n });\n }\n\n // No model, so no binding: the datasource owns no schema through this repository.\n if (metadata.type === RepositoryTypes.REMOTE) {\n registerDataSourceInjection({\n target,\n registry,\n dataSourceRef: metadata.dataSource,\n resolvedDataSource,\n });\n return {\n type: RepositoryTypes.REMOTE,\n dataSource: resolvedDataSource,\n operationScope: metadata.operationScope,\n };\n }\n\n const resolvedModel = resolveValue({ value: metadata.model });\n\n registry.registerRepositoryBinding({\n repository: target,\n model: resolvedModel,\n dataSource: resolvedDataSource,\n });\n\n registerDataSourceInjection({\n target,\n registry,\n dataSourceRef: metadata.dataSource,\n resolvedDataSource,\n });\n\n return {\n type: RepositoryTypes.MODEL,\n model: resolvedModel,\n dataSource: resolvedDataSource,\n operationScope: metadata.operationScope,\n };\n};\n\n/** A bare `@repository()` on a subclass reuses the type, model and datasource its nearest decorated parent declared; the registration options (`binding`, `when`, ...) are never inherited, so the subclass registers under its own name. */\nconst inheritRepositoryMetadata = (opts: {\n target: Function;\n registry: MetadataRegistry;\n}): TRepositoryMetadata => {\n // Own metadata does not exist yet at decoration time, so this read walks the prototype chain.\n const inherited = opts.registry.getRepositoryMetadata({ target: opts.target });\n if (!inherited) {\n throw getError({\n message: `[@repository][${opts.target.name}] No metadata given and no decorated repository above it in the prototype chain | pass { model, dataSource } or decorate the parent`,\n });\n }\n\n if (inherited.type === RepositoryTypes.REMOTE) {\n const { type, dataSource, operationScope } = inherited;\n return { type, dataSource, operationScope };\n }\n\n const { type, model: parentModel, dataSource, operationScope } = inherited;\n return { type, model: parentModel, dataSource, operationScope };\n};\n\nconst applyRepositoryMetadata = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(opts: {\n metadata: TRepositoryMetadata<Model, DataSource>;\n registration: IArtifactRegistrationOptions;\n target: Function;\n registry: MetadataRegistry;\n}): void => {\n const { metadata, registration, target, registry } = opts;\n injectable({\n type: ArtifactTypes.REPOSITORY,\n ...pickRegistrationOptions({ metadata: registration }),\n })(target);\n\n const resolved = resolveRepositoryMetadata({ metadata, target, registry });\n\n registry.setRepositoryMetadata({ target, metadata: { ...metadata, _resolved: resolved } });\n};\n\nexport const repository = <\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n>(\n metadata?: TRepositoryMetadata<Model, DataSource>,\n): ClassDecorator => {\n return (target) => {\n const registry = MetadataRegistry.getInstance();\n if (!metadata) {\n applyRepositoryMetadata({\n metadata: inheritRepositoryMetadata({ target, registry }),\n registration: {},\n target,\n registry,\n });\n return;\n }\n\n applyRepositoryMetadata({ metadata, registration: metadata, target, registry });\n };\n};\n"]}