@venizia/ignis-kernel 0.4.0 → 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 (139) hide show
  1. package/dist/cjs/base/applications/abstract.js +2 -2
  2. package/dist/cjs/base/applications/abstract.js.map +1 -1
  3. package/dist/cjs/base/applications/artifact-group.js +1 -1
  4. package/dist/cjs/base/applications/artifact-group.js.map +1 -1
  5. package/dist/cjs/base/applications/artifact-index.js +11 -11
  6. package/dist/cjs/base/applications/artifact-index.js.map +1 -1
  7. package/dist/cjs/base/applications/boot-sequence.js +1 -1
  8. package/dist/cjs/base/applications/boot-sequence.js.map +1 -1
  9. package/dist/cjs/base/applications/rest.js +5 -5
  10. package/dist/cjs/base/applications/rest.js.map +1 -1
  11. package/dist/cjs/base/auth/authenticate/common/codecs.js +2 -2
  12. package/dist/cjs/base/auth/authenticate/common/codecs.js.map +1 -1
  13. package/dist/cjs/base/auth/authenticate/providers/authentication.provider.js +1 -1
  14. package/dist/cjs/base/auth/authenticate/providers/authentication.provider.js.map +1 -1
  15. package/dist/cjs/base/auth/authenticate/strategies/strategy-registry.js +1 -1
  16. package/dist/cjs/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
  17. package/dist/cjs/base/auth/authorize/builders/grant.builder.js +12 -12
  18. package/dist/cjs/base/auth/authorize/builders/grant.builder.js.map +1 -1
  19. package/dist/cjs/base/auth/authorize/builders/permission.builder.js +1 -1
  20. package/dist/cjs/base/auth/authorize/builders/permission.builder.js.map +1 -1
  21. package/dist/cjs/base/auth/authorize/builders/policy.builder.js +1 -1
  22. package/dist/cjs/base/auth/authorize/builders/policy.builder.js.map +1 -1
  23. package/dist/cjs/base/auth/authorize/common/constants/authorization.d.ts.map +1 -1
  24. package/dist/cjs/base/auth/authorize/common/constants/authorization.js +2 -2
  25. package/dist/cjs/base/auth/authorize/common/constants/authorization.js.map +1 -1
  26. package/dist/cjs/base/auth/authorize/enforcers/enforcer-registry.js +1 -1
  27. package/dist/cjs/base/auth/authorize/enforcers/enforcer-registry.js.map +1 -1
  28. package/dist/cjs/base/auth/authorize/providers/authorization.provider.js +3 -3
  29. package/dist/cjs/base/auth/authorize/providers/authorization.provider.js.map +1 -1
  30. package/dist/cjs/base/controllers/factory/controller.d.ts +2 -2
  31. package/dist/cjs/base/controllers/factory/controller.d.ts.map +1 -1
  32. package/dist/cjs/base/controllers/factory/controller.js +1 -0
  33. package/dist/cjs/base/controllers/factory/controller.js.map +1 -1
  34. package/dist/cjs/base/controllers/factory/crud/abstract.d.ts +1 -1
  35. package/dist/cjs/base/controllers/factory/crud/abstract.d.ts.map +1 -1
  36. package/dist/cjs/base/controllers/factory/crud/abstract.js.map +1 -1
  37. package/dist/cjs/base/controllers/factory/definition.js +1 -1
  38. package/dist/cjs/base/controllers/factory/definition.js.map +1 -1
  39. package/dist/cjs/base/controllers/rest/extras.js +5 -5
  40. package/dist/cjs/base/controllers/rest/extras.js.map +1 -1
  41. package/dist/cjs/base/metadata/injectable.js +1 -1
  42. package/dist/cjs/base/metadata/injectable.js.map +1 -1
  43. package/dist/cjs/base/metadata/persistents.js +4 -4
  44. package/dist/cjs/base/metadata/persistents.js.map +1 -1
  45. package/dist/cjs/base/metadata/routes/controller.js +1 -1
  46. package/dist/cjs/base/metadata/routes/controller.js.map +1 -1
  47. package/dist/cjs/base/middlewares/app-error/app-error.middleware.js +3 -3
  48. package/dist/cjs/base/middlewares/app-error/app-error.middleware.js.map +1 -1
  49. package/dist/cjs/base/middlewares/app-error/zod.handler.js +2 -2
  50. package/dist/cjs/base/middlewares/app-error/zod.handler.js.map +1 -1
  51. package/dist/cjs/base/middlewares/form-body/form-body.middleware.js +2 -2
  52. package/dist/cjs/base/middlewares/form-body/form-body.middleware.js.map +1 -1
  53. package/dist/cjs/base/middlewares/not-found/not-found.middleware.js.map +1 -1
  54. package/dist/cjs/base/models/common/utilities.js +1 -1
  55. package/dist/cjs/base/models/common/utilities.js.map +1 -1
  56. package/dist/cjs/base/repositories/common/types/contracts.d.ts +17 -17
  57. package/dist/cjs/base/repositories/common/types/contracts.d.ts.map +1 -1
  58. package/dist/cjs/base/repositories/common/types/contracts.js.map +1 -1
  59. package/dist/cjs/base/repositories/core/abstract.d.ts +17 -17
  60. package/dist/cjs/base/repositories/core/abstract.d.ts.map +1 -1
  61. package/dist/cjs/base/repositories/core/abstract.js +4 -3
  62. package/dist/cjs/base/repositories/core/abstract.js.map +1 -1
  63. package/dist/cjs/helpers/inversion/mixins/model.mixin.js +1 -1
  64. package/dist/cjs/helpers/inversion/mixins/model.mixin.js.map +1 -1
  65. package/dist/cjs/helpers/inversion/mixins/repository.mixin.js +1 -1
  66. package/dist/cjs/helpers/inversion/mixins/repository.mixin.js.map +1 -1
  67. package/dist/cjs/repository.d.ts +1 -1
  68. package/dist/cjs/repository.d.ts.map +1 -1
  69. package/dist/cjs/repository.js.map +1 -1
  70. package/dist/esm/base/applications/abstract.js +2 -2
  71. package/dist/esm/base/applications/abstract.js.map +1 -1
  72. package/dist/esm/base/applications/artifact-group.js +1 -1
  73. package/dist/esm/base/applications/artifact-group.js.map +1 -1
  74. package/dist/esm/base/applications/artifact-index.js +11 -11
  75. package/dist/esm/base/applications/artifact-index.js.map +1 -1
  76. package/dist/esm/base/applications/boot-sequence.js +1 -1
  77. package/dist/esm/base/applications/boot-sequence.js.map +1 -1
  78. package/dist/esm/base/applications/rest.js +5 -5
  79. package/dist/esm/base/applications/rest.js.map +1 -1
  80. package/dist/esm/base/auth/authenticate/common/codecs.js +2 -2
  81. package/dist/esm/base/auth/authenticate/common/codecs.js.map +1 -1
  82. package/dist/esm/base/auth/authenticate/providers/authentication.provider.js +1 -1
  83. package/dist/esm/base/auth/authenticate/providers/authentication.provider.js.map +1 -1
  84. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js +1 -1
  85. package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
  86. package/dist/esm/base/auth/authorize/builders/grant.builder.js +12 -12
  87. package/dist/esm/base/auth/authorize/builders/grant.builder.js.map +1 -1
  88. package/dist/esm/base/auth/authorize/builders/permission.builder.js +1 -1
  89. package/dist/esm/base/auth/authorize/builders/permission.builder.js.map +1 -1
  90. package/dist/esm/base/auth/authorize/builders/policy.builder.js +1 -1
  91. package/dist/esm/base/auth/authorize/builders/policy.builder.js.map +1 -1
  92. package/dist/esm/base/auth/authorize/common/constants/authorization.d.ts.map +1 -1
  93. package/dist/esm/base/auth/authorize/common/constants/authorization.js +2 -2
  94. package/dist/esm/base/auth/authorize/common/constants/authorization.js.map +1 -1
  95. package/dist/esm/base/auth/authorize/enforcers/enforcer-registry.js +1 -1
  96. package/dist/esm/base/auth/authorize/enforcers/enforcer-registry.js.map +1 -1
  97. package/dist/esm/base/auth/authorize/providers/authorization.provider.js +3 -3
  98. package/dist/esm/base/auth/authorize/providers/authorization.provider.js.map +1 -1
  99. package/dist/esm/base/controllers/factory/controller.d.ts +2 -2
  100. package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
  101. package/dist/esm/base/controllers/factory/controller.js +1 -0
  102. package/dist/esm/base/controllers/factory/controller.js.map +1 -1
  103. package/dist/esm/base/controllers/factory/crud/abstract.d.ts +1 -1
  104. package/dist/esm/base/controllers/factory/crud/abstract.d.ts.map +1 -1
  105. package/dist/esm/base/controllers/factory/crud/abstract.js.map +1 -1
  106. package/dist/esm/base/controllers/factory/definition.js +1 -1
  107. package/dist/esm/base/controllers/factory/definition.js.map +1 -1
  108. package/dist/esm/base/controllers/rest/extras.js +5 -5
  109. package/dist/esm/base/controllers/rest/extras.js.map +1 -1
  110. package/dist/esm/base/metadata/injectable.js +1 -1
  111. package/dist/esm/base/metadata/injectable.js.map +1 -1
  112. package/dist/esm/base/metadata/persistents.js +4 -4
  113. package/dist/esm/base/metadata/persistents.js.map +1 -1
  114. package/dist/esm/base/metadata/routes/controller.js +1 -1
  115. package/dist/esm/base/metadata/routes/controller.js.map +1 -1
  116. package/dist/esm/base/middlewares/app-error/app-error.middleware.js +3 -3
  117. package/dist/esm/base/middlewares/app-error/app-error.middleware.js.map +1 -1
  118. package/dist/esm/base/middlewares/app-error/zod.handler.js +2 -2
  119. package/dist/esm/base/middlewares/app-error/zod.handler.js.map +1 -1
  120. package/dist/esm/base/middlewares/form-body/form-body.middleware.js +2 -2
  121. package/dist/esm/base/middlewares/form-body/form-body.middleware.js.map +1 -1
  122. package/dist/esm/base/middlewares/not-found/not-found.middleware.js.map +1 -1
  123. package/dist/esm/base/models/common/utilities.js +1 -1
  124. package/dist/esm/base/models/common/utilities.js.map +1 -1
  125. package/dist/esm/base/repositories/common/types/contracts.d.ts +17 -17
  126. package/dist/esm/base/repositories/common/types/contracts.d.ts.map +1 -1
  127. package/dist/esm/base/repositories/common/types/contracts.js.map +1 -1
  128. package/dist/esm/base/repositories/core/abstract.d.ts +17 -17
  129. package/dist/esm/base/repositories/core/abstract.d.ts.map +1 -1
  130. package/dist/esm/base/repositories/core/abstract.js +4 -3
  131. package/dist/esm/base/repositories/core/abstract.js.map +1 -1
  132. package/dist/esm/helpers/inversion/mixins/model.mixin.js +1 -1
  133. package/dist/esm/helpers/inversion/mixins/model.mixin.js.map +1 -1
  134. package/dist/esm/helpers/inversion/mixins/repository.mixin.js +1 -1
  135. package/dist/esm/helpers/inversion/mixins/repository.mixin.js.map +1 -1
  136. package/dist/esm/repository.d.ts +1 -1
  137. package/dist/esm/repository.d.ts.map +1 -1
  138. package/dist/esm/repository.js.map +1 -1
  139. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/base/applications/rest.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TBindingNamespace } from '@/common/bindings';\nimport { ArtifactNamespaces, BindingNamespaces, CoreBindings } from '@/common/bindings';\nimport type { Binding, TBindingScope } from '@/helpers/inversion';\nimport { BindingScopes, MetadataRegistry } from '@/helpers/inversion';\nimport { OpenAPIHono } from '@hono/zod-openapi';\nimport type { AnyType, IConfigurable, TClass, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport {\n executeWithPerformanceMeasure,\n getError,\n RequestIdGenerator,\n RetryHelper,\n} from '@venizia/ignis-helpers/core';\nimport type { Env, Schema } from 'hono';\nimport { showRoutes as showApplicationRoutes } from 'hono/dev';\nimport { bodyLimit } from 'hono/body-limit';\nimport { requestId } from 'hono/request-id';\nimport type { BaseComponent } from '../components';\nimport { ArtifactBindingKeys } from '../metadata/artifact-keys';\nimport { RestComponent } from '../components/controller/rest/rest.component';\nimport type { BaseConfiguration } from '../configurations';\nimport { ControllerTransports } from '../controllers/common/constants';\nimport type { IDataSource } from '../datasources';\nimport { BaseAppErrorMiddleware } from '../middlewares/app-error/app-error.middleware';\nimport { RequestErrors } from '../middlewares/common/errors';\nimport { notFoundHandler } from '../middlewares/not-found/not-found.middleware';\nimport type { TMixinOpts } from '../mixins/common';\nimport type { IRepository } from '../repositories';\nimport type { IService } from '../services';\nimport { AbstractApplication } from './abstract';\nimport { ArtifactIndexHelper } from './artifact-index';\nimport type { IBootSequenceStep } from './boot-sequence';\nimport { BootSteps } from './boot-sequence';\nimport type { IApplicationConfigs, IBodyLimitOptions, TArtifactIndexInput } from './common';\n\ninterface IRegisterDynamicBindingsOptions<T extends IConfigurable = IConfigurable> {\n namespace: TBindingNamespace;\n\n onBeforeConfigure?: (opts: { binding: Binding<T> }) => Promise<void>;\n onAfterConfigure?: (opts: { binding: Binding<T>; instance: T }) => Promise<void>;\n}\n\n/** Adds the `OpenAPIHono` router surface on top of `AbstractApplication` - no listening server, so this is the layer a browser Worker or gRPC-only host can extend without pulling in `Bun.serve` / `@hono/node-server`. */\nexport abstract class RestApplication<\n AppEnv extends Env = Env,\n AppSchema extends Schema = {},\n BasePath extends string = '/',\n> extends AbstractApplication {\n private registeredBindings: Record<string, Set<string>> = {};\n private artifactOptions = new Map<string, object>();\n\n /** The router, and nothing else. What runtime is underneath and what socket is bound are `ServerApplication`'s to know - a browser Worker has neither, and carrying the union here made `RuntimeModules.detect()` answer `'node'` inside a Worker. */\n protected server: { hono: OpenAPIHono<AppEnv, AppSchema, BasePath> };\n\n protected rootRouter: OpenAPIHono<AppEnv, AppSchema, BasePath>;\n protected readonly requestIdGenerator: RequestIdGenerator;\n\n /** A copy of the `bodyLimit` the default stack installed, absent until `registerDefaultMiddlewares()` ran. */\n private installedBodyLimit?: { options?: IBodyLimitOptions };\n\n constructor(opts: { scope: string; config: IApplicationConfigs }) {\n super(opts);\n\n // A config built from the environment can lose `path.base` at run time; the router would only fail later, inside `route()`, with a message that names nothing.\n if (typeof this.configs.path?.base !== 'string') {\n throw getError({\n message: `[${opts.scope}] configs.path.base must be a string | value: ${String(this.configs.path?.base)} | an empty string mounts the application at the root`,\n });\n }\n\n // The index signature accepts any key, so a leftover `strictPath` would compile and be ignored.\n if (this.configs.strictPath !== undefined) {\n throw getError({\n message: `[${opts.scope}] configs.strictPath was removed | value: ${String(this.configs.strictPath)} | Use configs.path.isStrict`,\n });\n }\n\n this.requestIdGenerator = new RequestIdGenerator({ scope: opts.scope });\n\n const strict = this.configs.path.isStrict ?? true;\n const honoServer = new OpenAPIHono<AppEnv, AppSchema, BasePath>({ strict });\n this.rootRouter = new OpenAPIHono({ strict });\n\n this.server = { hono: honoServer };\n }\n\n getRootRouter(): OpenAPIHono<AppEnv, AppSchema, BasePath> {\n return this.rootRouter;\n }\n\n getServer(): OpenAPIHono<AppEnv, AppSchema, BasePath> {\n return this.server.hono;\n }\n\n protected override registerCoreBindings() {\n super.registerCoreBindings();\n\n this.bind<typeof this.server>({\n key: CoreBindings.APPLICATION_SERVER,\n }).toProvider(_ => this.server);\n this.bind<typeof this.rootRouter>({\n key: CoreBindings.APPLICATION_ROOT_ROUTER,\n }).toProvider(_ => this.rootRouter);\n }\n\n /** The correlation id every host stamps - see {@link RequestIdGenerator} for why `crypto.randomUUID` is refused. */\n protected generateRequestId(): string {\n return this.requestIdGenerator.nextId();\n }\n\n /** The error handler the default stack installs. `@venizia/ignis` overrides it to swap in the `ErrorPrettier`-backed formatter, which reaches `node:util` and so cannot live here. */\n protected buildErrorMiddleware(): BaseAppErrorMiddleware {\n const environment = this.configs.error?.environment;\n\n return new BaseAppErrorMiddleware({\n logger: this.logger,\n rootKey: this.configs.error?.rootKey ?? undefined,\n // Spread, not `environment: () => environment`: the option's PRESENCE is what claims this host\n // has an ambient environment at all, so an unset config must leave it absent.\n ...(environment === undefined ? {} : { environment: () => environment }),\n });\n }\n\n /**\n * The three registrations every host needs: request id, error envelope, JSON 404 - without them a\n * thrown `ApplicationError` is a generic 500, a 404 is `text/plain`, and no response carries a request id.\n * Registered before `initialize()`, so an application's own handlers still win.\n */\n protected registerDefaultMiddlewares(): ValueOrPromise<void> {\n const server = this.getServer();\n\n server.use(requestId({ generator: () => this.generateRequestId() }));\n\n // Ahead of every middleware a host adds after this one, so none of them buffers a body over it.\n const bodyLimitOptions = this.configs.middlewares?.bodyLimit;\n this.installedBodyLimit = { options: this.toInstalledBodyLimit({ options: bodyLimitOptions }) };\n\n if (bodyLimitOptions && bodyLimitOptions.enable !== false) {\n const { maxSize, path, onError } = bodyLimitOptions;\n\n if (typeof maxSize !== 'number' || !Number.isFinite(maxSize) || maxSize < 0) {\n throw getError({\n message: `[registerDefaultMiddlewares] configs.middlewares.bodyLimit.maxSize must be a non-negative number of bytes | value: ${String(maxSize)}`,\n });\n }\n\n const limiter = bodyLimit({\n maxSize,\n onError:\n onError ??\n (() => {\n throw getError({\n error: RequestErrors.BODY_TOO_LARGE,\n message: `Request body exceeds the maximum of ${maxSize} bytes`,\n });\n }),\n });\n\n if (path) {\n server.use(path, limiter);\n } else {\n server.use(limiter);\n }\n }\n\n server.onError(this.buildErrorMiddleware().value());\n server.notFound(notFoundHandler({ logger: this.logger }));\n }\n\n /** What a `bodyLimit` config installs: nothing when absent or disabled, else a copy, so a later in-place edit shows. */\n private toInstalledBodyLimit(opts: {\n options?: IBodyLimitOptions;\n }): IBodyLimitOptions | undefined {\n const { options } = opts;\n\n if (!options || options.enable === false) {\n return undefined;\n }\n\n return { ...options };\n }\n\n private isSameBodyLimit(opts: { left?: IBodyLimitOptions; right?: IBodyLimitOptions }): boolean {\n const { left, right } = opts;\n\n if (!left || !right) {\n return left === right;\n }\n\n const keys = new Set([...Object.keys(left), ...Object.keys(right)]);\n for (const key of keys) {\n if (!Object.is(left[key], right[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * `configs.middlewares` is read by `registerDefaultMiddlewares()`, which runs before `staticConfigure()`.\n * A limit assigned in a boot hook would read back as configured while every request ran unlimited.\n */\n private assertBodyLimitUnchanged(opts: { step: string }): void {\n if (!this.installedBodyLimit) {\n return;\n }\n\n const installed = this.installedBodyLimit.options;\n const current = this.toInstalledBodyLimit({ options: this.configs.middlewares?.bodyLimit });\n\n if (this.isSameBodyLimit({ left: installed, right: current })) {\n return;\n }\n\n throw getError({\n message: `[${opts.step}] configs.middlewares.bodyLimit changed after registerDefaultMiddlewares() installed it | installed maxSize: ${installed?.maxSize ?? 'none'} | now maxSize: ${current?.maxSize ?? 'none'} | Pass it through the constructor config: new Application({ config: { middlewares: { bodyLimit } } })`,\n });\n }\n\n /**\n * The artifact order, stated once: datasources before the repositories that auto-resolve them,\n * components before the controllers they may contribute. `BaseApplication` splices its server-only\n * steps around these by name instead of rewriting the list.\n */\n protected getBootSequence(): IBootSequenceStep[] {\n return [\n {\n name: BootSteps.STATIC_CONFIGURE,\n run: async () => {\n // Declared `void`, but an override may be async; the step has always waited on it.\n await Promise.resolve(this.staticConfigure());\n this.assertBodyLimitUnchanged({ step: BootSteps.STATIC_CONFIGURE });\n },\n },\n { name: BootSteps.REGISTER_ARTIFACTS, run: () => this.registerConfiguredArtifacts() },\n {\n name: BootSteps.PRE_CONFIGURE,\n run: async () => {\n await this.runApplicationHook({\n name: BootSteps.PRE_CONFIGURE,\n hook: () => this.preConfigure(),\n });\n this.assertBodyLimitUnchanged({ step: BootSteps.PRE_CONFIGURE });\n },\n },\n {\n name: BootSteps.REGISTER_CONFIGURATIONS,\n run: () => this.registerConfigurations(),\n },\n { name: BootSteps.REGISTER_DATA_SOURCES, run: () => this.registerDataSources() },\n { name: BootSteps.REGISTER_COMPONENTS, run: () => this.registerComponents() },\n {\n name: BootSteps.REGISTER_CONTRIBUTED_DATA_SOURCES,\n run: () => this.registerContributedDataSources(),\n },\n { name: BootSteps.REGISTER_CONTROLLERS, run: () => this.registerControllers() },\n {\n name: BootSteps.POST_CONFIGURE,\n run: () =>\n this.runApplicationHook({\n name: BootSteps.POST_CONFIGURE,\n hook: () => this.postConfigure(),\n }),\n },\n { name: BootSteps.VERIFY_BINDINGS, run: () => this.verifyBindings() },\n ];\n }\n\n async initialize(): Promise<void> {\n await this.runBootSequence({ steps: this.getBootSequence() });\n }\n\n /** The application hook currently running, so `registerArtifact` can tell a hand registration inside `preConfigure`/`postConfigure` from one the index step made. */\n private runningApplicationHook: string | undefined;\n\n private async runApplicationHook(opts: {\n name: string;\n hook: () => ValueOrPromise<void>;\n }): Promise<void> {\n this.runningApplicationHook = opts.name;\n try {\n await opts.hook();\n } finally {\n this.runningApplicationHook = undefined;\n }\n }\n\n /**\n * Bound keys carrying one of `tags` that nothing has resolved since the counts were last reset.\n * The counter answers \"who was read\", never \"who is dead\" - an unread binding may be an\n * allow-list entry or a technical floor, and only the application can tell those apart.\n *\n * Counting is off by default. Call `startResolutionCounting()` after `initialize()` and run the\n * traffic that exercises the application, then read this.\n */\n getUnresolvedBindings(opts?: { tags?: string[] }): string[] {\n if (!this.hasStartedResolutionCounting) {\n throw getError({\n message: `[${this.getUnresolvedBindings.name}] Resolution counting never started | Call startResolutionCounting() after initialize(), run the traffic that exercises the application, then read this - without it every binding would be reported unresolved`,\n });\n }\n\n const tags = opts?.tags ?? [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY];\n const counts = this.getResolutionCounts();\n const unresolved: string[] = [];\n\n for (const tag of tags) {\n const bindings = this.findByTag({ tag });\n for (const binding of bindings) {\n if (counts.has(binding.key)) {\n continue;\n }\n\n unresolved.push(binding.key);\n }\n }\n\n return unresolved;\n }\n\n /** `bootChecks.binding.doVerify`: resolve every service and repository once, collect every failure, throw once with the whole list - a made-up `@inject` key or a dependency a `when` excluded then fails the boot, not the first request. */\n protected verifyBindings(): void {\n if (!this.configs.bootChecks?.binding?.doVerify) {\n return;\n }\n\n const logger = this.logger.for(this.verifyBindings.name);\n const tags = [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY];\n const failures: string[] = [];\n let verified = 0;\n\n for (const tag of tags) {\n const bindings = this.findByTag({ tag });\n for (const binding of bindings) {\n try {\n this.get({ key: binding.key });\n verified += 1;\n } catch (error) {\n failures.push(\n `${binding.key}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n if (failures.length > 0) {\n throw getError({\n message: `[${this.verifyBindings.name}] ${failures.length} binding(s) cannot be resolved | ${failures.join(' | ')}`,\n });\n }\n\n logger.info('Every service and repository binding resolves | verified: %d', verified);\n }\n\n /** One measured log line per step, and a failure names its step before rethrowing, so a hung or failed boot is attributable without reading the sequence. */\n protected async runBootSequence(opts: { steps: IBootSequenceStep[] }): Promise<void> {\n const { steps } = opts;\n const logger = this.logger.for(this.initialize.name);\n const t = performance.now();\n\n const stepsEntries = steps.entries();\n for (const [index, step] of stepsEntries) {\n try {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.initialize.name,\n description: `Boot step ${index + 1}/${steps.length} ${step.name}`,\n task: () => step.run(),\n });\n } catch (error) {\n logger.error(\n 'Boot step failed | step: %s (%d/%d) | error: %s',\n step.name,\n index + 1,\n steps.length,\n error,\n );\n throw error;\n }\n }\n\n logger.info(\n 'Boot sequence complete | %d step(s) | Took: %s (ms) | %s',\n steps.length,\n performance.now() - t,\n steps.map(step => step.name).join(' -> '),\n );\n }\n\n protected inspectRoutes() {\n const t = performance.now();\n const shouldShowRoutes = this.configs?.debug?.shouldShowRoutes ?? false;\n\n if (!shouldShowRoutes) {\n return;\n }\n\n this.logger.for(this.inspectRoutes.name).info('START | Inspect all application route(s)');\n showApplicationRoutes(this.getServer());\n this.logger\n .for(this.inspectRoutes.name)\n .info('DONE | Inspect all application route(s) | Took: %s (ms)', performance.now() - t);\n }\n\n /**\n * `configured` is the drain's state, mutated in place: a fresh `Set` gives a one-shot complete\n * drain (`RestComponent`); `registerDynamicBindings` passes its persistent per-namespace `Set`,\n * which is why a second sweep touches only what the first one missed.\n */\n async drainByTag<T>(opts: {\n tag: string;\n configured: Set<string>;\n onEach: (opts: { binding: Binding<T> }) => Promise<void>;\n }): Promise<void> {\n const { tag, configured, onEach } = opts;\n\n // A whole batch is drained before re-scanning: the re-scan exists only to pick up bindings a\n // `configure()` added, and asking after every single item makes boot N+1 full scans of the\n // binding map - 3.5ms at 200 controllers, against 0.04ms for this shape.\n let bindings = this.findByTag<T>({ tag, exclude: configured });\n\n while (bindings.length > 0) {\n for (const binding of bindings) {\n // Within a batch a nested `configure()` may already have taken this one.\n if (configured.has(binding.key)) {\n continue;\n }\n\n await onEach({ binding });\n configured.add(binding.key);\n }\n\n // Re-fetch excluding already configured - picks up dynamically added bindings\n bindings = this.findByTag<T>({ tag, exclude: configured });\n }\n }\n\n protected async registerDynamicBindings<T extends IConfigurable = IConfigurable>(\n opts: IRegisterDynamicBindingsOptions<T>,\n ): Promise<void> {\n const logger = this.logger.for(this.registerDynamicBindings.name);\n const { namespace, onBeforeConfigure, onAfterConfigure } = opts;\n\n if (!this.registeredBindings[namespace]) {\n this.registeredBindings[namespace] = new Set<string>();\n }\n const configured = this.registeredBindings[namespace];\n\n await this.drainByTag<T>({\n tag: namespace,\n configured,\n onEach: async ({ binding }) => {\n if (onBeforeConfigure) {\n await onBeforeConfigure({ binding });\n }\n\n const instance = this.get<T>({ key: binding.key, isOptional: false });\n if (!instance) {\n logger.debug('No binding instance | namespace: %s | key: %s', namespace, binding.key);\n return;\n }\n\n if (typeof (instance as Partial<IConfigurable>)?.configure === 'function') {\n const options = this.artifactOptions.get(binding.key);\n await (instance as IConfigurable).configure(options);\n }\n\n // Marked before the after-hook runs, so the hook sees its own binding as configured.\n configured.add(binding.key);\n\n if (onAfterConfigure) {\n await onAfterConfigure({ binding, instance });\n }\n },\n });\n }\n\n /** The same-key guard behind every artifact registration (`component`/`controller`/`service`/`repository`/`dataSource`). `allowOverride` defaults true to match `bind()`'s overwrite behavior; `allowOverride: false` on one registration, or `bootChecks.binding.allowOverride: false` for the whole application, opts into strict mode. */\n protected assertNoBindingCollision(opts: {\n key: string;\n allowOverride?: boolean;\n caller: string;\n }): void {\n const { key, caller } = opts;\n const allowOverride =\n opts.allowOverride ?? this.configs.bootChecks?.binding?.allowOverride ?? true;\n\n if (allowOverride || !this.isBound({ key })) {\n return;\n }\n\n const reason =\n opts.allowOverride === false\n ? `'allowOverride: false' was set and this key collides with an existing binding | Use a distinct 'opts.binding' key, or drop 'allowOverride: false' if overriding is intentional`\n : `'bootChecks.binding.allowOverride' is false and this key collides with an existing binding | Use a distinct 'opts.binding' key, or set 'allowOverride: true' on this registration if overriding is intentional`;\n\n throw getError({\n message: `[${caller}] Binding key already registered: '${key}' | ${reason}`,\n });\n }\n\n /** Resolution order for every registration: explicit `opts` > the class's `@injectable` defaults > the derived key and the kind's default scope. `order` and `when` are `registerArtifacts`' concern, not this one. */\n private registerArtifact<Base>(opts: {\n target: TClass<Base>;\n namespace: TBindingNamespace;\n defaultScope: TBindingScope;\n caller: string;\n opts?: TMixinOpts;\n }): Binding<Base> {\n const { target, namespace, defaultScope, caller } = opts;\n const declared = MetadataRegistry.getInstance().getArtifactMetadata({ target });\n\n if (\n this.runningApplicationHook &&\n this.configs.artifacts &&\n this.configs.bootChecks?.binding?.allowManual === false\n ) {\n throw getError({\n message: `[${caller}] '${target.name}' is registered by hand inside ${this.runningApplicationHook}() while 'configs.artifacts' is set and 'bootChecks.binding.allowManual' is false | Move the class into the generated index (or an explicit entry of 'configs.artifacts'), or allow manual registration`,\n });\n }\n\n const pinned = opts.opts?.binding ?? declared?.binding;\n BindingNamespaces.assertArtifactNamespace({\n namespace: pinned?.namespace ?? namespace,\n artifact: target.name,\n caller,\n });\n\n const { key } = ArtifactBindingKeys.resolve({ target, namespace, binding: pinned });\n\n // What `@inject({ target })` reads back. Only here knows the call site's `binding`, and a\n // class registered by hand has no stereotype metadata to derive one from.\n MetadataRegistry.getInstance().setBindingKey({ target, key });\n\n if (opts.opts?.options !== undefined) {\n this.artifactOptions.set(key, opts.opts.options);\n }\n\n this.assertNoBindingCollision({\n key,\n allowOverride: opts.opts?.allowOverride ?? declared?.allowOverride,\n caller,\n });\n\n return this.bind<Base>({ key })\n .toClass(target)\n .setScope(declared?.scope ?? defaultScope);\n }\n\n configuration<Base extends BaseConfiguration<Options>, Options extends object = {}>(\n target: TClass<Base>,\n opts?: TMixinOpts<Options>,\n ): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.CONFIGURATION,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.configuration.name,\n opts,\n });\n }\n\n async registerConfigurations(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerConfigurations.name,\n description: 'Register application configurations',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.CONFIGURATION });\n },\n });\n }\n\n component<Base extends BaseComponent<Options>, Options extends object = {}>(\n target: TClass<Base>,\n opts?: TMixinOpts<Options>,\n ): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.COMPONENT,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.component.name,\n opts,\n });\n }\n\n async registerComponents(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerComponents.name,\n description: 'Register application components',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.COMPONENT });\n },\n });\n }\n\n /**\n * Second DATASOURCE sweep, for datasources components contributed at any depth. Calls\n * `registerDynamicBindings` directly: `this.registerDataSources()` is polymorphic and an override\n * would run twice. Runs after every component, so a component a datasource registers is never configured.\n */\n async registerContributedDataSources(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerContributedDataSources.name,\n description: 'Register application contributed data sources',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.DATASOURCE });\n },\n });\n }\n\n /** REST only - the kernel has no gRPC (it reaches `node:module`). `BaseApplication` adds the gRPC branch on top. */\n async registerControllers(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n description: 'Register application REST controllers',\n scope: this.registerControllers.name,\n task: async () => {\n const transports = this.configs.transports ?? [ControllerTransports.REST];\n if (!transports.includes(ControllerTransports.REST)) {\n return;\n }\n\n const restComponent = new RestComponent(this);\n await restComponent.configure();\n },\n });\n }\n\n /** SINGLETON like `component()`: `RestComponent` mounts the one instance it resolves, so a second resolution must be that instance, not an unmounted twin. */\n controller<Base>(target: TClass<Base>, opts?: TMixinOpts): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.CONTROLLER,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.controller.name,\n opts,\n });\n }\n\n service<Base extends IService>(target: TClass<Base>, opts?: TMixinOpts): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.SERVICE,\n defaultScope: BindingScopes.TRANSIENT,\n caller: this.service.name,\n opts,\n });\n }\n\n repository<Base extends IRepository>(target: TClass<Base>, opts?: TMixinOpts): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.REPOSITORY,\n defaultScope: BindingScopes.TRANSIENT,\n caller: this.repository.name,\n opts,\n });\n }\n\n dataSource<Base extends IDataSource<Options>, Options extends object = {}>(\n target: TClass<Base>,\n opts?: TMixinOpts<Options>,\n ): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.DATASOURCE,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.dataSource.name,\n opts,\n });\n }\n\n /** The boot step body behind `configs.artifacts`, also callable by hand: registers every kind in dependency order across the given indexes. */\n async registerArtifacts(index: TArtifactIndexInput): Promise<void> {\n const resolved = await ArtifactIndexHelper.getInstance().resolve({\n input: index,\n application: this,\n });\n\n const registry = MetadataRegistry.getInstance();\n const kinds: Array<[ReadonlyArray<TClass<AnyType>>, TBindingNamespace]> = [\n [resolved.configurations, BindingNamespaces.CONFIGURATION],\n [resolved.dataSources, BindingNamespaces.DATASOURCE],\n [resolved.components, BindingNamespaces.COMPONENT],\n [resolved.repositories, BindingNamespaces.REPOSITORY],\n [resolved.services, BindingNamespaces.SERVICE],\n [resolved.controllers, BindingNamespaces.CONTROLLER],\n ];\n const collisions = ArtifactBindingKeys.findDerivedCollisions({\n entries: kinds.flatMap(([targets, namespace]) =>\n targets.map(target => ({\n target,\n namespace,\n binding: registry.getArtifactMetadata({ target })?.binding,\n })),\n ),\n });\n\n for (const key of collisions) {\n const message = ArtifactBindingKeys.describeCollision({ key, caller: 'registerArtifacts' });\n\n if (!this.configs.bootChecks?.allowDerivedKeyCollision) {\n throw getError({ message });\n }\n\n this.logger.warn('%s', message);\n }\n\n for (const target of resolved.configurations) {\n this.configuration(target);\n this.bindProvidedKeys({ target });\n }\n\n for (const target of resolved.dataSources) {\n this.dataSource(target);\n }\n\n for (const target of resolved.components) {\n this.component(target);\n this.bindProvidedKeys({ target });\n }\n\n for (const target of resolved.repositories) {\n this.repository(target);\n }\n\n for (const target of resolved.services) {\n this.service(target);\n }\n\n for (const target of resolved.controllers) {\n this.controller(target);\n }\n }\n\n /** Registers every class a stereotype decorated, with no `configs.artifacts` entry anywhere. `when` and `order` apply exactly as they do to a declared index - which is how one process running several applications keeps them apart. */\n async registerDiscoveredArtifacts(): Promise<void> {\n await this.registerArtifacts(ArtifactIndexHelper.getInstance().buildDiscoveredIndex());\n }\n\n /**\n * The artifact boot step. `configs.discoverArtifacts` adds every decorated class in the import\n * graph; `configs.artifacts` adds exactly what it lists. Both together register the union.\n *\n * An absent `artifacts` still registers nothing. Reading it as \"register everything\" would change\n * what an existing application boots with, silently, and the failure would surface as ten times\n * the bindings rather than as an error.\n */\n protected async registerConfiguredArtifacts(): Promise<void> {\n const inputs: TArtifactIndexInput[] = [];\n\n if (this.configs.discoverArtifacts) {\n inputs.push(ArtifactIndexHelper.getInstance().buildDiscoveredIndex());\n }\n\n if (this.configs.artifacts) {\n inputs.push(this.configs.artifacts);\n }\n\n if (inputs.length === 0) {\n return;\n }\n\n await this.registerArtifacts(inputs);\n }\n\n /** Each `@provide` method becomes a lazy provider: the component is resolved (SINGLETON) and the method called on first `get`, so a provided value may depend on datasources or secrets that do not exist yet at registration time. */\n private bindProvidedKeys(opts: { target: TClass<any> }): void {\n const { target } = opts;\n const registry = MetadataRegistry.getInstance();\n const provides = registry.getProvideMetadata({ target });\n if (provides.length === 0) {\n return;\n }\n\n const declared = registry.getArtifactMetadata({ target });\n const defaultNamespace = declared?.type\n ? ArtifactNamespaces.resolve({ type: declared.type })\n : BindingNamespaces.COMPONENT;\n // The key the registration actually bound - a call-site override included.\n const componentKey =\n registry.getBindingKey({ target }) ??\n ArtifactBindingKeys.resolve({\n target,\n namespace: defaultNamespace,\n binding: declared?.binding,\n }).key;\n for (const entry of provides) {\n this.bind({ key: entry.key })\n .toProvider(container => {\n const instance = container.get<Record<string | symbol, () => unknown>>({\n key: componentKey,\n });\n return instance[entry.methodName]();\n })\n .setScope(entry.scope ?? BindingScopes.SINGLETON);\n }\n }\n\n async registerDataSources(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerDataSources.name,\n description: 'Register application data sources',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.DATASOURCE });\n },\n });\n }\n\n /**\n * Closes every datasource the boot configured, so a stopped application holds no pool, socket or\n * WASM instance. A failure, or a `close()` still pending after `dataSourceCloseTimeoutMs`, is logged\n * and never stops the rest. A datasource configured by hand is closed by whoever configured it.\n */\n protected async closeDataSources(): Promise<void> {\n const keys = this.registeredBindings[BindingNamespaces.DATASOURCE] ?? new Set<string>();\n const timeoutMs = this.configs.dataSourceCloseTimeoutMs ?? 10_000;\n const logger = this.logger.for(this.closeDataSources.name);\n\n for (const key of keys) {\n try {\n const dataSource = this.get<IDataSource>({ key, isOptional: true });\n if (!dataSource?.close) {\n logger.debug('Nothing to close | key: %s', key);\n continue;\n }\n\n const closing = dataSource.close();\n await RetryHelper.runWithTimeout({ operation: key, timeoutMs, execution: () => closing });\n } catch (error) {\n if (RetryHelper.isRetryTimeoutError(error)) {\n logger.error('Close timed out | key: %s | timeoutMs: %d', key, timeoutMs);\n continue;\n }\n\n logger.error('Failed to close datasource | key: %s | error: %s', key, error);\n continue;\n }\n\n logger.info('Closed datasource | key: %s', key);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/base/applications/rest.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TBindingNamespace } from '@/common/bindings';\nimport { ArtifactNamespaces, BindingNamespaces, CoreBindings } from '@/common/bindings';\nimport type { Binding, TBindingScope } from '@/helpers/inversion';\nimport { BindingScopes, MetadataRegistry } from '@/helpers/inversion';\nimport { OpenAPIHono } from '@hono/zod-openapi';\nimport type { AnyType, IConfigurable, TClass, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport {\n executeWithPerformanceMeasure,\n getError,\n RequestIdGenerator,\n RetryHelper,\n} from '@venizia/ignis-helpers/core';\nimport type { Env, Schema } from 'hono';\nimport { showRoutes as showApplicationRoutes } from 'hono/dev';\nimport { bodyLimit } from 'hono/body-limit';\nimport { requestId } from 'hono/request-id';\nimport type { BaseComponent } from '../components';\nimport { ArtifactBindingKeys } from '../metadata/artifact-keys';\nimport { RestComponent } from '../components/controller/rest/rest.component';\nimport type { BaseConfiguration } from '../configurations';\nimport { ControllerTransports } from '../controllers/common/constants';\nimport type { IDataSource } from '../datasources';\nimport { BaseAppErrorMiddleware } from '../middlewares/app-error/app-error.middleware';\nimport { RequestErrors } from '../middlewares/common/errors';\nimport { notFoundHandler } from '../middlewares/not-found/not-found.middleware';\nimport type { TMixinOpts } from '../mixins/common';\nimport type { IRepository } from '../repositories';\nimport type { IService } from '../services';\nimport { AbstractApplication } from './abstract';\nimport { ArtifactIndexHelper } from './artifact-index';\nimport type { IBootSequenceStep } from './boot-sequence';\nimport { BootSteps } from './boot-sequence';\nimport type { IApplicationConfigs, IBodyLimitOptions, TArtifactIndexInput } from './common';\n\ninterface IRegisterDynamicBindingsOptions<T extends IConfigurable = IConfigurable> {\n namespace: TBindingNamespace;\n\n onBeforeConfigure?: (opts: { binding: Binding<T> }) => Promise<void>;\n onAfterConfigure?: (opts: { binding: Binding<T>; instance: T }) => Promise<void>;\n}\n\n/** Adds the `OpenAPIHono` router surface on top of `AbstractApplication` - no listening server, so this is the layer a browser Worker or gRPC-only host can extend without pulling in `Bun.serve` / `@hono/node-server`. */\nexport abstract class RestApplication<\n AppEnv extends Env = Env,\n AppSchema extends Schema = {},\n BasePath extends string = '/',\n> extends AbstractApplication {\n private registeredBindings: Record<string, Set<string>> = {};\n private artifactOptions = new Map<string, object>();\n\n /** The router, and nothing else. What runtime is underneath and what socket is bound are `ServerApplication`'s to know - a browser Worker has neither, and carrying the union here made `RuntimeModules.detect()` answer `'node'` inside a Worker. */\n protected server: { hono: OpenAPIHono<AppEnv, AppSchema, BasePath> };\n\n protected rootRouter: OpenAPIHono<AppEnv, AppSchema, BasePath>;\n protected readonly requestIdGenerator: RequestIdGenerator;\n\n /** A copy of the `bodyLimit` the default stack installed, absent until `registerDefaultMiddlewares()` ran. */\n private installedBodyLimit?: { options?: IBodyLimitOptions };\n\n constructor(opts: { scope: string; config: IApplicationConfigs }) {\n super(opts);\n\n // A config built from the environment can lose `path.base` at run time; the router would only fail later, inside `route()`, with a message that names nothing.\n if (typeof this.configs.path?.base !== 'string') {\n throw getError({\n message: `[${opts.scope}] configs.path.base must be a string | value: ${String(this.configs.path?.base)} | an empty string mounts the application at the root`,\n });\n }\n\n // The index signature accepts any key, so a leftover `strictPath` would compile and be ignored.\n if (this.configs.strictPath !== undefined) {\n throw getError({\n message: `[${opts.scope}] configs.strictPath was removed | value: ${String(this.configs.strictPath)} | Use configs.path.isStrict`,\n });\n }\n\n this.requestIdGenerator = new RequestIdGenerator({ scope: opts.scope });\n\n const strict = this.configs.path.isStrict ?? true;\n const honoServer = new OpenAPIHono<AppEnv, AppSchema, BasePath>({ strict });\n this.rootRouter = new OpenAPIHono({ strict });\n\n this.server = { hono: honoServer };\n }\n\n getRootRouter(): OpenAPIHono<AppEnv, AppSchema, BasePath> {\n return this.rootRouter;\n }\n\n getServer(): OpenAPIHono<AppEnv, AppSchema, BasePath> {\n return this.server.hono;\n }\n\n protected override registerCoreBindings() {\n super.registerCoreBindings();\n\n this.bind<typeof this.server>({\n key: CoreBindings.APPLICATION_SERVER,\n }).toProvider((_) => this.server);\n this.bind<typeof this.rootRouter>({\n key: CoreBindings.APPLICATION_ROOT_ROUTER,\n }).toProvider((_) => this.rootRouter);\n }\n\n /** The correlation id every host stamps - see {@link RequestIdGenerator} for why `crypto.randomUUID` is refused. */\n protected generateRequestId(): string {\n return this.requestIdGenerator.nextId();\n }\n\n /** The error handler the default stack installs. `@venizia/ignis` overrides it to swap in the `ErrorPrettier`-backed formatter, which reaches `node:util` and so cannot live here. */\n protected buildErrorMiddleware(): BaseAppErrorMiddleware {\n const environment = this.configs.error?.environment;\n\n return new BaseAppErrorMiddleware({\n logger: this.logger,\n rootKey: this.configs.error?.rootKey ?? undefined,\n // Spread, not `environment: () => environment`: the option's PRESENCE is what claims this host\n // has an ambient environment at all, so an unset config must leave it absent.\n ...(environment === undefined ? {} : { environment: () => environment }),\n });\n }\n\n /**\n * The three registrations every host needs: request id, error envelope, JSON 404 - without them a\n * thrown `ApplicationError` is a generic 500, a 404 is `text/plain`, and no response carries a request id.\n * Registered before `initialize()`, so an application's own handlers still win.\n */\n protected registerDefaultMiddlewares(): ValueOrPromise<void> {\n const server = this.getServer();\n\n server.use(requestId({ generator: () => this.generateRequestId() }));\n\n // Ahead of every middleware a host adds after this one, so none of them buffers a body over it.\n const bodyLimitOptions = this.configs.middlewares?.bodyLimit;\n this.installedBodyLimit = { options: this.toInstalledBodyLimit({ options: bodyLimitOptions }) };\n\n if (bodyLimitOptions && bodyLimitOptions.enable !== false) {\n const { maxSize, path, onError } = bodyLimitOptions;\n\n if (typeof maxSize !== 'number' || !Number.isFinite(maxSize) || maxSize < 0) {\n throw getError({\n message: `[registerDefaultMiddlewares] configs.middlewares.bodyLimit.maxSize must be a non-negative number of bytes | value: ${String(maxSize)}`,\n });\n }\n\n const limiter = bodyLimit({\n maxSize,\n onError:\n onError ??\n (() => {\n throw getError({\n error: RequestErrors.BODY_TOO_LARGE,\n message: `Request body exceeds the maximum of ${maxSize} bytes`,\n });\n }),\n });\n\n if (path) {\n server.use(path, limiter);\n } else {\n server.use(limiter);\n }\n }\n\n server.onError(this.buildErrorMiddleware().value());\n server.notFound(notFoundHandler({ logger: this.logger }));\n }\n\n /** What a `bodyLimit` config installs: nothing when absent or disabled, else a copy, so a later in-place edit shows. */\n private toInstalledBodyLimit(opts: {\n options?: IBodyLimitOptions;\n }): IBodyLimitOptions | undefined {\n const { options } = opts;\n\n if (!options || options.enable === false) {\n return undefined;\n }\n\n return { ...options };\n }\n\n private isSameBodyLimit(opts: { left?: IBodyLimitOptions; right?: IBodyLimitOptions }): boolean {\n const { left, right } = opts;\n\n if (!left || !right) {\n return left === right;\n }\n\n const keys = new Set([...Object.keys(left), ...Object.keys(right)]);\n for (const key of keys) {\n if (!Object.is(left[key], right[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * `configs.middlewares` is read by `registerDefaultMiddlewares()`, which runs before `staticConfigure()`.\n * A limit assigned in a boot hook would read back as configured while every request ran unlimited.\n */\n private assertBodyLimitUnchanged(opts: { step: string }): void {\n if (!this.installedBodyLimit) {\n return;\n }\n\n const installed = this.installedBodyLimit.options;\n const current = this.toInstalledBodyLimit({ options: this.configs.middlewares?.bodyLimit });\n\n if (this.isSameBodyLimit({ left: installed, right: current })) {\n return;\n }\n\n throw getError({\n message: `[${opts.step}] configs.middlewares.bodyLimit changed after registerDefaultMiddlewares() installed it | installed maxSize: ${installed?.maxSize ?? 'none'} | now maxSize: ${current?.maxSize ?? 'none'} | Pass it through the constructor config: new Application({ config: { middlewares: { bodyLimit } } })`,\n });\n }\n\n /**\n * The artifact order, stated once: datasources before the repositories that auto-resolve them,\n * components before the controllers they may contribute. `BaseApplication` splices its server-only\n * steps around these by name instead of rewriting the list.\n */\n protected getBootSequence(): IBootSequenceStep[] {\n return [\n {\n name: BootSteps.STATIC_CONFIGURE,\n run: async () => {\n // Declared `void`, but an override may be async; the step has always waited on it.\n await Promise.resolve(this.staticConfigure());\n this.assertBodyLimitUnchanged({ step: BootSteps.STATIC_CONFIGURE });\n },\n },\n { name: BootSteps.REGISTER_ARTIFACTS, run: () => this.registerConfiguredArtifacts() },\n {\n name: BootSteps.PRE_CONFIGURE,\n run: async () => {\n await this.runApplicationHook({\n name: BootSteps.PRE_CONFIGURE,\n hook: () => this.preConfigure(),\n });\n this.assertBodyLimitUnchanged({ step: BootSteps.PRE_CONFIGURE });\n },\n },\n {\n name: BootSteps.REGISTER_CONFIGURATIONS,\n run: () => this.registerConfigurations(),\n },\n { name: BootSteps.REGISTER_DATA_SOURCES, run: () => this.registerDataSources() },\n { name: BootSteps.REGISTER_COMPONENTS, run: () => this.registerComponents() },\n {\n name: BootSteps.REGISTER_CONTRIBUTED_DATA_SOURCES,\n run: () => this.registerContributedDataSources(),\n },\n { name: BootSteps.REGISTER_CONTROLLERS, run: () => this.registerControllers() },\n {\n name: BootSteps.POST_CONFIGURE,\n run: () =>\n this.runApplicationHook({\n name: BootSteps.POST_CONFIGURE,\n hook: () => this.postConfigure(),\n }),\n },\n { name: BootSteps.VERIFY_BINDINGS, run: () => this.verifyBindings() },\n ];\n }\n\n async initialize(): Promise<void> {\n await this.runBootSequence({ steps: this.getBootSequence() });\n }\n\n /** The application hook currently running, so `registerArtifact` can tell a hand registration inside `preConfigure`/`postConfigure` from one the index step made. */\n private runningApplicationHook: string | undefined;\n\n private async runApplicationHook(opts: {\n name: string;\n hook: () => ValueOrPromise<void>;\n }): Promise<void> {\n this.runningApplicationHook = opts.name;\n try {\n await opts.hook();\n } finally {\n this.runningApplicationHook = undefined;\n }\n }\n\n /**\n * Bound keys carrying one of `tags` that nothing has resolved since the counts were last reset.\n * The counter answers \"who was read\", never \"who is dead\" - an unread binding may be an\n * allow-list entry or a technical floor, and only the application can tell those apart.\n *\n * Counting is off by default. Call `startResolutionCounting()` after `initialize()` and run the\n * traffic that exercises the application, then read this.\n */\n getUnresolvedBindings(opts?: { tags?: string[] }): string[] {\n if (!this.hasStartedResolutionCounting) {\n throw getError({\n message: `[${this.getUnresolvedBindings.name}] Resolution counting never started | Call startResolutionCounting() after initialize(), run the traffic that exercises the application, then read this - without it every binding would be reported unresolved`,\n });\n }\n\n const tags = opts?.tags ?? [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY];\n const counts = this.getResolutionCounts();\n const unresolved: string[] = [];\n\n for (const tag of tags) {\n const bindings = this.findByTag({ tag });\n for (const binding of bindings) {\n if (counts.has(binding.key)) {\n continue;\n }\n\n unresolved.push(binding.key);\n }\n }\n\n return unresolved;\n }\n\n /** `bootChecks.binding.doVerify`: resolve every service and repository once, collect every failure, throw once with the whole list - a made-up `@inject` key or a dependency a `when` excluded then fails the boot, not the first request. */\n protected verifyBindings(): void {\n if (!this.configs.bootChecks?.binding?.doVerify) {\n return;\n }\n\n const logger = this.logger.for(this.verifyBindings.name);\n const tags = [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY];\n const failures: string[] = [];\n let verified = 0;\n\n for (const tag of tags) {\n const bindings = this.findByTag({ tag });\n for (const binding of bindings) {\n try {\n this.get({ key: binding.key });\n verified += 1;\n } catch (error) {\n failures.push(\n `${binding.key}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n if (failures.length > 0) {\n throw getError({\n message: `[${this.verifyBindings.name}] ${failures.length} binding(s) cannot be resolved | ${failures.join(' | ')}`,\n });\n }\n\n logger.info('Every service and repository binding resolves | verified: %d', verified);\n }\n\n /** One measured log line per step, and a failure names its step before rethrowing, so a hung or failed boot is attributable without reading the sequence. */\n protected async runBootSequence(opts: { steps: IBootSequenceStep[] }): Promise<void> {\n const { steps } = opts;\n const logger = this.logger.for(this.initialize.name);\n const t = performance.now();\n\n const stepsEntries = steps.entries();\n for (const [index, step] of stepsEntries) {\n try {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.initialize.name,\n description: `Boot step ${index + 1}/${steps.length} ${step.name}`,\n task: () => step.run(),\n });\n } catch (error) {\n logger.error(\n 'Boot step failed | step: %s (%d/%d) | error: %s',\n step.name,\n index + 1,\n steps.length,\n error,\n );\n throw error;\n }\n }\n\n logger.info(\n 'Boot sequence complete | %d step(s) | Took: %s (ms) | %s',\n steps.length,\n performance.now() - t,\n steps.map((step) => step.name).join(' -> '),\n );\n }\n\n protected inspectRoutes() {\n const t = performance.now();\n const shouldShowRoutes = this.configs?.debug?.shouldShowRoutes ?? false;\n\n if (!shouldShowRoutes) {\n return;\n }\n\n this.logger.for(this.inspectRoutes.name).info('START | Inspect all application route(s)');\n showApplicationRoutes(this.getServer());\n this.logger\n .for(this.inspectRoutes.name)\n .info('DONE | Inspect all application route(s) | Took: %s (ms)', performance.now() - t);\n }\n\n /**\n * `configured` is the drain's state, mutated in place: a fresh `Set` gives a one-shot complete\n * drain (`RestComponent`); `registerDynamicBindings` passes its persistent per-namespace `Set`,\n * which is why a second sweep touches only what the first one missed.\n */\n async drainByTag<T>(opts: {\n tag: string;\n configured: Set<string>;\n onEach: (opts: { binding: Binding<T> }) => Promise<void>;\n }): Promise<void> {\n const { tag, configured, onEach } = opts;\n\n // A whole batch is drained before re-scanning: the re-scan exists only to pick up bindings a\n // `configure()` added, and asking after every single item makes boot N+1 full scans of the\n // binding map - 3.5ms at 200 controllers, against 0.04ms for this shape.\n let bindings = this.findByTag<T>({ tag, exclude: configured });\n\n while (bindings.length > 0) {\n for (const binding of bindings) {\n // Within a batch a nested `configure()` may already have taken this one.\n if (configured.has(binding.key)) {\n continue;\n }\n\n await onEach({ binding });\n configured.add(binding.key);\n }\n\n // Re-fetch excluding already configured - picks up dynamically added bindings\n bindings = this.findByTag<T>({ tag, exclude: configured });\n }\n }\n\n protected async registerDynamicBindings<T extends IConfigurable = IConfigurable>(\n opts: IRegisterDynamicBindingsOptions<T>,\n ): Promise<void> {\n const logger = this.logger.for(this.registerDynamicBindings.name);\n const { namespace, onBeforeConfigure, onAfterConfigure } = opts;\n\n if (!this.registeredBindings[namespace]) {\n this.registeredBindings[namespace] = new Set<string>();\n }\n const configured = this.registeredBindings[namespace];\n\n await this.drainByTag<T>({\n tag: namespace,\n configured,\n onEach: async ({ binding }) => {\n if (onBeforeConfigure) {\n await onBeforeConfigure({ binding });\n }\n\n const instance = this.get<T>({ key: binding.key, isOptional: false });\n if (!instance) {\n logger.debug('No binding instance | namespace: %s | key: %s', namespace, binding.key);\n return;\n }\n\n if (typeof (instance as Partial<IConfigurable>)?.configure === 'function') {\n const options = this.artifactOptions.get(binding.key);\n await (instance as IConfigurable).configure(options);\n }\n\n // Marked before the after-hook runs, so the hook sees its own binding as configured.\n configured.add(binding.key);\n\n if (onAfterConfigure) {\n await onAfterConfigure({ binding, instance });\n }\n },\n });\n }\n\n /** The same-key guard behind every artifact registration (`component`/`controller`/`service`/`repository`/`dataSource`). `allowOverride` defaults true to match `bind()`'s overwrite behavior; `allowOverride: false` on one registration, or `bootChecks.binding.allowOverride: false` for the whole application, opts into strict mode. */\n protected assertNoBindingCollision(opts: {\n key: string;\n allowOverride?: boolean;\n caller: string;\n }): void {\n const { key, caller } = opts;\n const allowOverride =\n opts.allowOverride ?? this.configs.bootChecks?.binding?.allowOverride ?? true;\n\n if (allowOverride || !this.isBound({ key })) {\n return;\n }\n\n const reason =\n opts.allowOverride === false\n ? `'allowOverride: false' was set and this key collides with an existing binding | Use a distinct 'opts.binding' key, or drop 'allowOverride: false' if overriding is intentional`\n : `'bootChecks.binding.allowOverride' is false and this key collides with an existing binding | Use a distinct 'opts.binding' key, or set 'allowOverride: true' on this registration if overriding is intentional`;\n\n throw getError({\n message: `[${caller}] Binding key already registered: '${key}' | ${reason}`,\n });\n }\n\n /** Resolution order for every registration: explicit `opts` > the class's `@injectable` defaults > the derived key and the kind's default scope. `order` and `when` are `registerArtifacts`' concern, not this one. */\n private registerArtifact<Base>(opts: {\n target: TClass<Base>;\n namespace: TBindingNamespace;\n defaultScope: TBindingScope;\n caller: string;\n opts?: TMixinOpts;\n }): Binding<Base> {\n const { target, namespace, defaultScope, caller } = opts;\n const declared = MetadataRegistry.getInstance().getArtifactMetadata({ target });\n\n if (\n this.runningApplicationHook &&\n this.configs.artifacts &&\n this.configs.bootChecks?.binding?.allowManual === false\n ) {\n throw getError({\n message: `[${caller}] '${target.name}' is registered by hand inside ${this.runningApplicationHook}() while 'configs.artifacts' is set and 'bootChecks.binding.allowManual' is false | Move the class into the generated index (or an explicit entry of 'configs.artifacts'), or allow manual registration`,\n });\n }\n\n const pinned = opts.opts?.binding ?? declared?.binding;\n BindingNamespaces.assertArtifactNamespace({\n namespace: pinned?.namespace ?? namespace,\n artifact: target.name,\n caller,\n });\n\n const { key } = ArtifactBindingKeys.resolve({ target, namespace, binding: pinned });\n\n // What `@inject({ target })` reads back. Only here knows the call site's `binding`, and a\n // class registered by hand has no stereotype metadata to derive one from.\n MetadataRegistry.getInstance().setBindingKey({ target, key });\n\n if (opts.opts?.options !== undefined) {\n this.artifactOptions.set(key, opts.opts.options);\n }\n\n this.assertNoBindingCollision({\n key,\n allowOverride: opts.opts?.allowOverride ?? declared?.allowOverride,\n caller,\n });\n\n return this.bind<Base>({ key })\n .toClass(target)\n .setScope(declared?.scope ?? defaultScope);\n }\n\n configuration<Base extends BaseConfiguration<Options>, Options extends object = {}>(\n target: TClass<Base>,\n opts?: TMixinOpts<Options>,\n ): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.CONFIGURATION,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.configuration.name,\n opts,\n });\n }\n\n async registerConfigurations(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerConfigurations.name,\n description: 'Register application configurations',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.CONFIGURATION });\n },\n });\n }\n\n component<Base extends BaseComponent<Options>, Options extends object = {}>(\n target: TClass<Base>,\n opts?: TMixinOpts<Options>,\n ): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.COMPONENT,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.component.name,\n opts,\n });\n }\n\n async registerComponents(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerComponents.name,\n description: 'Register application components',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.COMPONENT });\n },\n });\n }\n\n /**\n * Second DATASOURCE sweep, for datasources components contributed at any depth. Calls\n * `registerDynamicBindings` directly: `this.registerDataSources()` is polymorphic and an override\n * would run twice. Runs after every component, so a component a datasource registers is never configured.\n */\n async registerContributedDataSources(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerContributedDataSources.name,\n description: 'Register application contributed data sources',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.DATASOURCE });\n },\n });\n }\n\n /** REST only - the kernel has no gRPC (it reaches `node:module`). `BaseApplication` adds the gRPC branch on top. */\n async registerControllers(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n description: 'Register application REST controllers',\n scope: this.registerControllers.name,\n task: async () => {\n const transports = this.configs.transports ?? [ControllerTransports.REST];\n if (!transports.includes(ControllerTransports.REST)) {\n return;\n }\n\n const restComponent = new RestComponent(this);\n await restComponent.configure();\n },\n });\n }\n\n /** SINGLETON like `component()`: `RestComponent` mounts the one instance it resolves, so a second resolution must be that instance, not an unmounted twin. */\n controller<Base>(target: TClass<Base>, opts?: TMixinOpts): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.CONTROLLER,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.controller.name,\n opts,\n });\n }\n\n service<Base extends IService>(target: TClass<Base>, opts?: TMixinOpts): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.SERVICE,\n defaultScope: BindingScopes.TRANSIENT,\n caller: this.service.name,\n opts,\n });\n }\n\n repository<Base extends IRepository>(target: TClass<Base>, opts?: TMixinOpts): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.REPOSITORY,\n defaultScope: BindingScopes.TRANSIENT,\n caller: this.repository.name,\n opts,\n });\n }\n\n dataSource<Base extends IDataSource<Options>, Options extends object = {}>(\n target: TClass<Base>,\n opts?: TMixinOpts<Options>,\n ): Binding<Base> {\n return this.registerArtifact({\n target,\n namespace: BindingNamespaces.DATASOURCE,\n defaultScope: BindingScopes.SINGLETON,\n caller: this.dataSource.name,\n opts,\n });\n }\n\n /** The boot step body behind `configs.artifacts`, also callable by hand: registers every kind in dependency order across the given indexes. */\n async registerArtifacts(index: TArtifactIndexInput): Promise<void> {\n const resolved = await ArtifactIndexHelper.getInstance().resolve({\n input: index,\n application: this,\n });\n\n const registry = MetadataRegistry.getInstance();\n const kinds: Array<[ReadonlyArray<TClass<AnyType>>, TBindingNamespace]> = [\n [resolved.configurations, BindingNamespaces.CONFIGURATION],\n [resolved.dataSources, BindingNamespaces.DATASOURCE],\n [resolved.components, BindingNamespaces.COMPONENT],\n [resolved.repositories, BindingNamespaces.REPOSITORY],\n [resolved.services, BindingNamespaces.SERVICE],\n [resolved.controllers, BindingNamespaces.CONTROLLER],\n ];\n const collisions = ArtifactBindingKeys.findDerivedCollisions({\n entries: kinds.flatMap(([targets, namespace]) =>\n targets.map((target) => ({\n target,\n namespace,\n binding: registry.getArtifactMetadata({ target })?.binding,\n })),\n ),\n });\n\n for (const key of collisions) {\n const message = ArtifactBindingKeys.describeCollision({ key, caller: 'registerArtifacts' });\n\n if (!this.configs.bootChecks?.allowDerivedKeyCollision) {\n throw getError({ message });\n }\n\n this.logger.warn('%s', message);\n }\n\n for (const target of resolved.configurations) {\n this.configuration(target);\n this.bindProvidedKeys({ target });\n }\n\n for (const target of resolved.dataSources) {\n this.dataSource(target);\n }\n\n for (const target of resolved.components) {\n this.component(target);\n this.bindProvidedKeys({ target });\n }\n\n for (const target of resolved.repositories) {\n this.repository(target);\n }\n\n for (const target of resolved.services) {\n this.service(target);\n }\n\n for (const target of resolved.controllers) {\n this.controller(target);\n }\n }\n\n /** Registers every class a stereotype decorated, with no `configs.artifacts` entry anywhere. `when` and `order` apply exactly as they do to a declared index - which is how one process running several applications keeps them apart. */\n async registerDiscoveredArtifacts(): Promise<void> {\n await this.registerArtifacts(ArtifactIndexHelper.getInstance().buildDiscoveredIndex());\n }\n\n /**\n * The artifact boot step. `configs.discoverArtifacts` adds every decorated class in the import\n * graph; `configs.artifacts` adds exactly what it lists. Both together register the union.\n *\n * An absent `artifacts` still registers nothing. Reading it as \"register everything\" would change\n * what an existing application boots with, silently, and the failure would surface as ten times\n * the bindings rather than as an error.\n */\n protected async registerConfiguredArtifacts(): Promise<void> {\n const inputs: TArtifactIndexInput[] = [];\n\n if (this.configs.discoverArtifacts) {\n inputs.push(ArtifactIndexHelper.getInstance().buildDiscoveredIndex());\n }\n\n if (this.configs.artifacts) {\n inputs.push(this.configs.artifacts);\n }\n\n if (inputs.length === 0) {\n return;\n }\n\n await this.registerArtifacts(inputs);\n }\n\n /** Each `@provide` method becomes a lazy provider: the component is resolved (SINGLETON) and the method called on first `get`, so a provided value may depend on datasources or secrets that do not exist yet at registration time. */\n private bindProvidedKeys(opts: { target: TClass<any> }): void {\n const { target } = opts;\n const registry = MetadataRegistry.getInstance();\n const provides = registry.getProvideMetadata({ target });\n if (provides.length === 0) {\n return;\n }\n\n const declared = registry.getArtifactMetadata({ target });\n const defaultNamespace = declared?.type\n ? ArtifactNamespaces.resolve({ type: declared.type })\n : BindingNamespaces.COMPONENT;\n // The key the registration actually bound - a call-site override included.\n const componentKey =\n registry.getBindingKey({ target }) ??\n ArtifactBindingKeys.resolve({\n target,\n namespace: defaultNamespace,\n binding: declared?.binding,\n }).key;\n for (const entry of provides) {\n this.bind({ key: entry.key })\n .toProvider((container) => {\n const instance = container.get<Record<string | symbol, () => unknown>>({\n key: componentKey,\n });\n return instance[entry.methodName]();\n })\n .setScope(entry.scope ?? BindingScopes.SINGLETON);\n }\n }\n\n async registerDataSources(): Promise<void> {\n await executeWithPerformanceMeasure({\n logger: this.logger,\n scope: this.registerDataSources.name,\n description: 'Register application data sources',\n task: async () => {\n await this.registerDynamicBindings({ namespace: BindingNamespaces.DATASOURCE });\n },\n });\n }\n\n /**\n * Closes every datasource the boot configured, so a stopped application holds no pool, socket or\n * WASM instance. A failure, or a `close()` still pending after `dataSourceCloseTimeoutMs`, is logged\n * and never stops the rest. A datasource configured by hand is closed by whoever configured it.\n */\n protected async closeDataSources(): Promise<void> {\n const keys = this.registeredBindings[BindingNamespaces.DATASOURCE] ?? new Set<string>();\n const timeoutMs = this.configs.dataSourceCloseTimeoutMs ?? 10_000;\n const logger = this.logger.for(this.closeDataSources.name);\n\n for (const key of keys) {\n try {\n const dataSource = this.get<IDataSource>({ key, isOptional: true });\n if (!dataSource?.close) {\n logger.debug('Nothing to close | key: %s', key);\n continue;\n }\n\n const closing = dataSource.close();\n await RetryHelper.runWithTimeout({ operation: key, timeoutMs, execution: () => closing });\n } catch (error) {\n if (RetryHelper.isRetryTimeoutError(error)) {\n logger.error('Close timed out | key: %s | timeoutMs: %d', key, timeoutMs);\n continue;\n }\n\n logger.error('Failed to close datasource | key: %s | error: %s', key, error);\n continue;\n }\n\n logger.info('Closed datasource | key: %s', key);\n }\n }\n}\n"]}
@@ -6,10 +6,10 @@ class AuthenticationFieldCodecs {
6
6
  static { this.ROLES_CODEC = {
7
7
  key: 'roles',
8
8
  serialize(opts) {
9
- return JSON.stringify(opts.value.map(el => `${el.id}|${el.identifier}|${el.priority}`));
9
+ return JSON.stringify(opts.value.map((el) => `${el.id}|${el.identifier}|${el.priority}`));
10
10
  },
11
11
  deserialize(opts) {
12
- return JSON.parse(opts.raw).map(el => {
12
+ return JSON.parse(opts.raw).map((el) => {
13
13
  const [id, identifier, priority] = el.split('|');
14
14
  return { id, identifier, priority: (0, core_1.int)(priority) };
15
15
  });
@@ -1 +1 @@
1
- {"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authenticate/common/codecs.ts"],"names":[],"mappings":";;;AAAA,sDAAkD;AAGlD,MAAa,yBAAyB;aACpB,gBAAW,GAAkD;QAC3E,GAAG,EAAE,OAAO;QACZ,SAAS,CAAC,IAAI;YACZ,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC1F,CAAC;QACD,WAAW,CAAC,IAAI;YACd,OAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBACjD,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjD,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAA,UAAG,EAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,2CAA2C;IAC3C,MAAM,CAAC,KAAK,CAAc,IAIzB;QACC,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;;AAzBH,8DA0BC","sourcesContent":["import { int } from '@venizia/ignis-helpers/core';\nimport type { IJWTTokenPayload, IPayloadFieldCodec } from './types';\n\nexport class AuthenticationFieldCodecs {\n static readonly ROLES_CODEC: IPayloadFieldCodec<IJWTTokenPayload['roles']> = {\n key: 'roles',\n serialize(opts) {\n return JSON.stringify(opts.value.map(el => `${el.id}|${el.identifier}|${el.priority}`));\n },\n deserialize(opts) {\n return (JSON.parse(opts.raw) as string[]).map(el => {\n const [id, identifier, priority] = el.split('|');\n return { id, identifier, priority: int(priority) };\n });\n },\n };\n\n /** Builds a single payload field codec. */\n static build<T = unknown>(opts: {\n key: string;\n serialize: IPayloadFieldCodec<T>['serialize'];\n deserialize: IPayloadFieldCodec<T>['deserialize'];\n }): IPayloadFieldCodec<T> {\n return {\n key: opts.key,\n serialize: opts.serialize,\n deserialize: opts.deserialize,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authenticate/common/codecs.ts"],"names":[],"mappings":";;;AAAA,sDAAkD;AAGlD,MAAa,yBAAyB;aACpB,gBAAW,GAAkD;QAC3E,GAAG,EAAE,OAAO;QACZ,SAAS,CAAC,IAAI;YACZ,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC5F,CAAC;QACD,WAAW,CAAC,IAAI;YACd,OAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;gBACnD,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjD,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAA,UAAG,EAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,2CAA2C;IAC3C,MAAM,CAAC,KAAK,CAAc,IAIzB;QACC,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;;AAzBH,8DA0BC","sourcesContent":["import { int } from '@venizia/ignis-helpers/core';\nimport type { IJWTTokenPayload, IPayloadFieldCodec } from './types';\n\nexport class AuthenticationFieldCodecs {\n static readonly ROLES_CODEC: IPayloadFieldCodec<IJWTTokenPayload['roles']> = {\n key: 'roles',\n serialize(opts) {\n return JSON.stringify(opts.value.map((el) => `${el.id}|${el.identifier}|${el.priority}`));\n },\n deserialize(opts) {\n return (JSON.parse(opts.raw) as string[]).map((el) => {\n const [id, identifier, priority] = el.split('|');\n return { id, identifier, priority: int(priority) };\n });\n },\n };\n\n /** Builds a single payload field codec. */\n static build<T = unknown>(opts: {\n key: string;\n serialize: IPayloadFieldCodec<T>['serialize'];\n deserialize: IPayloadFieldCodec<T>['deserialize'];\n }): IPayloadFieldCodec<T> {\n return {\n key: opts.key,\n serialize: opts.serialize,\n deserialize: opts.deserialize,\n };\n }\n}\n"]}
@@ -11,7 +11,7 @@ class AuthenticationProvider extends core_1.BaseHelper {
11
11
  super({ scope: AuthenticationProvider.name });
12
12
  }
13
13
  value() {
14
- return opts => {
14
+ return (opts) => {
15
15
  return this.createAuthenticateMiddleware(opts);
16
16
  };
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.provider.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authenticate/providers/authentication.provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TContext } from '@/base/controllers/common/types';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport type { IProvider } from '@venizia/ignis-inversion';\nimport type { Env } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport type { IAuthUser, TAuthenticateFn, TAuthMode } from '../common';\nimport { Authentication, AuthenticationErrors, AuthenticationModes } from '../common';\nimport { AuthenticationStrategyRegistry } from '../strategies/strategy-registry';\n\nexport class AuthenticationProvider<RouteEnv extends Env = Env>\n extends BaseHelper\n implements IProvider<TAuthenticateFn<RouteEnv>>\n{\n constructor() {\n super({ scope: AuthenticationProvider.name });\n }\n\n value(): TAuthenticateFn<RouteEnv> {\n return opts => {\n return this.createAuthenticateMiddleware(opts);\n };\n }\n\n private createAuthenticateMiddleware(opts: { strategies: string[]; mode?: TAuthMode }) {\n const { strategies, mode = AuthenticationModes.ANY } = opts;\n const registry = AuthenticationStrategyRegistry.getInstance();\n\n return createMiddleware(async (context, next) => {\n const isSkipAuthenticate = context.get(Authentication.SKIP_AUTHENTICATION);\n if (isSkipAuthenticate) {\n this.logger\n .for(this.createAuthenticateMiddleware.name)\n .debug('SKIP checking authentication | path: %s', context.req.path);\n return next();\n }\n\n const isAuthenticated = context.get(Authentication.CURRENT_USER);\n if (isAuthenticated) {\n return next();\n }\n\n switch (mode) {\n case AuthenticationModes.ANY: {\n await this.executeAnyMode({\n context: context as TContext,\n strategies,\n registry,\n next,\n });\n return;\n }\n case AuthenticationModes.ALL: {\n await this.executeAllMode({\n context: context as TContext,\n strategies,\n registry,\n next,\n });\n return;\n }\n default: {\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: `Invalid authentication mode | mode: ${mode}`,\n });\n }\n }\n });\n }\n\n private async executeAnyMode(opts: {\n context: TContext;\n strategies: string[];\n registry: AuthenticationStrategyRegistry;\n next: () => Promise<void>;\n }) {\n const { context, strategies, registry, next } = opts;\n\n // The first strategy's failure is the primary one - kept so the 401 carries WHY, instead of only which strategies were tried.\n let primaryFailure: unknown;\n\n for (const strategyName of strategies) {\n try {\n const strategy = registry.resolveStrategy({ name: strategyName });\n const user = await strategy.authenticate(context);\n this.setCurrentUser({ context, user });\n break;\n } catch (error) {\n primaryFailure ??= error;\n this.logger\n .for(this.executeAnyMode.name)\n .debug('Strategy %s failed, trying next... | Error: %s', strategyName, error);\n }\n }\n\n const currentUser = context.get(Authentication.CURRENT_USER);\n if (!currentUser) {\n throw getError({\n error: AuthenticationErrors.FAILED,\n message: `Authentication failed. Tried strategies: ${strategies.join(', ')}`,\n logLevel: 'warn',\n cause: primaryFailure,\n });\n }\n\n await next();\n }\n\n private async executeAllMode(opts: {\n context: TContext;\n strategies: string[];\n registry: AuthenticationStrategyRegistry;\n next: () => Promise<void>;\n }) {\n const { context, strategies, registry, next } = opts;\n\n // Use the first strategy's user as the identity source - all must succeed but first wins for identity\n let authUser: IAuthUser | null = null;\n\n for (const strategyName of strategies) {\n const strategy = registry.resolveStrategy({ name: strategyName });\n const user = await strategy.authenticate(context);\n\n authUser ??= user;\n }\n\n if (authUser?.userId) {\n this.setCurrentUser({ context, user: authUser });\n } else {\n this.logger\n .for(this.executeAllMode.name)\n .error(\n 'Failed to identify authenticated user | user: %j | userId: %s',\n authUser,\n authUser?.userId,\n );\n throw getError({ error: AuthenticationErrors.USER_UNRESOLVED });\n }\n\n return next();\n }\n\n private setCurrentUser(opts: { context: TContext; user: IAuthUser }) {\n const { context, user } = opts;\n context.set(Authentication.CURRENT_USER, user);\n\n if (user?.userId) {\n context.set(Authentication.AUDIT_USER_ID, user.userId);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"authentication.provider.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authenticate/providers/authentication.provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TContext } from '@/base/controllers/common/types';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport type { IProvider } from '@venizia/ignis-inversion';\nimport type { Env } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport type { IAuthUser, TAuthenticateFn, TAuthMode } from '../common';\nimport { Authentication, AuthenticationErrors, AuthenticationModes } from '../common';\nimport { AuthenticationStrategyRegistry } from '../strategies/strategy-registry';\n\nexport class AuthenticationProvider<RouteEnv extends Env = Env>\n extends BaseHelper\n implements IProvider<TAuthenticateFn<RouteEnv>>\n{\n constructor() {\n super({ scope: AuthenticationProvider.name });\n }\n\n value(): TAuthenticateFn<RouteEnv> {\n return (opts) => {\n return this.createAuthenticateMiddleware(opts);\n };\n }\n\n private createAuthenticateMiddleware(opts: { strategies: string[]; mode?: TAuthMode }) {\n const { strategies, mode = AuthenticationModes.ANY } = opts;\n const registry = AuthenticationStrategyRegistry.getInstance();\n\n return createMiddleware(async (context, next) => {\n const isSkipAuthenticate = context.get(Authentication.SKIP_AUTHENTICATION);\n if (isSkipAuthenticate) {\n this.logger\n .for(this.createAuthenticateMiddleware.name)\n .debug('SKIP checking authentication | path: %s', context.req.path);\n return next();\n }\n\n const isAuthenticated = context.get(Authentication.CURRENT_USER);\n if (isAuthenticated) {\n return next();\n }\n\n switch (mode) {\n case AuthenticationModes.ANY: {\n await this.executeAnyMode({\n context: context as TContext,\n strategies,\n registry,\n next,\n });\n return;\n }\n case AuthenticationModes.ALL: {\n await this.executeAllMode({\n context: context as TContext,\n strategies,\n registry,\n next,\n });\n return;\n }\n default: {\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: `Invalid authentication mode | mode: ${mode}`,\n });\n }\n }\n });\n }\n\n private async executeAnyMode(opts: {\n context: TContext;\n strategies: string[];\n registry: AuthenticationStrategyRegistry;\n next: () => Promise<void>;\n }) {\n const { context, strategies, registry, next } = opts;\n\n // The first strategy's failure is the primary one - kept so the 401 carries WHY, instead of only which strategies were tried.\n let primaryFailure: unknown;\n\n for (const strategyName of strategies) {\n try {\n const strategy = registry.resolveStrategy({ name: strategyName });\n const user = await strategy.authenticate(context);\n this.setCurrentUser({ context, user });\n break;\n } catch (error) {\n primaryFailure ??= error;\n this.logger\n .for(this.executeAnyMode.name)\n .debug('Strategy %s failed, trying next... | Error: %s', strategyName, error);\n }\n }\n\n const currentUser = context.get(Authentication.CURRENT_USER);\n if (!currentUser) {\n throw getError({\n error: AuthenticationErrors.FAILED,\n message: `Authentication failed. Tried strategies: ${strategies.join(', ')}`,\n logLevel: 'warn',\n cause: primaryFailure,\n });\n }\n\n await next();\n }\n\n private async executeAllMode(opts: {\n context: TContext;\n strategies: string[];\n registry: AuthenticationStrategyRegistry;\n next: () => Promise<void>;\n }) {\n const { context, strategies, registry, next } = opts;\n\n // Use the first strategy's user as the identity source - all must succeed but first wins for identity\n let authUser: IAuthUser | null = null;\n\n for (const strategyName of strategies) {\n const strategy = registry.resolveStrategy({ name: strategyName });\n const user = await strategy.authenticate(context);\n\n authUser ??= user;\n }\n\n if (authUser?.userId) {\n this.setCurrentUser({ context, user: authUser });\n } else {\n this.logger\n .for(this.executeAllMode.name)\n .error(\n 'Failed to identify authenticated user | user: %j | userId: %s',\n authUser,\n authUser?.userId,\n );\n throw getError({ error: AuthenticationErrors.USER_UNRESOLVED });\n }\n\n return next();\n }\n\n private setCurrentUser(opts: { context: TContext; user: IAuthUser }) {\n const { context, user } = opts;\n context.set(Authentication.CURRENT_USER, user);\n\n if (user?.userId) {\n context.set(Authentication.AUDIT_USER_ID, user.userId);\n }\n }\n}\n"]}
@@ -45,7 +45,7 @@ class AuthenticationStrategyRegistry extends base_1.AbstractAuthRegistry {
45
45
  if (names.length === 0 || this.descriptors.size === 0) {
46
46
  return [];
47
47
  }
48
- return names.filter(name => !this.has({ name }));
48
+ return names.filter((name) => !this.has({ name }));
49
49
  }
50
50
  /**
51
51
  * Refuses to continue past an unregistered name. For an APPLICATION's own startup check.
@@ -1 +1 @@
1
- {"version":3,"file":"strategy-registry.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authenticate/strategies/strategy-registry.ts"],"names":[],"mappings":";;;AACA,+DAA2D;AAE3D,sDAAuD;AACvD,qCAAkD;AAElD,sCAA2C;AAE3C,MAAa,8BAA+B,SAAQ,2BAA6C;aAC/E,uBAAkB,GAAG,kCAAkC,CAAC;IAExE;QACE,KAAK,CAAC,EAAE,KAAK,EAAE,8BAA8B,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,OAAO,gCAAc,CAAC,OAAO,CAAC;YAC5B,GAAG,EAAE,8BAA8B,CAAC,kBAAkB;YACtD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,8BAA8B,EAAE;SACnD,CAAC,CAAC;IACL,CAAC;IAES,gBAAgB;QACxB,OAAO,uBAAc,CAAC,uBAAuB,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,IAGR;QACC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAEvC,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,kBAAkB,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,eAAe,CAAC,IAAsB;QACpC,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,IAAyB;QACxC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAEvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAyC;QACxD,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QAExC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,IAAA,eAAQ,EAAC;YACb,OAAO,EAAE,IAAI,KAAK,qDAAqD,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,4FAA4F;SACvO,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,IAAyC;QAC1D,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QAExC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM;aACR,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;aACjC,KAAK,CACJ,uHAAuH,EACvH,KAAK,EACL,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EACvB,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3B,CAAC;IACN,CAAC;;AApGH,wEAqGC","sourcesContent":["import type { Container } from '@/helpers/inversion/container';\nimport { SingletonRealm } from '@/helpers/singleton-realm';\nimport type { TClass } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { AbstractAuthRegistry } from '../../base';\nimport type { IAuthenticationStrategy } from '../common';\nimport { Authentication } from '../common';\n\nexport class AuthenticationStrategyRegistry extends AbstractAuthRegistry<IAuthenticationStrategy> {\n static readonly SINGLETON_REAL_KEY = 'authentication-strategy-registry';\n\n constructor() {\n super({ scope: AuthenticationStrategyRegistry.name });\n }\n\n static getInstance() {\n return SingletonRealm.resolve({\n key: AuthenticationStrategyRegistry.SINGLETON_REAL_KEY,\n create: () => new AuthenticationStrategyRegistry(),\n });\n }\n\n protected getBindingPrefix(): string {\n return Authentication.AUTHENTICATION_STRATEGY;\n }\n\n register(opts: {\n container: Container;\n strategies: { strategy: TClass<IAuthenticationStrategy>; name: string }[];\n }) {\n const { container, strategies } = opts;\n\n for (const { strategy, name } of strategies) {\n this.registerDescriptor({ container, target: strategy, name });\n }\n\n return this;\n }\n\n resolveStrategy(opts: { name: string }): IAuthenticationStrategy {\n return this.resolveDescriptor(opts);\n }\n\n /**\n * The names on this list that no registered strategy answers to.\n *\n * An EMPTY list yields nothing - it is the framework's own encoding of\n * `authenticate: { skip: true }`, so treating it as a problem would flag every public route.\n *\n * Nothing is reported while the registry is empty. Route configs are built during\n * `registerControllers()`, after `preConfigure()` and `registerComponents()`, so a real\n * application has registered by then; an empty registry means this is running outside that\n * lifecycle - a unit test on a controller - where no name could resolve either way.\n */\n findUnregistered(opts: { names: string[] }): string[] {\n const { names } = opts;\n\n if (names.length === 0 || this.descriptors.size === 0) {\n return [];\n }\n\n return names.filter(name => !this.has({ name }));\n }\n\n /**\n * Refuses to continue past an unregistered name. For an APPLICATION's own startup check.\n *\n * The framework does NOT call this - it reports instead. A hard failure cannot be the default\n * here: a route listing several strategies in ANY mode tolerates one that does not resolve, and\n * `defineAuthController` hard-codes `'jwt'` on four of its routes, so an application that\n * registers its JWT strategy under a different name works today and would stop booting.\n */\n assertRegistered(opts: { names: string[]; scope?: string }): void {\n const { names, scope = 'route' } = opts;\n\n const unregistered = this.findUnregistered({ names });\n if (unregistered.length === 0) {\n return;\n }\n\n throw getError({\n message: `[${scope}] Unknown authentication strategy | unregistered: ${unregistered.join(', ')} | registered: ${this.getNames().join(', ')} | register it with AuthenticationStrategyRegistry.register() before controllers are bound`,\n });\n }\n\n /**\n * Names an unregistered strategy at boot, at a level someone sees. Never throws.\n *\n * This is what replaces the guard the open `TAuthStrategy` gave up: `resolveStrategy` throws at\n * request time, the provider's ANY mode swallows it at DEBUG, and the route 401s with nothing to\n * explain why.\n */\n reportUnregistered(opts: { names: string[]; scope?: string }): void {\n const { names, scope = 'route' } = opts;\n\n const unregistered = this.findUnregistered({ names });\n if (unregistered.length === 0) {\n return;\n }\n\n this.logger\n .for(this.reportUnregistered.name)\n .error(\n '[%s] Unknown authentication strategy - requests relying on it cannot authenticate | unregistered: %s | registered: %s',\n scope,\n unregistered.join(', '),\n this.getNames().join(', '),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"strategy-registry.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authenticate/strategies/strategy-registry.ts"],"names":[],"mappings":";;;AACA,+DAA2D;AAE3D,sDAAuD;AACvD,qCAAkD;AAElD,sCAA2C;AAE3C,MAAa,8BAA+B,SAAQ,2BAA6C;aAC/E,uBAAkB,GAAG,kCAAkC,CAAC;IAExE;QACE,KAAK,CAAC,EAAE,KAAK,EAAE,8BAA8B,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,OAAO,gCAAc,CAAC,OAAO,CAAC;YAC5B,GAAG,EAAE,8BAA8B,CAAC,kBAAkB;YACtD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,8BAA8B,EAAE;SACnD,CAAC,CAAC;IACL,CAAC;IAES,gBAAgB;QACxB,OAAO,uBAAc,CAAC,uBAAuB,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,IAGR;QACC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAEvC,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,kBAAkB,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,eAAe,CAAC,IAAsB;QACpC,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,IAAyB;QACxC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAEvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAyC;QACxD,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QAExC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,IAAA,eAAQ,EAAC;YACb,OAAO,EAAE,IAAI,KAAK,qDAAqD,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,4FAA4F;SACvO,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,IAAyC;QAC1D,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QAExC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM;aACR,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;aACjC,KAAK,CACJ,uHAAuH,EACvH,KAAK,EACL,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EACvB,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3B,CAAC;IACN,CAAC;;AApGH,wEAqGC","sourcesContent":["import type { Container } from '@/helpers/inversion/container';\nimport { SingletonRealm } from '@/helpers/singleton-realm';\nimport type { TClass } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { AbstractAuthRegistry } from '../../base';\nimport type { IAuthenticationStrategy } from '../common';\nimport { Authentication } from '../common';\n\nexport class AuthenticationStrategyRegistry extends AbstractAuthRegistry<IAuthenticationStrategy> {\n static readonly SINGLETON_REAL_KEY = 'authentication-strategy-registry';\n\n constructor() {\n super({ scope: AuthenticationStrategyRegistry.name });\n }\n\n static getInstance() {\n return SingletonRealm.resolve({\n key: AuthenticationStrategyRegistry.SINGLETON_REAL_KEY,\n create: () => new AuthenticationStrategyRegistry(),\n });\n }\n\n protected getBindingPrefix(): string {\n return Authentication.AUTHENTICATION_STRATEGY;\n }\n\n register(opts: {\n container: Container;\n strategies: { strategy: TClass<IAuthenticationStrategy>; name: string }[];\n }) {\n const { container, strategies } = opts;\n\n for (const { strategy, name } of strategies) {\n this.registerDescriptor({ container, target: strategy, name });\n }\n\n return this;\n }\n\n resolveStrategy(opts: { name: string }): IAuthenticationStrategy {\n return this.resolveDescriptor(opts);\n }\n\n /**\n * The names on this list that no registered strategy answers to.\n *\n * An EMPTY list yields nothing - it is the framework's own encoding of\n * `authenticate: { skip: true }`, so treating it as a problem would flag every public route.\n *\n * Nothing is reported while the registry is empty. Route configs are built during\n * `registerControllers()`, after `preConfigure()` and `registerComponents()`, so a real\n * application has registered by then; an empty registry means this is running outside that\n * lifecycle - a unit test on a controller - where no name could resolve either way.\n */\n findUnregistered(opts: { names: string[] }): string[] {\n const { names } = opts;\n\n if (names.length === 0 || this.descriptors.size === 0) {\n return [];\n }\n\n return names.filter((name) => !this.has({ name }));\n }\n\n /**\n * Refuses to continue past an unregistered name. For an APPLICATION's own startup check.\n *\n * The framework does NOT call this - it reports instead. A hard failure cannot be the default\n * here: a route listing several strategies in ANY mode tolerates one that does not resolve, and\n * `defineAuthController` hard-codes `'jwt'` on four of its routes, so an application that\n * registers its JWT strategy under a different name works today and would stop booting.\n */\n assertRegistered(opts: { names: string[]; scope?: string }): void {\n const { names, scope = 'route' } = opts;\n\n const unregistered = this.findUnregistered({ names });\n if (unregistered.length === 0) {\n return;\n }\n\n throw getError({\n message: `[${scope}] Unknown authentication strategy | unregistered: ${unregistered.join(', ')} | registered: ${this.getNames().join(', ')} | register it with AuthenticationStrategyRegistry.register() before controllers are bound`,\n });\n }\n\n /**\n * Names an unregistered strategy at boot, at a level someone sees. Never throws.\n *\n * This is what replaces the guard the open `TAuthStrategy` gave up: `resolveStrategy` throws at\n * request time, the provider's ANY mode swallows it at DEBUG, and the route 401s with nothing to\n * explain why.\n */\n reportUnregistered(opts: { names: string[]; scope?: string }): void {\n const { names, scope = 'route' } = opts;\n\n const unregistered = this.findUnregistered({ names });\n if (unregistered.length === 0) {\n return;\n }\n\n this.logger\n .for(this.reportUnregistered.name)\n .error(\n '[%s] Unknown authentication strategy - requests relying on it cannot authenticate | unregistered: %s | registered: %s',\n scope,\n unregistered.join(', '),\n this.getNames().join(', '),\n );\n }\n}\n"]}
@@ -139,9 +139,9 @@ class GrantBuilder extends core_1.BaseHelper {
139
139
  if (!ops.length) {
140
140
  throw (0, core_1.getError)({ message: '[planGrant] intent.ops must not be empty.' });
141
141
  }
142
- const subjectCatalog = opts.catalog.filter(entry => entry.subject === opts.resource.subject);
143
- const byMethod = new Map(subjectCatalog.map(entry => [entry.method, entry]));
144
- const unknown = ops.filter(op => !byMethod.has(op));
142
+ const subjectCatalog = opts.catalog.filter((entry) => entry.subject === opts.resource.subject);
143
+ const byMethod = new Map(subjectCatalog.map((entry) => [entry.method, entry]));
144
+ const unknown = ops.filter((op) => !byMethod.has(op));
145
145
  if (unknown.length) {
146
146
  throw (0, core_1.getError)({
147
147
  message: `[planGrant] Unknown operations for resource "${opts.resource.subject}": ${unknown.join(', ')}`,
@@ -159,7 +159,7 @@ class GrantBuilder extends core_1.BaseHelper {
159
159
  if (opts.exact !== true) {
160
160
  this.collapseRemainingIntoTiers({ subjectCatalog, remaining, rows, tierRow });
161
161
  }
162
- const leftover = ops.filter(op => remaining.has(op));
162
+ const leftover = ops.filter((op) => remaining.has(op));
163
163
  if (!leftover.length) {
164
164
  return rows;
165
165
  }
@@ -193,17 +193,17 @@ class GrantBuilder extends core_1.BaseHelper {
193
193
  collapseRemainingIntoTiers(opts) {
194
194
  const { subjectCatalog, remaining, rows, tierRow } = opts;
195
195
  // manage equals read+write+execute only when the subject has at least one operation in EACH narrow tier; otherwise manage also covers a future tier, which is more than the narrow tiers confer today.
196
- const spansAllNarrowTiers = GrantBuilder.NARROW_TIERS.every(tier => {
196
+ const spansAllNarrowTiers = GrantBuilder.NARROW_TIERS.every((tier) => {
197
197
  const covered = this.actionsCoveredBy({ tier });
198
- return subjectCatalog.some(entry => covered.has(entry.action));
198
+ return subjectCatalog.some((entry) => covered.has(entry.action));
199
199
  });
200
200
  const manageCovered = this.actionsCoveredBy({ tier: common_1.AuthorizationActions.MANAGE });
201
201
  const manageOps = subjectCatalog
202
- .filter(entry => manageCovered.has(entry.action))
203
- .map(entry => entry.method);
202
+ .filter((entry) => manageCovered.has(entry.action))
203
+ .map((entry) => entry.method);
204
204
  if (spansAllNarrowTiers &&
205
205
  manageOps.length &&
206
- manageOps.every(method => remaining.has(method))) {
206
+ manageOps.every((method) => remaining.has(method))) {
207
207
  rows.push(tierRow(common_1.AuthorizationActions.MANAGE));
208
208
  for (const method of manageOps) {
209
209
  remaining.delete(method);
@@ -213,9 +213,9 @@ class GrantBuilder extends core_1.BaseHelper {
213
213
  for (const tier of GrantBuilder.NARROW_TIERS) {
214
214
  const covered = this.actionsCoveredBy({ tier });
215
215
  const methods = subjectCatalog
216
- .filter(entry => covered.has(entry.action))
217
- .map(entry => entry.method);
218
- if (!methods.length || !methods.every(method => remaining.has(method))) {
216
+ .filter((entry) => covered.has(entry.action))
217
+ .map((entry) => entry.method);
218
+ if (!methods.length || !methods.every((method) => remaining.has(method))) {
219
219
  continue;
220
220
  }
221
221
  rows.push(tierRow(tier));
@@ -1 +1 @@
1
- {"version":3,"file":"grant.builder.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authorize/builders/grant.builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { SingletonRealm } from '@/helpers/singleton-realm';\nimport type { IdType } from '@/base';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { type TNullable } from '@venizia/ignis-helpers/common';\nimport {\n AuthorizationActions,\n AuthorizationDecisions,\n type TAuthorizationAction,\n type TAuthorizationDecision,\n type TGrantIntent,\n type TPlannedGrantRow,\n} from '../common';\nimport { AuthorizationPolicyBuilder, type TPolicyDomainInput } from './policy.builder';\n\n/** One closure pass over the action lattice: adds every child reachable from an already-covered parent, reporting whether the set grew. */\nconst expandCoveredActions = (opts: { covered: Set<string> }): boolean => {\n const { covered } = opts;\n let grew = false;\n\n for (const edge of AuthorizationActions.LATTICE) {\n if (!covered.has(edge.parent) || covered.has(edge.child)) {\n continue;\n }\n\n covered.add(edge.child);\n grew = true;\n }\n\n return grew;\n};\n\nexport class GrantBuilder extends BaseHelper {\n static readonly SINGLETON_REAL_KEY = 'grant-builder';\n\n /** Tiers a caller may ask for; `custom` is an encoding marker and is never a valid intent. */\n private static readonly PLANNABLE_TIERS = new Set<string>([\n AuthorizationActions.READ,\n AuthorizationActions.WRITE,\n AuthorizationActions.EXECUTE,\n AuthorizationActions.MANAGE,\n ]);\n\n /** Tried after `manage`; disjoint from each other, since an operation has one catalogued action. */\n private static readonly NARROW_TIERS: ReadonlyArray<TAuthorizationAction> = [\n AuthorizationActions.READ,\n AuthorizationActions.WRITE,\n AuthorizationActions.EXECUTE,\n ];\n\n constructor() {\n super({ scope: GrantBuilder.name });\n }\n\n static getInstance() {\n return SingletonRealm.resolve({\n key: GrantBuilder.SINGLETON_REAL_KEY,\n create: () => new GrantBuilder(),\n });\n }\n\n decodeMetadata<MetadataType = unknown>(opts: { metadata: MetadataType }) {\n if (typeof opts.metadata !== 'string') {\n return opts.metadata;\n }\n\n try {\n return JSON.parse(opts.metadata);\n } catch (error) {\n this.logger\n .for(this.decodeMetadata.name)\n .error('Failed to parse metadata | Error: %s', error);\n return null;\n }\n }\n\n /** Read `{ ops }` off a grant row's metadata, or null when the shape is unusable. Callers treat null as a defect to log and skip - never as an empty grant. */\n parseCustomGrantMetadata(opts: { metadata: unknown }): { ops: string[] } | null {\n const decoded = this.decodeMetadata(opts);\n\n if (typeof decoded !== 'object' || decoded === null || Array.isArray(decoded)) {\n return null;\n }\n\n const ops = (decoded as { ops?: unknown }).ops;\n if (!Array.isArray(ops) || ops.length === 0) {\n return null;\n }\n\n const seen = new Set<string>();\n const unique: string[] = [];\n\n for (const op of ops) {\n if (typeof op !== 'string' || op.length === 0) {\n return null;\n }\n\n if (!seen.has(op)) {\n seen.add(op);\n unique.push(op);\n }\n }\n\n return { ops: unique };\n }\n\n /** Split operation names into those present in the catalog for `subject` and those that are not. Pure - the caller supplies the catalog slice; the adapter re-runs this independently at read time. */\n validateCustomGrantOps(opts: {\n ops: string[];\n subject: string;\n catalog: Array<{ subject: string; method: string }>;\n }): { valid: string[]; unknown: string[] } {\n const known = new Set<string>();\n\n for (const entry of opts.catalog) {\n if (entry.subject === opts.subject) {\n known.add(entry.method);\n }\n }\n\n const valid: string[] = [];\n const unknown: string[] = [];\n\n for (const op of opts.ops) {\n if (known.has(op)) {\n valid.push(op);\n continue;\n }\n\n unknown.push(op);\n }\n\n return { valid, unknown };\n }\n\n /** Actions a tier confers, derived from LATTICE rather than hardcoded so the two cannot drift. */\n actionsCoveredBy(opts: { tier: TAuthorizationAction }): Set<string> {\n const covered = new Set<string>([opts.tier]);\n\n let grew = true;\n while (grew) {\n grew = expandCoveredActions({ covered });\n }\n\n return covered;\n }\n\n /** Decide which rows express an intent: a custom row is a last resort, so as much of the selection as possible collapses into tier grants first. `exact` disables collapsing when the caller means these operations and no future ones. Pure - the caller supplies the catalog and persists. */\n planGrant(opts: {\n subject: { type: string; id: IdType };\n resource: { type: string; id: IdType; subject: string };\n intent: TGrantIntent;\n catalog: Array<{ subject: string; method: string; code: string; action: string }>;\n domain?: TNullable<TPolicyDomainInput>;\n effect?: TAuthorizationDecision;\n supportsCustomMetadata?: boolean;\n exact?: boolean;\n }): TPlannedGrantRow[] {\n const effect = opts.effect ?? AuthorizationDecisions.ALLOW;\n const domain = opts.domain ?? null;\n\n if ('tier' in opts.intent) {\n if (!GrantBuilder.PLANNABLE_TIERS.has(opts.intent.tier)) {\n throw getError({\n message: `[planGrant] Invalid tier: ${opts.intent.tier} | Valids: [${[...GrantBuilder.PLANNABLE_TIERS].join(', ')}]`,\n });\n }\n\n return [\n AuthorizationPolicyBuilder.grant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: opts.resource.id },\n action: opts.intent.tier,\n domain,\n effect,\n }),\n ];\n }\n\n const seen = new Set<string>();\n const ops: string[] = [];\n\n for (const op of opts.intent.ops) {\n if (seen.has(op)) {\n continue;\n }\n\n seen.add(op);\n ops.push(op);\n }\n\n if (!ops.length) {\n throw getError({ message: '[planGrant] intent.ops must not be empty.' });\n }\n\n const subjectCatalog = opts.catalog.filter(entry => entry.subject === opts.resource.subject);\n const byMethod = new Map(subjectCatalog.map(entry => [entry.method, entry]));\n\n const unknown = ops.filter(op => !byMethod.has(op));\n if (unknown.length) {\n throw getError({\n message: `[planGrant] Unknown operations for resource \"${opts.resource.subject}\": ${unknown.join(', ')}`,\n });\n }\n\n const tierRow = (tier: TAuthorizationAction) =>\n AuthorizationPolicyBuilder.grant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: opts.resource.id },\n action: tier,\n domain,\n effect,\n });\n\n const rows: TPlannedGrantRow[] = [];\n const remaining = new Set(ops);\n\n if (opts.exact !== true) {\n this.collapseRemainingIntoTiers({ subjectCatalog, remaining, rows, tierRow });\n }\n\n const leftover = ops.filter(op => remaining.has(op));\n\n if (!leftover.length) {\n return rows;\n }\n\n const isPerOperationGrant = leftover.length === 1 || opts.supportsCustomMetadata === false;\n\n if (!isPerOperationGrant) {\n rows.push(\n AuthorizationPolicyBuilder.customGrant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: opts.resource.id },\n ops: leftover,\n domain,\n effect,\n }),\n );\n\n return rows;\n }\n\n for (const op of leftover) {\n const entry = byMethod.get(op);\n if (!entry) {\n throw getError({ message: `[planGrant] No catalog entry for operation \"${op}\".` });\n }\n\n rows.push(\n AuthorizationPolicyBuilder.grant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: entry.code },\n action: entry.action,\n domain,\n effect,\n }),\n );\n }\n\n return rows;\n }\n\n /** Collapse `remaining` into the fewest tier grants, mutating `remaining` and appending to `rows`. */\n protected collapseRemainingIntoTiers(opts: {\n subjectCatalog: Array<{ subject: string; method: string; code: string; action: string }>;\n remaining: Set<string>;\n rows: TPlannedGrantRow[];\n tierRow: (tier: TAuthorizationAction) => TPlannedGrantRow;\n }): void {\n const { subjectCatalog, remaining, rows, tierRow } = opts;\n\n // manage equals read+write+execute only when the subject has at least one operation in EACH narrow tier; otherwise manage also covers a future tier, which is more than the narrow tiers confer today.\n const spansAllNarrowTiers = GrantBuilder.NARROW_TIERS.every(tier => {\n const covered = this.actionsCoveredBy({ tier });\n return subjectCatalog.some(entry => covered.has(entry.action));\n });\n\n const manageCovered = this.actionsCoveredBy({ tier: AuthorizationActions.MANAGE });\n const manageOps = subjectCatalog\n .filter(entry => manageCovered.has(entry.action))\n .map(entry => entry.method);\n\n if (\n spansAllNarrowTiers &&\n manageOps.length &&\n manageOps.every(method => remaining.has(method))\n ) {\n rows.push(tierRow(AuthorizationActions.MANAGE));\n for (const method of manageOps) {\n remaining.delete(method);\n }\n\n return;\n }\n\n for (const tier of GrantBuilder.NARROW_TIERS) {\n const covered = this.actionsCoveredBy({ tier });\n const methods = subjectCatalog\n .filter(entry => covered.has(entry.action))\n .map(entry => entry.method);\n\n if (!methods.length || !methods.every(method => remaining.has(method))) {\n continue;\n }\n\n rows.push(tierRow(tier));\n for (const method of methods) {\n remaining.delete(method);\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"grant.builder.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authorize/builders/grant.builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { SingletonRealm } from '@/helpers/singleton-realm';\nimport type { IdType } from '@/base';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { type TNullable } from '@venizia/ignis-helpers/common';\nimport {\n AuthorizationActions,\n AuthorizationDecisions,\n type TAuthorizationAction,\n type TAuthorizationDecision,\n type TGrantIntent,\n type TPlannedGrantRow,\n} from '../common';\nimport { AuthorizationPolicyBuilder, type TPolicyDomainInput } from './policy.builder';\n\n/** One closure pass over the action lattice: adds every child reachable from an already-covered parent, reporting whether the set grew. */\nconst expandCoveredActions = (opts: { covered: Set<string> }): boolean => {\n const { covered } = opts;\n let grew = false;\n\n for (const edge of AuthorizationActions.LATTICE) {\n if (!covered.has(edge.parent) || covered.has(edge.child)) {\n continue;\n }\n\n covered.add(edge.child);\n grew = true;\n }\n\n return grew;\n};\n\nexport class GrantBuilder extends BaseHelper {\n static readonly SINGLETON_REAL_KEY = 'grant-builder';\n\n /** Tiers a caller may ask for; `custom` is an encoding marker and is never a valid intent. */\n private static readonly PLANNABLE_TIERS = new Set<string>([\n AuthorizationActions.READ,\n AuthorizationActions.WRITE,\n AuthorizationActions.EXECUTE,\n AuthorizationActions.MANAGE,\n ]);\n\n /** Tried after `manage`; disjoint from each other, since an operation has one catalogued action. */\n private static readonly NARROW_TIERS: ReadonlyArray<TAuthorizationAction> = [\n AuthorizationActions.READ,\n AuthorizationActions.WRITE,\n AuthorizationActions.EXECUTE,\n ];\n\n constructor() {\n super({ scope: GrantBuilder.name });\n }\n\n static getInstance() {\n return SingletonRealm.resolve({\n key: GrantBuilder.SINGLETON_REAL_KEY,\n create: () => new GrantBuilder(),\n });\n }\n\n decodeMetadata<MetadataType = unknown>(opts: { metadata: MetadataType }) {\n if (typeof opts.metadata !== 'string') {\n return opts.metadata;\n }\n\n try {\n return JSON.parse(opts.metadata);\n } catch (error) {\n this.logger\n .for(this.decodeMetadata.name)\n .error('Failed to parse metadata | Error: %s', error);\n return null;\n }\n }\n\n /** Read `{ ops }` off a grant row's metadata, or null when the shape is unusable. Callers treat null as a defect to log and skip - never as an empty grant. */\n parseCustomGrantMetadata(opts: { metadata: unknown }): { ops: string[] } | null {\n const decoded = this.decodeMetadata(opts);\n\n if (typeof decoded !== 'object' || decoded === null || Array.isArray(decoded)) {\n return null;\n }\n\n const ops = (decoded as { ops?: unknown }).ops;\n if (!Array.isArray(ops) || ops.length === 0) {\n return null;\n }\n\n const seen = new Set<string>();\n const unique: string[] = [];\n\n for (const op of ops) {\n if (typeof op !== 'string' || op.length === 0) {\n return null;\n }\n\n if (!seen.has(op)) {\n seen.add(op);\n unique.push(op);\n }\n }\n\n return { ops: unique };\n }\n\n /** Split operation names into those present in the catalog for `subject` and those that are not. Pure - the caller supplies the catalog slice; the adapter re-runs this independently at read time. */\n validateCustomGrantOps(opts: {\n ops: string[];\n subject: string;\n catalog: Array<{ subject: string; method: string }>;\n }): { valid: string[]; unknown: string[] } {\n const known = new Set<string>();\n\n for (const entry of opts.catalog) {\n if (entry.subject === opts.subject) {\n known.add(entry.method);\n }\n }\n\n const valid: string[] = [];\n const unknown: string[] = [];\n\n for (const op of opts.ops) {\n if (known.has(op)) {\n valid.push(op);\n continue;\n }\n\n unknown.push(op);\n }\n\n return { valid, unknown };\n }\n\n /** Actions a tier confers, derived from LATTICE rather than hardcoded so the two cannot drift. */\n actionsCoveredBy(opts: { tier: TAuthorizationAction }): Set<string> {\n const covered = new Set<string>([opts.tier]);\n\n let grew = true;\n while (grew) {\n grew = expandCoveredActions({ covered });\n }\n\n return covered;\n }\n\n /** Decide which rows express an intent: a custom row is a last resort, so as much of the selection as possible collapses into tier grants first. `exact` disables collapsing when the caller means these operations and no future ones. Pure - the caller supplies the catalog and persists. */\n planGrant(opts: {\n subject: { type: string; id: IdType };\n resource: { type: string; id: IdType; subject: string };\n intent: TGrantIntent;\n catalog: Array<{ subject: string; method: string; code: string; action: string }>;\n domain?: TNullable<TPolicyDomainInput>;\n effect?: TAuthorizationDecision;\n supportsCustomMetadata?: boolean;\n exact?: boolean;\n }): TPlannedGrantRow[] {\n const effect = opts.effect ?? AuthorizationDecisions.ALLOW;\n const domain = opts.domain ?? null;\n\n if ('tier' in opts.intent) {\n if (!GrantBuilder.PLANNABLE_TIERS.has(opts.intent.tier)) {\n throw getError({\n message: `[planGrant] Invalid tier: ${opts.intent.tier} | Valids: [${[...GrantBuilder.PLANNABLE_TIERS].join(', ')}]`,\n });\n }\n\n return [\n AuthorizationPolicyBuilder.grant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: opts.resource.id },\n action: opts.intent.tier,\n domain,\n effect,\n }),\n ];\n }\n\n const seen = new Set<string>();\n const ops: string[] = [];\n\n for (const op of opts.intent.ops) {\n if (seen.has(op)) {\n continue;\n }\n\n seen.add(op);\n ops.push(op);\n }\n\n if (!ops.length) {\n throw getError({ message: '[planGrant] intent.ops must not be empty.' });\n }\n\n const subjectCatalog = opts.catalog.filter((entry) => entry.subject === opts.resource.subject);\n const byMethod = new Map(subjectCatalog.map((entry) => [entry.method, entry]));\n\n const unknown = ops.filter((op) => !byMethod.has(op));\n if (unknown.length) {\n throw getError({\n message: `[planGrant] Unknown operations for resource \"${opts.resource.subject}\": ${unknown.join(', ')}`,\n });\n }\n\n const tierRow = (tier: TAuthorizationAction) =>\n AuthorizationPolicyBuilder.grant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: opts.resource.id },\n action: tier,\n domain,\n effect,\n });\n\n const rows: TPlannedGrantRow[] = [];\n const remaining = new Set(ops);\n\n if (opts.exact !== true) {\n this.collapseRemainingIntoTiers({ subjectCatalog, remaining, rows, tierRow });\n }\n\n const leftover = ops.filter((op) => remaining.has(op));\n\n if (!leftover.length) {\n return rows;\n }\n\n const isPerOperationGrant = leftover.length === 1 || opts.supportsCustomMetadata === false;\n\n if (!isPerOperationGrant) {\n rows.push(\n AuthorizationPolicyBuilder.customGrant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: opts.resource.id },\n ops: leftover,\n domain,\n effect,\n }),\n );\n\n return rows;\n }\n\n for (const op of leftover) {\n const entry = byMethod.get(op);\n if (!entry) {\n throw getError({ message: `[planGrant] No catalog entry for operation \"${op}\".` });\n }\n\n rows.push(\n AuthorizationPolicyBuilder.grant({\n subject: opts.subject,\n permission: { type: opts.resource.type, id: entry.code },\n action: entry.action,\n domain,\n effect,\n }),\n );\n }\n\n return rows;\n }\n\n /** Collapse `remaining` into the fewest tier grants, mutating `remaining` and appending to `rows`. */\n protected collapseRemainingIntoTiers(opts: {\n subjectCatalog: Array<{ subject: string; method: string; code: string; action: string }>;\n remaining: Set<string>;\n rows: TPlannedGrantRow[];\n tierRow: (tier: TAuthorizationAction) => TPlannedGrantRow;\n }): void {\n const { subjectCatalog, remaining, rows, tierRow } = opts;\n\n // manage equals read+write+execute only when the subject has at least one operation in EACH narrow tier; otherwise manage also covers a future tier, which is more than the narrow tiers confer today.\n const spansAllNarrowTiers = GrantBuilder.NARROW_TIERS.every((tier) => {\n const covered = this.actionsCoveredBy({ tier });\n return subjectCatalog.some((entry) => covered.has(entry.action));\n });\n\n const manageCovered = this.actionsCoveredBy({ tier: AuthorizationActions.MANAGE });\n const manageOps = subjectCatalog\n .filter((entry) => manageCovered.has(entry.action))\n .map((entry) => entry.method);\n\n if (\n spansAllNarrowTiers &&\n manageOps.length &&\n manageOps.every((method) => remaining.has(method))\n ) {\n rows.push(tierRow(AuthorizationActions.MANAGE));\n for (const method of manageOps) {\n remaining.delete(method);\n }\n\n return;\n }\n\n for (const tier of GrantBuilder.NARROW_TIERS) {\n const covered = this.actionsCoveredBy({ tier });\n const methods = subjectCatalog\n .filter((entry) => covered.has(entry.action))\n .map((entry) => entry.method);\n\n if (!methods.length || !methods.every((method) => remaining.has(method))) {\n continue;\n }\n\n rows.push(tierRow(tier));\n for (const method of methods) {\n remaining.delete(method);\n }\n }\n }\n}\n"]}
@@ -63,7 +63,7 @@ class AuthorizationPermissionBuilder {
63
63
  /** The CRUD permission set for a subject. `name` (and optional `description`) are per-method formatters, so the app supplies its own labels/i18n; the framework only owns the method-to-action map and the code shape. */
64
64
  static crud(opts) {
65
65
  const methods = opts.methods ?? AuthorizationPermissionBuilder.DEFAULT_CRUD_METHODS;
66
- return methods.map(method => {
66
+ return methods.map((method) => {
67
67
  const action = AuthorizationPermissionBuilder.actionForMethod(method);
68
68
  const ctx = {
69
69
  subject: opts.subject,
@@ -1 +1 @@
1
- {"version":3,"file":"permission.builder.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authorize/builders/permission.builder.ts"],"names":[],"mappings":";;;AAGA,mDAA2D;AAE3D,+RAA+R;AAC/R,MAAa,8BAA8B;IACzC,yFAAyF;aACzE,yBAAoB,GAAG,GAAG,CAAC;IAE3C,gHAAgH;aAChG,mBAAc,GAAmD;QAC/E,IAAI,EAAE,gCAAoB,CAAC,IAAI;QAC/B,QAAQ,EAAE,gCAAoB,CAAC,IAAI;QACnC,OAAO,EAAE,gCAAoB,CAAC,IAAI;QAClC,KAAK,EAAE,gCAAoB,CAAC,IAAI;QAChC,MAAM,EAAE,gCAAoB,CAAC,MAAM;QACnC,UAAU,EAAE,gCAAoB,CAAC,MAAM;QACvC,QAAQ,EAAE,gCAAoB,CAAC,MAAM;QACrC,UAAU,EAAE,gCAAoB,CAAC,MAAM;QACvC,QAAQ,EAAE,gCAAoB,CAAC,MAAM;KACtC,CAAC;IAEF,0DAA0D;aAC1C,yBAAoB,GAA0B;QAC5D,MAAM;QACN,UAAU;QACV,SAAS;QACT,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,UAAU;QACV,YAAY;QACZ,UAAU;KACX,CAAC;IAEF,kHAAkH;IAClH,MAAM,CAAC,eAAe,CAAC,MAAc;QACnC,OAAO,8BAA8B,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,gCAAoB,CAAC,OAAO,CAAC;IAC/F,CAAC;IAED,iHAAiH;IACjH,MAAM,CAAC,SAAS,CAAQ,IAQvB;QACC,OAAO;YACL,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAC3C,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,8BAA8B,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;YAClF,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;YACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;IACJ,CAAC;IAED,iMAAiM;IACjM,MAAM,CAAC,YAAY,CAAQ,IAQ1B;QACC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI;YAClC,MAAM,EAAE,8BAA8B,CAAC,oBAAoB;YAC3D,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,gCAAoB,CAAC,MAAM;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;YACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;IACJ,CAAC;IAED,0NAA0N;IAC1N,MAAM,CAAC,IAAI,CAAQ,IAUlB;QACC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,8BAA8B,CAAC,oBAAoB,CAAC;QAEpF,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC1B,MAAM,MAAM,GAAG,8BAA8B,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YACtE,MAAM,GAAG,GAAsE;gBAC7E,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM;gBACN,MAAM;aACP,CAAC;YAEF,OAAO,8BAA8B,CAAC,SAAS,CAAQ;gBACrD,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM;gBACN,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM;gBACN,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBACpB,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;aAClE,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,2RAA2R;IAC3R,MAAM,CAAC,WAAW,CAAC,SAAiB,EAAE,OAAe;QACnD,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAC7C,CAAC;;AA3HH,wEA4HC","sourcesContent":["import type { IdType } from '@/base';\nimport type { TNullable } from '@venizia/ignis-helpers/common';\nimport type { TAuthorizationAction } from '../common/constants';\nimport { AuthorizationActions } from '../common/constants';\n\n/** Builders for `Permission` catalog rows (the `obj` axis the scoped matcher resolves), generic over `TName` so i18n and plain-text apps both fit; only framework-owned columns (code/subject/method/action/scope/description/parentId) are produced - app columns are added by the caller. */\nexport class AuthorizationPermissionBuilder {\n /** Sentinel `method` for a coarse resource node (a grant target that is not a route). */\n static readonly RESOURCE_NODE_METHOD = '*';\n\n /** Standard repository method → base action. Unlisted methods (custom ops, aggregates) resolve to `execute`. */\n static readonly METHOD_ACTIONS: Readonly<Record<string, TAuthorizationAction>> = {\n find: AuthorizationActions.READ,\n findById: AuthorizationActions.READ,\n findOne: AuthorizationActions.READ,\n count: AuthorizationActions.READ,\n create: AuthorizationActions.CREATE,\n updateById: AuthorizationActions.UPDATE,\n updateBy: AuthorizationActions.UPDATE,\n deleteById: AuthorizationActions.DELETE,\n deleteBy: AuthorizationActions.DELETE,\n };\n\n /** The CRUD methods {@link crud} generates by default. */\n static readonly DEFAULT_CRUD_METHODS: ReadonlyArray<string> = [\n 'find',\n 'findById',\n 'findOne',\n 'count',\n 'create',\n 'updateById',\n 'updateBy',\n 'deleteById',\n 'deleteBy',\n ];\n\n /** Base action for a method: a known CRUD method maps to read/create/update/delete; anything else → `execute`. */\n static actionForMethod(method: string): TAuthorizationAction {\n return AuthorizationPermissionBuilder.METHOD_ACTIONS[method] ?? AuthorizationActions.EXECUTE;\n }\n\n /** One operation-level permission, `code = <subject>.<method>`. `action` defaults to {@link actionForMethod}. */\n static operation<TName>(opts: {\n subject: string;\n method: string;\n scope: string;\n name: TName;\n description?: TNullable<TName>;\n action?: TAuthorizationAction;\n parentId?: TNullable<IdType>;\n }) {\n return {\n code: [opts.subject, opts.method].join('.'),\n subject: opts.subject,\n method: opts.method,\n action: opts.action ?? AuthorizationPermissionBuilder.actionForMethod(opts.method),\n scope: opts.scope,\n description: opts.description ?? null,\n parentId: opts.parentId ?? null,\n name: opts.name,\n };\n }\n\n /** A coarse resource node used as a grant target: `code` is the bare name, `method` the {@link RESOURCE_NODE_METHOD} sentinel, `action` defaults to `manage` (grants carry their own action). */\n static resourceNode<TName>(opts: {\n code: string;\n subject?: string;\n scope: string;\n name: TName;\n description?: TNullable<TName>;\n action?: TAuthorizationAction;\n parentId?: TNullable<IdType>;\n }) {\n return {\n code: opts.code,\n subject: opts.subject ?? opts.code,\n method: AuthorizationPermissionBuilder.RESOURCE_NODE_METHOD,\n action: opts.action ?? AuthorizationActions.MANAGE,\n scope: opts.scope,\n description: opts.description ?? null,\n parentId: opts.parentId ?? null,\n name: opts.name,\n };\n }\n\n /** The CRUD permission set for a subject. `name` (and optional `description`) are per-method formatters, so the app supplies its own labels/i18n; the framework only owns the method-to-action map and the code shape. */\n static crud<TName>(opts: {\n subject: string;\n scope: string;\n name: (ctx: { subject: string; method: string; action: TAuthorizationAction }) => TName;\n description?: (ctx: {\n subject: string;\n method: string;\n action: TAuthorizationAction;\n }) => TNullable<TName>;\n methods?: ReadonlyArray<string>;\n }) {\n const methods = opts.methods ?? AuthorizationPermissionBuilder.DEFAULT_CRUD_METHODS;\n\n return methods.map(method => {\n const action = AuthorizationPermissionBuilder.actionForMethod(method);\n const ctx: { subject: string; method: string; action: TAuthorizationAction } = {\n subject: opts.subject,\n method,\n action,\n };\n\n return AuthorizationPermissionBuilder.operation<TName>({\n subject: opts.subject,\n method,\n scope: opts.scope,\n action,\n name: opts.name(ctx),\n description: opts.description ? opts.description(ctx) : undefined,\n });\n });\n }\n\n /** g4 resource matcher (r.obj vs p.obj): derives standard edges (endpoint ⊂ subject ⊂ `*`) from the dotted code {@link operation} produces, while non-standard nesting stays stored g4 edges served by `ResourceRoleManager`. Registered via `enforcer.addFunction` - must stay static. */\n static objectMatch(requested: string, granted: string): boolean {\n if (granted === '*') {\n return true;\n }\n\n if (requested === granted) {\n return true;\n }\n\n return requested.startsWith(`${granted}.`);\n }\n}\n"]}
1
+ {"version":3,"file":"permission.builder.js","sourceRoot":"","sources":["../../../../../../src/base/auth/authorize/builders/permission.builder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IdType } from '@/base';\nimport type { TNullable } from '@venizia/ignis-helpers/common';\nimport type { TAuthorizationAction } from '../common/constants';\nimport { AuthorizationActions } from '../common/constants';\n\n/** Builders for `Permission` catalog rows (the `obj` axis the scoped matcher resolves), generic over `TName` so i18n and plain-text apps both fit; only framework-owned columns (code/subject/method/action/scope/description/parentId) are produced - app columns are added by the caller. */\nexport class AuthorizationPermissionBuilder {\n /** Sentinel `method` for a coarse resource node (a grant target that is not a route). */\n static readonly RESOURCE_NODE_METHOD = '*';\n\n /** Standard repository method → base action. Unlisted methods (custom ops, aggregates) resolve to `execute`. */\n static readonly METHOD_ACTIONS: Readonly<Record<string, TAuthorizationAction>> = {\n find: AuthorizationActions.READ,\n findById: AuthorizationActions.READ,\n findOne: AuthorizationActions.READ,\n count: AuthorizationActions.READ,\n create: AuthorizationActions.CREATE,\n updateById: AuthorizationActions.UPDATE,\n updateBy: AuthorizationActions.UPDATE,\n deleteById: AuthorizationActions.DELETE,\n deleteBy: AuthorizationActions.DELETE,\n };\n\n /** The CRUD methods {@link crud} generates by default. */\n static readonly DEFAULT_CRUD_METHODS: ReadonlyArray<string> = [\n 'find',\n 'findById',\n 'findOne',\n 'count',\n 'create',\n 'updateById',\n 'updateBy',\n 'deleteById',\n 'deleteBy',\n ];\n\n /** Base action for a method: a known CRUD method maps to read/create/update/delete; anything else → `execute`. */\n static actionForMethod(method: string): TAuthorizationAction {\n return AuthorizationPermissionBuilder.METHOD_ACTIONS[method] ?? AuthorizationActions.EXECUTE;\n }\n\n /** One operation-level permission, `code = <subject>.<method>`. `action` defaults to {@link actionForMethod}. */\n static operation<TName>(opts: {\n subject: string;\n method: string;\n scope: string;\n name: TName;\n description?: TNullable<TName>;\n action?: TAuthorizationAction;\n parentId?: TNullable<IdType>;\n }) {\n return {\n code: [opts.subject, opts.method].join('.'),\n subject: opts.subject,\n method: opts.method,\n action: opts.action ?? AuthorizationPermissionBuilder.actionForMethod(opts.method),\n scope: opts.scope,\n description: opts.description ?? null,\n parentId: opts.parentId ?? null,\n name: opts.name,\n };\n }\n\n /** A coarse resource node used as a grant target: `code` is the bare name, `method` the {@link RESOURCE_NODE_METHOD} sentinel, `action` defaults to `manage` (grants carry their own action). */\n static resourceNode<TName>(opts: {\n code: string;\n subject?: string;\n scope: string;\n name: TName;\n description?: TNullable<TName>;\n action?: TAuthorizationAction;\n parentId?: TNullable<IdType>;\n }) {\n return {\n code: opts.code,\n subject: opts.subject ?? opts.code,\n method: AuthorizationPermissionBuilder.RESOURCE_NODE_METHOD,\n action: opts.action ?? AuthorizationActions.MANAGE,\n scope: opts.scope,\n description: opts.description ?? null,\n parentId: opts.parentId ?? null,\n name: opts.name,\n };\n }\n\n /** The CRUD permission set for a subject. `name` (and optional `description`) are per-method formatters, so the app supplies its own labels/i18n; the framework only owns the method-to-action map and the code shape. */\n static crud<TName>(opts: {\n subject: string;\n scope: string;\n name: (ctx: { subject: string; method: string; action: TAuthorizationAction }) => TName;\n description?: (ctx: {\n subject: string;\n method: string;\n action: TAuthorizationAction;\n }) => TNullable<TName>;\n methods?: ReadonlyArray<string>;\n }) {\n const methods = opts.methods ?? AuthorizationPermissionBuilder.DEFAULT_CRUD_METHODS;\n\n return methods.map((method) => {\n const action = AuthorizationPermissionBuilder.actionForMethod(method);\n const ctx: { subject: string; method: string; action: TAuthorizationAction } = {\n subject: opts.subject,\n method,\n action,\n };\n\n return AuthorizationPermissionBuilder.operation<TName>({\n subject: opts.subject,\n method,\n scope: opts.scope,\n action,\n name: opts.name(ctx),\n description: opts.description ? opts.description(ctx) : undefined,\n });\n });\n }\n\n /** g4 resource matcher (r.obj vs p.obj): derives standard edges (endpoint ⊂ subject ⊂ `*`) from the dotted code {@link operation} produces, while non-standard nesting stays stored g4 edges served by `ResourceRoleManager`. Registered via `enforcer.addFunction` - must stay static. */\n static objectMatch(requested: string, granted: string): boolean {\n if (granted === '*') {\n return true;\n }\n\n if (requested === granted) {\n return true;\n }\n\n return requested.startsWith(`${granted}.`);\n }\n}\n"]}