@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.
- package/dist/cjs/base/applications/abstract.js +2 -2
- package/dist/cjs/base/applications/abstract.js.map +1 -1
- package/dist/cjs/base/applications/artifact-group.js +1 -1
- package/dist/cjs/base/applications/artifact-group.js.map +1 -1
- package/dist/cjs/base/applications/artifact-index.js +11 -11
- package/dist/cjs/base/applications/artifact-index.js.map +1 -1
- package/dist/cjs/base/applications/boot-sequence.js +1 -1
- package/dist/cjs/base/applications/boot-sequence.js.map +1 -1
- package/dist/cjs/base/applications/rest.js +5 -5
- package/dist/cjs/base/applications/rest.js.map +1 -1
- package/dist/cjs/base/auth/authenticate/common/codecs.js +2 -2
- package/dist/cjs/base/auth/authenticate/common/codecs.js.map +1 -1
- package/dist/cjs/base/auth/authenticate/providers/authentication.provider.js +1 -1
- package/dist/cjs/base/auth/authenticate/providers/authentication.provider.js.map +1 -1
- package/dist/cjs/base/auth/authenticate/strategies/strategy-registry.js +1 -1
- package/dist/cjs/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
- package/dist/cjs/base/auth/authorize/builders/grant.builder.js +12 -12
- package/dist/cjs/base/auth/authorize/builders/grant.builder.js.map +1 -1
- package/dist/cjs/base/auth/authorize/builders/permission.builder.js +1 -1
- package/dist/cjs/base/auth/authorize/builders/permission.builder.js.map +1 -1
- package/dist/cjs/base/auth/authorize/builders/policy.builder.js +1 -1
- package/dist/cjs/base/auth/authorize/builders/policy.builder.js.map +1 -1
- package/dist/cjs/base/auth/authorize/common/constants/authorization.d.ts.map +1 -1
- package/dist/cjs/base/auth/authorize/common/constants/authorization.js +2 -2
- package/dist/cjs/base/auth/authorize/common/constants/authorization.js.map +1 -1
- package/dist/cjs/base/auth/authorize/enforcers/enforcer-registry.js +1 -1
- package/dist/cjs/base/auth/authorize/enforcers/enforcer-registry.js.map +1 -1
- package/dist/cjs/base/auth/authorize/providers/authorization.provider.js +3 -3
- package/dist/cjs/base/auth/authorize/providers/authorization.provider.js.map +1 -1
- package/dist/cjs/base/controllers/factory/controller.d.ts +2 -2
- package/dist/cjs/base/controllers/factory/controller.d.ts.map +1 -1
- package/dist/cjs/base/controllers/factory/controller.js +1 -0
- package/dist/cjs/base/controllers/factory/controller.js.map +1 -1
- package/dist/cjs/base/controllers/factory/crud/abstract.d.ts +1 -1
- package/dist/cjs/base/controllers/factory/crud/abstract.d.ts.map +1 -1
- package/dist/cjs/base/controllers/factory/crud/abstract.js.map +1 -1
- package/dist/cjs/base/controllers/factory/definition.js +1 -1
- package/dist/cjs/base/controllers/factory/definition.js.map +1 -1
- package/dist/cjs/base/controllers/rest/extras.js +5 -5
- package/dist/cjs/base/controllers/rest/extras.js.map +1 -1
- package/dist/cjs/base/metadata/injectable.js +1 -1
- package/dist/cjs/base/metadata/injectable.js.map +1 -1
- package/dist/cjs/base/metadata/persistents.js +4 -4
- package/dist/cjs/base/metadata/persistents.js.map +1 -1
- package/dist/cjs/base/metadata/routes/controller.js +1 -1
- package/dist/cjs/base/metadata/routes/controller.js.map +1 -1
- package/dist/cjs/base/middlewares/app-error/app-error.middleware.js +3 -3
- package/dist/cjs/base/middlewares/app-error/app-error.middleware.js.map +1 -1
- package/dist/cjs/base/middlewares/app-error/zod.handler.js +2 -2
- package/dist/cjs/base/middlewares/app-error/zod.handler.js.map +1 -1
- package/dist/cjs/base/middlewares/form-body/form-body.middleware.js +2 -2
- package/dist/cjs/base/middlewares/form-body/form-body.middleware.js.map +1 -1
- package/dist/cjs/base/middlewares/not-found/not-found.middleware.js.map +1 -1
- package/dist/cjs/base/models/common/utilities.js +1 -1
- package/dist/cjs/base/models/common/utilities.js.map +1 -1
- package/dist/cjs/base/repositories/common/types/contracts.d.ts +17 -17
- package/dist/cjs/base/repositories/common/types/contracts.d.ts.map +1 -1
- package/dist/cjs/base/repositories/common/types/contracts.js.map +1 -1
- package/dist/cjs/base/repositories/core/abstract.d.ts +17 -17
- package/dist/cjs/base/repositories/core/abstract.d.ts.map +1 -1
- package/dist/cjs/base/repositories/core/abstract.js +4 -3
- package/dist/cjs/base/repositories/core/abstract.js.map +1 -1
- package/dist/cjs/helpers/inversion/mixins/model.mixin.js +1 -1
- package/dist/cjs/helpers/inversion/mixins/model.mixin.js.map +1 -1
- package/dist/cjs/helpers/inversion/mixins/repository.mixin.js +1 -1
- package/dist/cjs/helpers/inversion/mixins/repository.mixin.js.map +1 -1
- package/dist/cjs/repository.d.ts +1 -1
- package/dist/cjs/repository.d.ts.map +1 -1
- package/dist/cjs/repository.js.map +1 -1
- package/dist/esm/base/applications/abstract.js +2 -2
- package/dist/esm/base/applications/abstract.js.map +1 -1
- package/dist/esm/base/applications/artifact-group.js +1 -1
- package/dist/esm/base/applications/artifact-group.js.map +1 -1
- package/dist/esm/base/applications/artifact-index.js +11 -11
- package/dist/esm/base/applications/artifact-index.js.map +1 -1
- package/dist/esm/base/applications/boot-sequence.js +1 -1
- package/dist/esm/base/applications/boot-sequence.js.map +1 -1
- package/dist/esm/base/applications/rest.js +5 -5
- package/dist/esm/base/applications/rest.js.map +1 -1
- package/dist/esm/base/auth/authenticate/common/codecs.js +2 -2
- package/dist/esm/base/auth/authenticate/common/codecs.js.map +1 -1
- package/dist/esm/base/auth/authenticate/providers/authentication.provider.js +1 -1
- package/dist/esm/base/auth/authenticate/providers/authentication.provider.js.map +1 -1
- package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js +1 -1
- package/dist/esm/base/auth/authenticate/strategies/strategy-registry.js.map +1 -1
- package/dist/esm/base/auth/authorize/builders/grant.builder.js +12 -12
- package/dist/esm/base/auth/authorize/builders/grant.builder.js.map +1 -1
- package/dist/esm/base/auth/authorize/builders/permission.builder.js +1 -1
- package/dist/esm/base/auth/authorize/builders/permission.builder.js.map +1 -1
- package/dist/esm/base/auth/authorize/builders/policy.builder.js +1 -1
- package/dist/esm/base/auth/authorize/builders/policy.builder.js.map +1 -1
- package/dist/esm/base/auth/authorize/common/constants/authorization.d.ts.map +1 -1
- package/dist/esm/base/auth/authorize/common/constants/authorization.js +2 -2
- package/dist/esm/base/auth/authorize/common/constants/authorization.js.map +1 -1
- package/dist/esm/base/auth/authorize/enforcers/enforcer-registry.js +1 -1
- package/dist/esm/base/auth/authorize/enforcers/enforcer-registry.js.map +1 -1
- package/dist/esm/base/auth/authorize/providers/authorization.provider.js +3 -3
- package/dist/esm/base/auth/authorize/providers/authorization.provider.js.map +1 -1
- package/dist/esm/base/controllers/factory/controller.d.ts +2 -2
- package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
- package/dist/esm/base/controllers/factory/controller.js +1 -0
- package/dist/esm/base/controllers/factory/controller.js.map +1 -1
- package/dist/esm/base/controllers/factory/crud/abstract.d.ts +1 -1
- package/dist/esm/base/controllers/factory/crud/abstract.d.ts.map +1 -1
- package/dist/esm/base/controllers/factory/crud/abstract.js.map +1 -1
- package/dist/esm/base/controllers/factory/definition.js +1 -1
- package/dist/esm/base/controllers/factory/definition.js.map +1 -1
- package/dist/esm/base/controllers/rest/extras.js +5 -5
- package/dist/esm/base/controllers/rest/extras.js.map +1 -1
- package/dist/esm/base/metadata/injectable.js +1 -1
- package/dist/esm/base/metadata/injectable.js.map +1 -1
- package/dist/esm/base/metadata/persistents.js +4 -4
- package/dist/esm/base/metadata/persistents.js.map +1 -1
- package/dist/esm/base/metadata/routes/controller.js +1 -1
- package/dist/esm/base/metadata/routes/controller.js.map +1 -1
- package/dist/esm/base/middlewares/app-error/app-error.middleware.js +3 -3
- package/dist/esm/base/middlewares/app-error/app-error.middleware.js.map +1 -1
- package/dist/esm/base/middlewares/app-error/zod.handler.js +2 -2
- package/dist/esm/base/middlewares/app-error/zod.handler.js.map +1 -1
- package/dist/esm/base/middlewares/form-body/form-body.middleware.js +2 -2
- package/dist/esm/base/middlewares/form-body/form-body.middleware.js.map +1 -1
- package/dist/esm/base/middlewares/not-found/not-found.middleware.js.map +1 -1
- package/dist/esm/base/models/common/utilities.js +1 -1
- package/dist/esm/base/models/common/utilities.js.map +1 -1
- package/dist/esm/base/repositories/common/types/contracts.d.ts +17 -17
- package/dist/esm/base/repositories/common/types/contracts.d.ts.map +1 -1
- package/dist/esm/base/repositories/common/types/contracts.js.map +1 -1
- package/dist/esm/base/repositories/core/abstract.d.ts +17 -17
- package/dist/esm/base/repositories/core/abstract.d.ts.map +1 -1
- package/dist/esm/base/repositories/core/abstract.js +4 -3
- package/dist/esm/base/repositories/core/abstract.js.map +1 -1
- package/dist/esm/helpers/inversion/mixins/model.mixin.js +1 -1
- package/dist/esm/helpers/inversion/mixins/model.mixin.js.map +1 -1
- package/dist/esm/helpers/inversion/mixins/repository.mixin.js +1 -1
- package/dist/esm/helpers/inversion/mixins/repository.mixin.js.map +1 -1
- package/dist/esm/repository.d.ts +1 -1
- package/dist/esm/repository.d.ts.map +1 -1
- package/dist/esm/repository.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../../src/base/repositories/core/abstract.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractDataSource } from '@/base/datasources';\nimport type { AbstractEntity, IdType } from '@/base/models';\nimport type { IModelMetadata } from '@/helpers/inversion';\nimport { MetadataRegistry } from '@/helpers/inversion';\nimport type { TClass, TNullable } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { resolveValue } from '@venizia/ignis-helpers/common';\nimport { RetryBackoffStrategies, RetryHelper, RetryJitterModes } from '@venizia/ignis-helpers/core';\nimport type {\n IExtraOptions,\n IPersistableRepository,\n IWithReadRetry,\n TCount,\n TDataWithRange,\n TFindOneOptions,\n TFindOptions,\n TFindRangeOptions,\n TRepositoryOperationScope,\n} from '../common';\n// The file, not the `../common` barrel: the barrel re-exports the OpenAPI schemas, and this module is\n// on the `./repository` entry, which must load without `@hono/zod-openapi` installed.\nimport {\n DEFAULT_MAX_LIMIT,\n RepositoryErrorCodes,\n RepositoryOperationScopes,\n} from '../common/constants';\nimport type { TFilter, TInclusion, TWhere } from '@venizia/ignis-filter';\n\n/**\n * Engine-neutral repository plumbing - lazy dataSource/entity resolution, class-keyed `@model`\n * settings, operation scope. `TOptions` defaults to `IExtraOptions` so connectors can narrow it\n * while staying assignable to this base.\n */\nexport abstract class AbstractRepository<\n TDataObject extends object,\n TPersistObject extends object = TDataObject,\n TOptions extends IExtraOptions = IExtraOptions,\n>\n extends BaseHelper\n implements IPersistableRepository<TDataObject, TPersistObject, TOptions>\n{\n protected _operationScope: TRepositoryOperationScope;\n\n /** Lazy-resolved on first access if not provided in constructor. */\n protected _dataSource?: AbstractDataSource;\n\n /** Lazy-resolved from @repository metadata on first access. */\n protected _entity?: AbstractEntity;\n\n /**\n * Memoized @model settings for `this.entity`'s class. `null` means not yet resolved - `undefined`\n * is itself a valid resolved value: the model declares no settings.\n */\n private _modelSettings: IModelMetadata['settings'] | null = null;\n\n constructor(\n dataSource?: AbstractDataSource,\n opts?: {\n scope?: string;\n entityClass?: TClass<AbstractEntity>;\n operationScope?: TRepositoryOperationScope;\n },\n ) {\n const scopeName =\n opts?.scope ??\n (opts?.entityClass?.name ? [opts.entityClass.name, 'Repository'].join('') : new.target.name);\n\n super({ scope: scopeName });\n\n this._operationScope = opts?.operationScope ?? RepositoryOperationScopes.READ_ONLY;\n\n if (dataSource) {\n this._dataSource = dataSource;\n }\n\n if (opts?.entityClass) {\n this._entity = new opts.entityClass();\n }\n }\n\n get dataSource(): AbstractDataSource {\n if (!this._dataSource) {\n throw getError({\n message: `[${this.constructor.name}] DataSource not available. Use @repository({ model: YourModel, dataSource: YourDataSource }) or pass dataSource in constructor.`,\n });\n }\n\n return this._dataSource;\n }\n\n set dataSource(value: AbstractDataSource) {\n this._dataSource = value;\n }\n\n /** Auto-resolves from @repository metadata if not explicitly set. */\n get entity(): AbstractEntity {\n this._entity ??= this.resolveEntity();\n return this._entity;\n }\n\n set entity(value: AbstractEntity) {\n this._entity = value;\n }\n\n get operationScope(): TRepositoryOperationScope {\n return this._operationScope;\n }\n\n setDataSource(opts: { dataSource: AbstractDataSource }): void {\n this._dataSource = opts.dataSource;\n }\n\n getEntity(): AbstractEntity {\n return this.entity;\n }\n\n /**\n * Resolved `@model` settings for `this.entity`'s class, keyed by Reflect target - not by\n * `entity.name`, which can diverge from the `@model` registry key.\n */\n protected get modelSettings(): IModelMetadata['settings'] {\n if (this._modelSettings !== null) {\n return this._modelSettings;\n }\n\n this._modelSettings = MetadataRegistry.getInstance().getModelMetadata({\n target: this.entity.constructor,\n })?.settings;\n\n return this._modelSettings;\n }\n\n protected get hiddenFields(): string[] {\n return this.modelSettings?.hiddenProperties ?? [];\n }\n\n /** Default where from @model settings.defaultFilter.where, AND-merged into every query unless skipped. */\n protected get defaultWhere(): TWhere | undefined {\n return this.modelSettings?.defaultFilter?.where;\n }\n\n protected get defaultLimit(): number | undefined {\n return this.modelSettings?.defaultLimit;\n }\n\n /** Largest `limit` a caller may ask for, when the model declares one; undefined leaves the tier's own default in force. */\n protected get maxLimit(): number | undefined {\n return this.modelSettings?.maxLimit;\n }\n\n /**\n * Both bounds, in one place, for every tier.\n *\n * The upper bound is the point: `@model({ settings: { maxLimit } })` is public and validated at\n * decoration time, but the relational tier read it nowhere, so `maxLimit: 2` still issued\n * `LIMIT 50000000`.\n *\n * The lower bound matters just as much and is easy to miss: a NEGATIVE limit is not a smaller\n * page. Drizzle renders the LIMIT clause only when the value is `>= 0`, so a negative one removes\n * the clause and returns the whole table. The wire schema now rejects it too, but a server-side\n * caller reaches this method without passing through the schema at all.\n */\n protected assertLimitWithinCeiling(opts: { limit?: number; scope?: string }): void {\n const { limit, scope = 'find' } = opts;\n\n if (limit === undefined) {\n return;\n }\n\n // The shape check first, because it needs no metadata at all.\n if (!Number.isInteger(limit) || limit < 0) {\n throw getError({\n message: `[${this.constructor.name}][${scope}] Invalid 'limit' | Expected a non-negative integer | Got: ${limit}`,\n });\n }\n\n // `maxLimit` reaches `modelSettings`, which resolves the entity - and THAT throws for a\n // repository with no `@repository` model binding. Such a repository is a misconfiguration this\n // method has no business reporting, and the caller path that used to reach `getDefaultLimit()`\n // never touched it either, because `??` short-circuits when a limit is given. So the ceiling is\n // consulted only when the binding that makes it resolvable is actually present.\n const hasModelBinding = Boolean(\n MetadataRegistry.getInstance().getRepositoryBinding({ target: this.constructor })?.model,\n );\n const ceiling = (hasModelBinding ? this.maxLimit : undefined) ?? DEFAULT_MAX_LIMIT;\n\n if (limit > ceiling) {\n throw getError({\n message: `[${this.constructor.name}][${scope}] Requested page exceeds this model's limit | requested: ${limit} | maximum: ${ceiling} | raise it with @model settings.maxLimit if larger pages are genuinely needed`,\n });\n }\n }\n\n /**\n * The whole filter, relations included. Checking only the top-level `limit` left the identical\n * defect reachable one level down: a relation scope's negative limit drops Drizzle's LIMIT clause\n * for that relation and loads the entire related table.\n *\n * A relation's limit gets the SHAPE check only, not a ceiling. The ceiling belongs to the\n * relation's own model, which this repository cannot resolve - claiming otherwise would enforce\n * the parent's `maxLimit` on a different entity.\n */\n protected assertFilterLimits(opts: { filter?: TFilter; scope?: string }): void {\n const { filter, scope = 'find' } = opts;\n\n if (!filter) {\n return;\n }\n\n this.assertLimitWithinCeiling({ limit: filter.limit, scope });\n\n const walk = (inclusions: TInclusion[] | undefined, path: string): void => {\n const inclusionsList = inclusions ?? [];\n for (const inclusion of inclusionsList) {\n const relationScope = inclusion.scope;\n if (!relationScope) {\n continue;\n }\n\n const relationPath = `${path}.${inclusion.relation}`;\n const relationLimit = relationScope.limit;\n\n if (\n relationLimit !== undefined &&\n (!Number.isInteger(relationLimit) || relationLimit < 0)\n ) {\n throw getError({\n message: `[${this.constructor.name}][${scope}] Invalid 'limit' on relation scope | relation: ${relationPath} | Expected a non-negative integer | Got: ${relationLimit}`,\n });\n }\n\n walk(relationScope.include, relationPath);\n }\n };\n\n walk(filter.include, scope);\n }\n\n /** Resolves the entity instance from @repository metadata on first access. */\n protected resolveEntity(): AbstractEntity {\n const registry = MetadataRegistry.getInstance();\n const binding = registry.getRepositoryBinding({ target: this.constructor });\n\n if (!binding?.model) {\n throw getError({\n message: `[${this.constructor.name}] Cannot resolve entity. Either pass entityClass in constructor or use @repository decorator with model option.`,\n });\n }\n\n // resolveValue() erases to the resolved value's structural type, not this class-or-resolver\n // union's member - the `@repository` decorator guarantees a class constructor here.\n const ModelClass = resolveValue({ value: binding.model }) as TClass<AbstractEntity>;\n return new ModelClass();\n }\n\n /** Rejects a verb the current operation scope does not permit. */\n protected denyOperation(opts: { methodName: string }): never {\n throw getError({\n messageCode: RepositoryErrorCodes.OPERATION_NOT_ALLOWED,\n message: `[${opts.methodName}] Repository operation is NOT ALLOWED | scope: ${this.operationScope}`,\n });\n }\n\n /**\n * Shared retry orchestration for read verbs. Inside a transaction retry is skipped - the pool\n * routes transactions to the primary, so there is no replica lag to wait out.\n */\n protected executeReadWithRetry<TResult>(opts: {\n operation: string;\n options: IExtraOptions & IWithReadRetry<TResult>;\n defaultUntil: (result: TResult) => boolean;\n execution: () => Promise<TResult>;\n }): Promise<TResult> {\n const { operation, options, defaultUntil, execution } = opts;\n\n if (!options.retry) {\n return execution();\n }\n\n if (options.transaction) {\n this.logger.for(operation).debug('Read retry skipped inside transaction');\n return execution();\n }\n\n const { maxAttempts, maxTotalMs, signal, backoff, until } = options.retry;\n\n return RetryHelper.executeWithRetryUntil<TResult>({\n operation: [this.constructor.name, operation].join('.'),\n execution,\n until: until ?? defaultUntil,\n maxAttempts,\n maxTotalMs,\n signal,\n backoff: backoff ?? {\n strategy: RetryBackoffStrategies.EXPONENTIAL,\n initialDelayMs: 50,\n maxDelayMs: 500,\n jitter: RetryJitterModes.EQUAL,\n },\n logger: this.logger,\n });\n }\n\n /**\n * A copy of `options` without `retry`, so re-entering a read verb takes its non-retry path - this\n * is what keeps the retry recursion single-depth. Copy-then-delete rather than a rest-destructure\n * (lint rejects the unused rest sibling) or `lodash/omit` (its `Omit<>` return type is not\n * assignable back to `TOptions`).\n */\n private omitReadRetry<TReadOptions extends { retry?: unknown }>(\n options: TReadOptions,\n ): TReadOptions {\n const rest = { ...options };\n delete rest.retry;\n return rest;\n }\n\n /** `find`, re-executed until the retry predicate holds - connectors dispatch here from `find` when `options.retry` is set. */\n protected findUntil<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindOptions<TOptions, R>;\n }): Promise<Array<R>> {\n const options = this.omitReadRetry(opts.options);\n\n return this.executeReadWithRetry<Array<R>>({\n operation: 'find',\n options: opts.options,\n defaultUntil: result => result.length > 0,\n execution: () => this.find<R>({ filter: opts.filter, options }),\n });\n }\n\n /** `find` with the range envelope, re-executed until the retry predicate holds - split from `findUntil` so each result shape is checked against its own `find` overload. */\n protected findRangeUntil<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindRangeOptions<TOptions, R>;\n }): Promise<TDataWithRange<R>> {\n const options = this.omitReadRetry(opts.options);\n\n return this.executeReadWithRetry<TDataWithRange<R>>({\n operation: 'find',\n options: opts.options,\n defaultUntil: result => result.data.length > 0,\n execution: () => this.find<R>({ filter: opts.filter, options }),\n });\n }\n\n /** `findOne`, re-executed until the retry predicate holds - also serves `findById` via its findOne delegation. */\n protected findOneUntil<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindOneOptions<TOptions, R>;\n }): Promise<TNullable<R>> {\n const options = this.omitReadRetry(opts.options);\n\n return this.executeReadWithRetry<TNullable<R>>({\n operation: 'findOne',\n options: opts.options,\n defaultUntil: result => result !== null && result !== undefined,\n execution: () => this.findOne<R>({ filter: opts.filter, options }),\n });\n }\n\n abstract count(opts: { where: TWhere<TDataObject>; options?: TOptions }): Promise<TCount>;\n\n abstract existsWith(opts: { where: TWhere<TDataObject>; options?: TOptions }): Promise<boolean>;\n\n abstract find<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindRangeOptions<TOptions, R>;\n }): Promise<TDataWithRange<R>>;\n\n abstract find<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options?: TFindOptions<TOptions, R>;\n }): Promise<R[]>;\n\n abstract findOne<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options?: TFindOneOptions<TOptions, R>;\n }): Promise<TNullable<R>>;\n\n abstract findById<R = TDataObject>(opts: {\n id: IdType;\n filter?: Omit<TFilter<TDataObject>, 'where'>;\n options?: TFindOneOptions<TOptions, R>;\n }): Promise<TNullable<R>>;\n\n abstract create(opts: {\n data: TPersistObject;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract create<R = TDataObject>(opts: {\n data: TPersistObject;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: R }>;\n\n abstract createAll(opts: {\n data: Array<TPersistObject>;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract createAll<R = TDataObject>(opts: {\n data: Array<TPersistObject>;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: Array<R> }>;\n\n abstract updateById(opts: {\n id: IdType;\n data: Partial<TPersistObject>;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract updateById<R = TDataObject>(opts: {\n id: IdType;\n data: Partial<TPersistObject>;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: R }>;\n\n abstract updateAll(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract updateAll<R = TDataObject>(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n\n /** Alias for updateAll. */\n updateBy(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n updateBy<R = TDataObject>(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n updateBy<R = TDataObject>(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: boolean; force?: boolean };\n }): Promise<TCount & { data: TNullable<Array<R>> }> {\n const { data, where, options } = opts;\n\n if (options?.shouldReturn === false) {\n return this.updateAll({ data, where, options: { ...options, shouldReturn: false } });\n }\n\n return this.updateAll<R>({ data, where, options });\n }\n\n abstract deleteById(opts: {\n id: IdType;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract deleteById<R = TDataObject>(opts: {\n id: IdType;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: R }>;\n\n abstract deleteAll(opts: {\n where?: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract deleteAll<R = TDataObject>(opts: {\n where?: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n\n /** Alias for deleteAll. */\n deleteBy(opts: {\n where: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n deleteBy<R = TDataObject>(opts: {\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n deleteBy<R = TDataObject>(opts: {\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: boolean; force?: boolean };\n }): Promise<TCount & { data: TNullable<Array<R>> }> {\n const { where, options } = opts;\n\n if (options?.shouldReturn === false) {\n return this.deleteAll({ where, options: { ...options, shouldReturn: false } });\n }\n\n return this.deleteAll<R>({ where, options });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../../src/base/repositories/core/abstract.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractDataSource } from '@/base/datasources';\nimport type { AbstractEntity, IdType } from '@/base/models';\nimport type { IModelMetadata } from '@/helpers/inversion';\nimport { MetadataRegistry } from '@/helpers/inversion';\nimport type { TClass, TNullable } from '@venizia/ignis-helpers/common';\nimport { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { resolveValue } from '@venizia/ignis-helpers/common';\nimport { RetryBackoffStrategies, RetryHelper, RetryJitterModes } from '@venizia/ignis-helpers/core';\nimport type {\n IExtraOptions,\n IPersistableRepository,\n IWithReadRetry,\n TCount,\n TDataWithRange,\n TFindOneOptions,\n TFindOptions,\n TFindRangeOptions,\n TRepositoryOperationScope,\n} from '../common';\n// The file, not the `../common` barrel: the barrel re-exports the OpenAPI schemas, and this module is\n// on the `./repository` entry, which must load without `@hono/zod-openapi` installed.\nimport {\n DEFAULT_MAX_LIMIT,\n RepositoryErrorCodes,\n RepositoryOperationScopes,\n} from '../common/constants';\nimport type {\n TByIdFilter,\n TFields,\n TFilter,\n TInclusion,\n TRow,\n TWhere,\n} from '@venizia/ignis-filter';\n\n/**\n * Engine-neutral repository plumbing - lazy dataSource/entity resolution, class-keyed `@model`\n * settings, operation scope. `TOptions` defaults to `IExtraOptions` so connectors can narrow it\n * while staying assignable to this base.\n */\nexport abstract class AbstractRepository<\n TDataObject extends object,\n TPersistObject extends object = TDataObject,\n TOptions extends IExtraOptions = IExtraOptions,\n>\n extends BaseHelper\n implements IPersistableRepository<TDataObject, TPersistObject, TOptions>\n{\n protected _operationScope: TRepositoryOperationScope;\n\n /** Lazy-resolved on first access if not provided in constructor. */\n protected _dataSource?: AbstractDataSource;\n\n /** Lazy-resolved from @repository metadata on first access. */\n protected _entity?: AbstractEntity;\n\n /**\n * Memoized @model settings for `this.entity`'s class. `null` means not yet resolved - `undefined`\n * is itself a valid resolved value: the model declares no settings.\n */\n private _modelSettings: IModelMetadata['settings'] | null = null;\n\n constructor(\n dataSource?: AbstractDataSource,\n opts?: {\n scope?: string;\n entityClass?: TClass<AbstractEntity>;\n operationScope?: TRepositoryOperationScope;\n },\n ) {\n const scopeName =\n opts?.scope ??\n (opts?.entityClass?.name ? [opts.entityClass.name, 'Repository'].join('') : new.target.name);\n\n super({ scope: scopeName });\n\n this._operationScope = opts?.operationScope ?? RepositoryOperationScopes.READ_ONLY;\n\n if (dataSource) {\n this._dataSource = dataSource;\n }\n\n if (opts?.entityClass) {\n this._entity = new opts.entityClass();\n }\n }\n\n get dataSource(): AbstractDataSource {\n if (!this._dataSource) {\n throw getError({\n message: `[${this.constructor.name}] DataSource not available. Use @repository({ model: YourModel, dataSource: YourDataSource }) or pass dataSource in constructor.`,\n });\n }\n\n return this._dataSource;\n }\n\n set dataSource(value: AbstractDataSource) {\n this._dataSource = value;\n }\n\n /** Auto-resolves from @repository metadata if not explicitly set. */\n get entity(): AbstractEntity {\n this._entity ??= this.resolveEntity();\n return this._entity;\n }\n\n set entity(value: AbstractEntity) {\n this._entity = value;\n }\n\n get operationScope(): TRepositoryOperationScope {\n return this._operationScope;\n }\n\n setDataSource(opts: { dataSource: AbstractDataSource }): void {\n this._dataSource = opts.dataSource;\n }\n\n getEntity(): AbstractEntity {\n return this.entity;\n }\n\n /**\n * Resolved `@model` settings for `this.entity`'s class, keyed by Reflect target - not by\n * `entity.name`, which can diverge from the `@model` registry key.\n */\n protected get modelSettings(): IModelMetadata['settings'] {\n if (this._modelSettings !== null) {\n return this._modelSettings;\n }\n\n this._modelSettings = MetadataRegistry.getInstance().getModelMetadata({\n target: this.entity.constructor,\n })?.settings;\n\n return this._modelSettings;\n }\n\n protected get hiddenFields(): string[] {\n return this.modelSettings?.hiddenProperties ?? [];\n }\n\n /** Default where from @model settings.defaultFilter.where, AND-merged into every query unless skipped. */\n protected get defaultWhere(): TWhere | undefined {\n return this.modelSettings?.defaultFilter?.where;\n }\n\n protected get defaultLimit(): number | undefined {\n return this.modelSettings?.defaultLimit;\n }\n\n /** Largest `limit` a caller may ask for, when the model declares one; undefined leaves the tier's own default in force. */\n protected get maxLimit(): number | undefined {\n return this.modelSettings?.maxLimit;\n }\n\n /**\n * Both bounds, in one place, for every tier.\n *\n * The upper bound is the point: `@model({ settings: { maxLimit } })` is public and validated at\n * decoration time, but the relational tier read it nowhere, so `maxLimit: 2` still issued\n * `LIMIT 50000000`.\n *\n * The lower bound matters just as much and is easy to miss: a NEGATIVE limit is not a smaller\n * page. Drizzle renders the LIMIT clause only when the value is `>= 0`, so a negative one removes\n * the clause and returns the whole table. The wire schema now rejects it too, but a server-side\n * caller reaches this method without passing through the schema at all.\n */\n protected assertLimitWithinCeiling(opts: { limit?: number; scope?: string }): void {\n const { limit, scope = 'find' } = opts;\n\n if (limit === undefined) {\n return;\n }\n\n // The shape check first, because it needs no metadata at all.\n if (!Number.isInteger(limit) || limit < 0) {\n throw getError({\n message: `[${this.constructor.name}][${scope}] Invalid 'limit' | Expected a non-negative integer | Got: ${limit}`,\n });\n }\n\n // `maxLimit` reaches `modelSettings`, which resolves the entity - and THAT throws for a\n // repository with no `@repository` model binding. Such a repository is a misconfiguration this\n // method has no business reporting, and the caller path that used to reach `getDefaultLimit()`\n // never touched it either, because `??` short-circuits when a limit is given. So the ceiling is\n // consulted only when the binding that makes it resolvable is actually present.\n const hasModelBinding = Boolean(\n MetadataRegistry.getInstance().getRepositoryBinding({ target: this.constructor })?.model,\n );\n const ceiling = (hasModelBinding ? this.maxLimit : undefined) ?? DEFAULT_MAX_LIMIT;\n\n if (limit > ceiling) {\n throw getError({\n message: `[${this.constructor.name}][${scope}] Requested page exceeds this model's limit | requested: ${limit} | maximum: ${ceiling} | raise it with @model settings.maxLimit if larger pages are genuinely needed`,\n });\n }\n }\n\n /**\n * The whole filter, relations included. Checking only the top-level `limit` left the identical\n * defect reachable one level down: a relation scope's negative limit drops Drizzle's LIMIT clause\n * for that relation and loads the entire related table.\n *\n * A relation's limit gets the SHAPE check only, not a ceiling. The ceiling belongs to the\n * relation's own model, which this repository cannot resolve - claiming otherwise would enforce\n * the parent's `maxLimit` on a different entity.\n */\n protected assertFilterLimits(opts: { filter?: TFilter; scope?: string }): void {\n const { filter, scope = 'find' } = opts;\n\n if (!filter) {\n return;\n }\n\n this.assertLimitWithinCeiling({ limit: filter.limit, scope });\n\n const walk = (inclusions: TInclusion[] | undefined, path: string): void => {\n const inclusionsList = inclusions ?? [];\n for (const inclusion of inclusionsList) {\n const relationScope = inclusion.scope;\n if (!relationScope) {\n continue;\n }\n\n const relationPath = `${path}.${inclusion.relation}`;\n const relationLimit = relationScope.limit;\n\n if (\n relationLimit !== undefined &&\n (!Number.isInteger(relationLimit) || relationLimit < 0)\n ) {\n throw getError({\n message: `[${this.constructor.name}][${scope}] Invalid 'limit' on relation scope | relation: ${relationPath} | Expected a non-negative integer | Got: ${relationLimit}`,\n });\n }\n\n walk(relationScope.include, relationPath);\n }\n };\n\n walk(filter.include, scope);\n }\n\n /** Resolves the entity instance from @repository metadata on first access. */\n protected resolveEntity(): AbstractEntity {\n const registry = MetadataRegistry.getInstance();\n const binding = registry.getRepositoryBinding({ target: this.constructor });\n\n if (!binding?.model) {\n throw getError({\n message: `[${this.constructor.name}] Cannot resolve entity. Either pass entityClass in constructor or use @repository decorator with model option.`,\n });\n }\n\n // resolveValue() erases to the resolved value's structural type, not this class-or-resolver\n // union's member - the `@repository` decorator guarantees a class constructor here.\n const ModelClass = resolveValue({ value: binding.model }) as TClass<AbstractEntity>;\n return new ModelClass();\n }\n\n /** Rejects a verb the current operation scope does not permit. */\n protected denyOperation(opts: { methodName: string }): never {\n throw getError({\n messageCode: RepositoryErrorCodes.OPERATION_NOT_ALLOWED,\n message: `[${opts.methodName}] Repository operation is NOT ALLOWED | scope: ${this.operationScope}`,\n });\n }\n\n /**\n * Shared retry orchestration for read verbs. Inside a transaction retry is skipped - the pool\n * routes transactions to the primary, so there is no replica lag to wait out.\n */\n protected executeReadWithRetry<TResult>(opts: {\n operation: string;\n options: IExtraOptions & IWithReadRetry<TResult>;\n defaultUntil: (result: TResult) => boolean;\n execution: () => Promise<TResult>;\n }): Promise<TResult> {\n const { operation, options, defaultUntil, execution } = opts;\n\n if (!options.retry) {\n return execution();\n }\n\n if (options.transaction) {\n this.logger.for(operation).debug('Read retry skipped inside transaction');\n return execution();\n }\n\n const { maxAttempts, maxTotalMs, signal, backoff, until } = options.retry;\n\n return RetryHelper.executeWithRetryUntil<TResult>({\n operation: [this.constructor.name, operation].join('.'),\n execution,\n until: until ?? defaultUntil,\n maxAttempts,\n maxTotalMs,\n signal,\n backoff: backoff ?? {\n strategy: RetryBackoffStrategies.EXPONENTIAL,\n initialDelayMs: 50,\n maxDelayMs: 500,\n jitter: RetryJitterModes.EQUAL,\n },\n logger: this.logger,\n });\n }\n\n /**\n * A copy of `options` without `retry`, so re-entering a read verb takes its non-retry path - this\n * is what keeps the retry recursion single-depth. Copy-then-delete rather than a rest-destructure\n * (lint rejects the unused rest sibling) or `lodash/omit` (its `Omit<>` return type is not\n * assignable back to `TOptions`).\n */\n private omitReadRetry<TReadOptions extends { retry?: unknown }>(\n options: TReadOptions,\n ): TReadOptions {\n const rest = { ...options };\n delete rest.retry;\n return rest;\n }\n\n /** `find`, re-executed until the retry predicate holds - connectors dispatch here from `find` when `options.retry` is set. */\n protected findUntil<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindOptions<TOptions, R>;\n }): Promise<Array<R>> {\n const options = this.omitReadRetry(opts.options);\n\n return this.executeReadWithRetry<Array<R>>({\n operation: 'find',\n options: opts.options,\n defaultUntil: (result) => result.length > 0,\n // `R` is named here, so the row is `R`; TypeScript cannot resolve `TRow` for an unresolved `R`.\n execution: () => this.find<R>({ filter: opts.filter, options }) as Promise<Array<R>>,\n });\n }\n\n /** `find` with the range envelope, re-executed until the retry predicate holds - split from `findUntil` so each result shape is checked against its own `find` overload. */\n protected findRangeUntil<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindRangeOptions<TOptions, R>;\n }): Promise<TDataWithRange<R>> {\n const options = this.omitReadRetry(opts.options);\n\n return this.executeReadWithRetry<TDataWithRange<R>>({\n operation: 'find',\n options: opts.options,\n defaultUntil: (result) => result.data.length > 0,\n execution: () =>\n this.find<R>({ filter: opts.filter, options }) as unknown as Promise<TDataWithRange<R>>,\n });\n }\n\n /** `findOne`, re-executed until the retry predicate holds - also serves `findById` via its findOne delegation. */\n protected findOneUntil<R = TDataObject>(opts: {\n filter: TFilter<TDataObject>;\n options: TFindOneOptions<TOptions, R>;\n }): Promise<TNullable<R>> {\n const options = this.omitReadRetry(opts.options);\n\n return this.executeReadWithRetry<TNullable<R>>({\n operation: 'findOne',\n options: opts.options,\n defaultUntil: (result) => result !== null && result !== undefined,\n execution: () => this.findOne<R>({ filter: opts.filter, options }) as Promise<TNullable<R>>,\n });\n }\n\n abstract count(opts: { where: TWhere<TDataObject>; options?: TOptions }): Promise<TCount>;\n\n abstract existsWith(opts: { where: TWhere<TDataObject>; options?: TOptions }): Promise<boolean>;\n\n abstract find<R = unknown, const F extends TFields<TDataObject> = TFields<TDataObject>>(opts: {\n filter: TFilter<TDataObject, F>;\n options: TFindRangeOptions<TOptions, TRow<TDataObject, R, F>>;\n }): Promise<TDataWithRange<TRow<TDataObject, R, F>>>;\n\n abstract find<R = unknown, const F extends TFields<TDataObject> = TFields<TDataObject>>(opts: {\n filter: TFilter<TDataObject, F>;\n options?: TFindOptions<TOptions, TRow<TDataObject, R, F>>;\n }): Promise<Array<TRow<TDataObject, R, F>>>;\n\n abstract findOne<R = unknown, const F extends TFields<TDataObject> = TFields<TDataObject>>(opts: {\n filter: TFilter<TDataObject, F>;\n options?: TFindOneOptions<TOptions, TRow<TDataObject, R, F>>;\n }): Promise<TNullable<TRow<TDataObject, R, F>>>;\n\n abstract findById<\n R = unknown,\n const F extends TFields<TDataObject> = TFields<TDataObject>,\n >(opts: {\n id: IdType;\n filter?: TByIdFilter<TDataObject, F>;\n options?: TFindOneOptions<TOptions, TRow<TDataObject, R, F>>;\n }): Promise<TNullable<TRow<TDataObject, R, F>>>;\n\n abstract create(opts: {\n data: TPersistObject;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract create<R = TDataObject>(opts: {\n data: TPersistObject;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: R }>;\n\n abstract createAll(opts: {\n data: Array<TPersistObject>;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract createAll<R = TDataObject>(opts: {\n data: Array<TPersistObject>;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: Array<R> }>;\n\n abstract updateById(opts: {\n id: IdType;\n data: Partial<TPersistObject>;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract updateById<R = TDataObject>(opts: {\n id: IdType;\n data: Partial<TPersistObject>;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: R }>;\n\n abstract updateAll(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract updateAll<R = TDataObject>(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n\n /** Alias for updateAll. */\n updateBy(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n updateBy<R = TDataObject>(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n updateBy<R = TDataObject>(opts: {\n data: Partial<TPersistObject>;\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: boolean; force?: boolean };\n }): Promise<TCount & { data: TNullable<Array<R>> }> {\n const { data, where, options } = opts;\n\n if (options?.shouldReturn === false) {\n return this.updateAll({ data, where, options: { ...options, shouldReturn: false } });\n }\n\n return this.updateAll<R>({ data, where, options });\n }\n\n abstract deleteById(opts: {\n id: IdType;\n options: TOptions & { shouldReturn: false };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract deleteById<R = TDataObject>(opts: {\n id: IdType;\n options?: TOptions & { shouldReturn?: true };\n }): Promise<TCount & { data: R }>;\n\n abstract deleteAll(opts: {\n where?: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n\n abstract deleteAll<R = TDataObject>(opts: {\n where?: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n\n /** Alias for deleteAll. */\n deleteBy(opts: {\n where: TWhere<TDataObject>;\n options: TOptions & { shouldReturn: false; force?: boolean };\n }): Promise<TCount & { data: undefined | null }>;\n deleteBy<R = TDataObject>(opts: {\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: true; force?: boolean };\n }): Promise<TCount & { data: Array<R> | null }>;\n deleteBy<R = TDataObject>(opts: {\n where: TWhere<TDataObject>;\n options?: TOptions & { shouldReturn?: boolean; force?: boolean };\n }): Promise<TCount & { data: TNullable<Array<R>> }> {\n const { where, options } = opts;\n\n if (options?.shouldReturn === false) {\n return this.deleteAll({ where, options: { ...options, shouldReturn: false } });\n }\n\n return this.deleteAll<R>({ where, options });\n }\n}\n"]}
|
|
@@ -83,7 +83,7 @@ const ModelMetadataMixin = (baseClass) => {
|
|
|
83
83
|
getAuthorizeModelPrincipals(opts) {
|
|
84
84
|
switch (opts.format) {
|
|
85
85
|
case 'array': {
|
|
86
|
-
return collectAuthorizePrincipals({ modelRegistry: this.modelRegistry }).map(item => item.principal);
|
|
86
|
+
return collectAuthorizePrincipals({ modelRegistry: this.modelRegistry }).map((item) => item.principal);
|
|
87
87
|
}
|
|
88
88
|
case 'record': {
|
|
89
89
|
const record = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.mixin.js","sourceRoot":"","sources":["../../../../../src/helpers/inversion/mixins/model.mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractEntity } from '@/base/models';\nimport type { TMixinTarget } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { MetadataRegistry as _MetadataRegistry } from '@venizia/ignis-inversion';\nimport { MetadataKeys } from '../common/keys';\nimport type {\n IModelAuthorizeSettings,\n IModelMetadata,\n IModelRegistryEntry,\n TDecoratorModelTarget,\n TModelClass,\n} from '../common/types';\n\n/** Registered models that declare an authorize setting, in registry order. */\nconst collectAuthorizeEntries = (opts: {\n modelRegistry: Map<string, IModelRegistryEntry>;\n}): Array<{ name: string; authorize: IModelAuthorizeSettings; entry: IModelRegistryEntry }> => {\n const result: Array<{\n name: string;\n authorize: IModelAuthorizeSettings;\n entry: IModelRegistryEntry;\n }> = [];\n\n for (const [name, entry] of opts.modelRegistry) {\n const authorize = entry.metadata.settings?.authorize;\n if (!authorize) {\n continue;\n }\n\n result.push({ name, authorize, entry });\n }\n\n return result;\n};\n\n/** Registered models that declare an authorize principal, in registry order. */\nconst collectAuthorizePrincipals = (opts: {\n modelRegistry: Map<string, IModelRegistryEntry>;\n}): Array<{ name: string; principal: string }> => {\n const result: Array<{ name: string; principal: string }> = [];\n\n for (const [name, entry] of opts.modelRegistry) {\n const principal = entry.metadata.settings?.authorize?.principal;\n if (!principal) {\n continue;\n }\n\n result.push({ name, principal });\n }\n\n return result;\n};\n\nexport const ModelMetadataMixin = <BaseClass extends TMixinTarget<_MetadataRegistry>>(\n baseClass: BaseClass,\n) => {\n return class extends baseClass {\n modelRegistry: Map<string, IModelRegistryEntry>;\n modelsBySchema: WeakMap<object, IModelRegistryEntry>;\n\n setModelMetadata<Target extends object = object>(opts: {\n target: Target;\n metadata: IModelMetadata;\n }): void {\n const { target, metadata } = opts;\n Reflect.defineMetadata(MetadataKeys.MODEL, metadata, target);\n }\n\n getModelMetadata<Target extends object = object>(opts: {\n target: Target;\n }): IModelMetadata | undefined {\n const { target } = opts;\n return Reflect.getMetadata(MetadataKeys.MODEL, target);\n }\n\n /** Registers a model (called by @model) - relations are stored as a resolver, not resolved immediately, so circular references between models resolve lazily in buildSchema(). */\n registerModel<Model extends AbstractEntity = AbstractEntity>(opts: {\n target: TDecoratorModelTarget<Model>;\n metadata: IModelMetadata;\n }) {\n const { target, metadata } = opts;\n\n // Decorator target is always a class constructor at runtime\n const modelClass = target as TModelClass<Model>;\n\n // Table name precedence: explicit metadata > static TABLE_NAME > class name. TABLE_NAME is deliberately outside IEntityStatics (not part of the neutral contract) but still honored here via a local cast.\n const tableName =\n [metadata.tableName, (modelClass as { TABLE_NAME?: string }).TABLE_NAME].find(Boolean) ??\n modelClass.name;\n\n // Resolver, not resolved value - executed lazily in buildSchema() once all models are loaded\n const relationsResolver = modelClass.relations;\n\n const entry: IModelRegistryEntry = {\n target: modelClass,\n metadata,\n schema: modelClass.schema,\n relationsResolver,\n };\n this.modelRegistry.set(tableName, entry);\n\n const { schema } = modelClass;\n if (schema && typeof schema === 'object') {\n const claimed = this.modelsBySchema.get(schema);\n if (claimed && claimed.target !== modelClass) {\n this.modelsBySchema.delete(schema);\n } else {\n this.modelsBySchema.set(schema, entry);\n }\n }\n\n // Also mirrored via Reflect so plain metadata lookups (getModelMetadata) still see it\n this.setModelMetadata({ target, metadata });\n }\n\n getModelEntry(opts: { name: string }): IModelRegistryEntry | undefined {\n return this.modelRegistry.get(opts.name);\n }\n\n getModelEntryBySchema(opts: { schema: object }): IModelRegistryEntry | undefined {\n return this.modelsBySchema.get(opts.schema);\n }\n\n getAllModels(): Map<string, IModelRegistryEntry> {\n return this.modelRegistry;\n }\n\n getModelAuthorizeSettings(opts: { name: string }): IModelAuthorizeSettings | undefined {\n const entry = this.getModelEntry(opts);\n return entry?.metadata?.settings?.authorize;\n }\n\n /** Authorization principals across all models that declare an authorize setting. */\n getAuthorizeModelPrincipals(opts: { format: 'array' }): string[];\n getAuthorizeModelPrincipals(opts: { format: 'record' }): Record<string, string>;\n getAuthorizeModelPrincipals(opts: { format: 'array' | 'record' }) {\n switch (opts.format) {\n case 'array': {\n return collectAuthorizePrincipals({ modelRegistry: this.modelRegistry }).map(\n item => item.principal,\n );\n }\n case 'record': {\n const record: Record<string, string> = {};\n\n const authorizePrincipals = collectAuthorizePrincipals({\n modelRegistry: this.modelRegistry,\n });\n for (const item of authorizePrincipals) {\n record[item.name] = item.principal;\n }\n\n return record;\n }\n default: {\n throw getError({\n message: `[getAuthorizeModelPrincipals] Invalid format | format: ${opts.format} | valid: array, record`,\n });\n }\n }\n }\n\n getAuthorizeModelSettings(opts: { format: 'array' }): Array<{\n name: string;\n authorize: IModelAuthorizeSettings;\n entry: IModelRegistryEntry;\n }>;\n getAuthorizeModelSettings(opts: {\n format: 'record';\n }): Record<string, { authorize: IModelAuthorizeSettings; entry: IModelRegistryEntry }>;\n getAuthorizeModelSettings(opts: { format: 'array' | 'record' }) {\n switch (opts.format) {\n case 'array': {\n return collectAuthorizeEntries({ modelRegistry: this.modelRegistry });\n }\n case 'record': {\n const record: Record<\n string,\n { authorize: IModelAuthorizeSettings; entry: IModelRegistryEntry }\n > = {};\n\n const authorizeEntries = collectAuthorizeEntries({ modelRegistry: this.modelRegistry });\n for (const item of authorizeEntries) {\n record[item.name] = { authorize: item.authorize, entry: item.entry };\n }\n\n return record;\n }\n default: {\n throw getError({\n message: `[getAuthorizeModelSettings] Invalid format | format: ${opts.format} | valid: array, record`,\n });\n }\n }\n }\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"model.mixin.js","sourceRoot":"","sources":["../../../../../src/helpers/inversion/mixins/model.mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractEntity } from '@/base/models';\nimport type { TMixinTarget } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { MetadataRegistry as _MetadataRegistry } from '@venizia/ignis-inversion';\nimport { MetadataKeys } from '../common/keys';\nimport type {\n IModelAuthorizeSettings,\n IModelMetadata,\n IModelRegistryEntry,\n TDecoratorModelTarget,\n TModelClass,\n} from '../common/types';\n\n/** Registered models that declare an authorize setting, in registry order. */\nconst collectAuthorizeEntries = (opts: {\n modelRegistry: Map<string, IModelRegistryEntry>;\n}): Array<{ name: string; authorize: IModelAuthorizeSettings; entry: IModelRegistryEntry }> => {\n const result: Array<{\n name: string;\n authorize: IModelAuthorizeSettings;\n entry: IModelRegistryEntry;\n }> = [];\n\n for (const [name, entry] of opts.modelRegistry) {\n const authorize = entry.metadata.settings?.authorize;\n if (!authorize) {\n continue;\n }\n\n result.push({ name, authorize, entry });\n }\n\n return result;\n};\n\n/** Registered models that declare an authorize principal, in registry order. */\nconst collectAuthorizePrincipals = (opts: {\n modelRegistry: Map<string, IModelRegistryEntry>;\n}): Array<{ name: string; principal: string }> => {\n const result: Array<{ name: string; principal: string }> = [];\n\n for (const [name, entry] of opts.modelRegistry) {\n const principal = entry.metadata.settings?.authorize?.principal;\n if (!principal) {\n continue;\n }\n\n result.push({ name, principal });\n }\n\n return result;\n};\n\nexport const ModelMetadataMixin = <BaseClass extends TMixinTarget<_MetadataRegistry>>(\n baseClass: BaseClass,\n) => {\n return class extends baseClass {\n modelRegistry: Map<string, IModelRegistryEntry>;\n modelsBySchema: WeakMap<object, IModelRegistryEntry>;\n\n setModelMetadata<Target extends object = object>(opts: {\n target: Target;\n metadata: IModelMetadata;\n }): void {\n const { target, metadata } = opts;\n Reflect.defineMetadata(MetadataKeys.MODEL, metadata, target);\n }\n\n getModelMetadata<Target extends object = object>(opts: {\n target: Target;\n }): IModelMetadata | undefined {\n const { target } = opts;\n return Reflect.getMetadata(MetadataKeys.MODEL, target);\n }\n\n /** Registers a model (called by @model) - relations are stored as a resolver, not resolved immediately, so circular references between models resolve lazily in buildSchema(). */\n registerModel<Model extends AbstractEntity = AbstractEntity>(opts: {\n target: TDecoratorModelTarget<Model>;\n metadata: IModelMetadata;\n }) {\n const { target, metadata } = opts;\n\n // Decorator target is always a class constructor at runtime\n const modelClass = target as TModelClass<Model>;\n\n // Table name precedence: explicit metadata > static TABLE_NAME > class name. TABLE_NAME is deliberately outside IEntityStatics (not part of the neutral contract) but still honored here via a local cast.\n const tableName =\n [metadata.tableName, (modelClass as { TABLE_NAME?: string }).TABLE_NAME].find(Boolean) ??\n modelClass.name;\n\n // Resolver, not resolved value - executed lazily in buildSchema() once all models are loaded\n const relationsResolver = modelClass.relations;\n\n const entry: IModelRegistryEntry = {\n target: modelClass,\n metadata,\n schema: modelClass.schema,\n relationsResolver,\n };\n this.modelRegistry.set(tableName, entry);\n\n const { schema } = modelClass;\n if (schema && typeof schema === 'object') {\n const claimed = this.modelsBySchema.get(schema);\n if (claimed && claimed.target !== modelClass) {\n this.modelsBySchema.delete(schema);\n } else {\n this.modelsBySchema.set(schema, entry);\n }\n }\n\n // Also mirrored via Reflect so plain metadata lookups (getModelMetadata) still see it\n this.setModelMetadata({ target, metadata });\n }\n\n getModelEntry(opts: { name: string }): IModelRegistryEntry | undefined {\n return this.modelRegistry.get(opts.name);\n }\n\n getModelEntryBySchema(opts: { schema: object }): IModelRegistryEntry | undefined {\n return this.modelsBySchema.get(opts.schema);\n }\n\n getAllModels(): Map<string, IModelRegistryEntry> {\n return this.modelRegistry;\n }\n\n getModelAuthorizeSettings(opts: { name: string }): IModelAuthorizeSettings | undefined {\n const entry = this.getModelEntry(opts);\n return entry?.metadata?.settings?.authorize;\n }\n\n /** Authorization principals across all models that declare an authorize setting. */\n getAuthorizeModelPrincipals(opts: { format: 'array' }): string[];\n getAuthorizeModelPrincipals(opts: { format: 'record' }): Record<string, string>;\n getAuthorizeModelPrincipals(opts: { format: 'array' | 'record' }) {\n switch (opts.format) {\n case 'array': {\n return collectAuthorizePrincipals({ modelRegistry: this.modelRegistry }).map(\n (item) => item.principal,\n );\n }\n case 'record': {\n const record: Record<string, string> = {};\n\n const authorizePrincipals = collectAuthorizePrincipals({\n modelRegistry: this.modelRegistry,\n });\n for (const item of authorizePrincipals) {\n record[item.name] = item.principal;\n }\n\n return record;\n }\n default: {\n throw getError({\n message: `[getAuthorizeModelPrincipals] Invalid format | format: ${opts.format} | valid: array, record`,\n });\n }\n }\n }\n\n getAuthorizeModelSettings(opts: { format: 'array' }): Array<{\n name: string;\n authorize: IModelAuthorizeSettings;\n entry: IModelRegistryEntry;\n }>;\n getAuthorizeModelSettings(opts: {\n format: 'record';\n }): Record<string, { authorize: IModelAuthorizeSettings; entry: IModelRegistryEntry }>;\n getAuthorizeModelSettings(opts: { format: 'array' | 'record' }) {\n switch (opts.format) {\n case 'array': {\n return collectAuthorizeEntries({ modelRegistry: this.modelRegistry });\n }\n case 'record': {\n const record: Record<\n string,\n { authorize: IModelAuthorizeSettings; entry: IModelRegistryEntry }\n > = {};\n\n const authorizeEntries = collectAuthorizeEntries({ modelRegistry: this.modelRegistry });\n for (const item of authorizeEntries) {\n record[item.name] = { authorize: item.authorize, entry: item.entry };\n }\n\n return record;\n }\n default: {\n throw getError({\n message: `[getAuthorizeModelSettings] Invalid format | format: ${opts.format} | valid: array, record`,\n });\n }\n }\n }\n };\n};\n"]}
|
|
@@ -90,7 +90,7 @@ const RepositoryMetadataMixin = (baseClass) => {
|
|
|
90
90
|
getModels(opts) {
|
|
91
91
|
const modelClasses = this.getDataSourceModelClasses({ dataSource: opts.dataSource });
|
|
92
92
|
const rs = Array.from(modelClasses)
|
|
93
|
-
.map(modelClass => {
|
|
93
|
+
.map((modelClass) => {
|
|
94
94
|
// Read straight off the class: a class -> name -> modelRegistry round-trip collapses two
|
|
95
95
|
// same-named models onto one entry, silently swapping schemas. `modelRegistry` stays
|
|
96
96
|
// name-keyed for the by-name APIs that need it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.mixin.js","sourceRoot":"","sources":["../../../../../src/helpers/inversion/mixins/repository.mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IDataSource } from '@/base/datasources';\nimport type { AbstractEntity } from '@/base/models';\nimport type { AnyType, TClass, TMixinTarget } from '@venizia/ignis-helpers/common';\nimport { resolveValue } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { MetadataRegistry as _MetadataRegistry } from '@venizia/ignis-inversion';\nimport { MetadataKeys } from '../common/keys';\nimport { RelationBuilderRegistry } from '../common/relation-builder';\nimport type {\n IModelMetadata,\n IModelRegistryEntry,\n IRepositoryBinding,\n IResolvedRepositoryMetadata,\n TRepositoryMetadata,\n} from '../common/types';\n\nexport const RepositoryMetadataMixin = <\n BaseClass extends TMixinTarget<\n _MetadataRegistry & {\n modelRegistry: Map<string, IModelRegistryEntry>;\n getModelMetadata(opts: { target: object }): IModelMetadata | undefined;\n }\n >,\n>(\n baseClass: BaseClass,\n) => {\n return class extends baseClass {\n /** By repository class name, for the by-name API. Two classes may share a name; `repositoryBindingsByClass` cannot confuse them. */\n repositoryBindings: Map<string, IRepositoryBinding<AbstractEntity>>;\n\n /** By repository class: a minified build renames classes, and two chunks may give two of them one name. */\n repositoryBindingsByClass: Map<Function, IRepositoryBinding<AbstractEntity>>;\n\n /**\n * The model classes each datasource owns, keyed by the datasource class - or by the string a\n * repository named it with (`dataSource: 'PgDataSource'`), which only a class of that name\n * can match. Never by class name alone: a minified build gives two datasources one name.\n */\n datasourceModels: Map<string | Function, Set<TClass<AnyType>>>;\n\n setRepositoryMetadata<\n Target extends object = object,\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n >(opts: {\n target: Target;\n metadata: TRepositoryMetadata<Model, DataSource> & {\n _resolved?: IResolvedRepositoryMetadata<Model, DataSource>;\n };\n }): void {\n const { target, metadata } = opts;\n Reflect.defineMetadata(MetadataKeys.REPOSITORY, metadata, target);\n }\n\n getRepositoryMetadata<Target extends object = object>(opts: {\n target: Target;\n }): (TRepositoryMetadata & { _resolved?: IResolvedRepositoryMetadata }) | undefined {\n const { target } = opts;\n return Reflect.getMetadata(MetadataKeys.REPOSITORY, target);\n }\n\n /** Registers a repository binding (called by @repository) linking a repository to its model + datasource. */\n registerRepositoryBinding<\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n >(opts: IRepositoryBinding<Model, DataSource>) {\n // Every member of the binding may be a resolver, the escape hatch for circular imports.\n // Reading `.name` off the resolver keys the registry by the arrow's inferred name, and the\n // datasource then silently discovers no schema.\n const repositoryClass = resolveValue({ value: opts.repository });\n this.repositoryBindings.set(repositoryClass.name, opts);\n this.repositoryBindingsByClass.set(repositoryClass, opts);\n\n const dataSourceRef = resolveValue({ value: opts.dataSource });\n const modelClass = resolveValue({ value: opts.model });\n\n if (!this.datasourceModels.has(dataSourceRef)) {\n this.datasourceModels.set(dataSourceRef, new Set());\n }\n\n this.datasourceModels.get(dataSourceRef)!.add(modelClass);\n }\n\n /** By class, walking up to the nearest decorated parent; by name only for callers holding a name. */\n getRepositoryBinding(\n opts: { target: Function } | { name: string },\n ): IRepositoryBinding<AbstractEntity> | undefined {\n if ('name' in opts) {\n return this.repositoryBindings.get(opts.name);\n }\n\n for (\n let current: Function | null = opts.target;\n current && current !== Function.prototype;\n current = Object.getPrototypeOf(current)\n ) {\n const binding = this.repositoryBindingsByClass.get(current);\n if (binding) {\n return binding;\n }\n }\n\n return undefined;\n }\n\n /** A class finds what was registered under it, and under a string equal to its name. */\n getDataSourceModelClasses(opts: {\n dataSource: string | TClass<IDataSource>;\n }): Set<TClass<AnyType>> {\n const { dataSource } = opts;\n\n if (typeof dataSource === 'string') {\n return this.datasourceModels.get(dataSource) ?? new Set();\n }\n\n return new Set([\n ...(this.datasourceModels.get(dataSource) ?? []),\n ...(this.datasourceModels.get(dataSource.name) ?? []),\n ]);\n }\n\n /**\n * Resolves and caches relations for a model entry - called lazily from buildSchema() so that\n * every `@model` class is registered first, which avoids circular-dependency ordering issues.\n * @internal\n */\n resolveModelRelations(modelMeta: IModelRegistryEntry): unknown {\n if (modelMeta._builtRelations !== undefined) {\n return modelMeta._builtRelations;\n }\n\n if (!modelMeta.relationsResolver) {\n return undefined;\n }\n\n const relations = resolveValue({ value: modelMeta.relationsResolver });\n\n if (!relations || !modelMeta.schema) {\n return undefined;\n }\n\n const builder = RelationBuilderRegistry.resolve();\n\n // Relations were declared but no connector installed a builder - silently dropping them\n // would surface much later as an empty `with` clause.\n if (!builder) {\n throw getError({\n message: `[RepositoryMetadataMixin][resolveModelRelations] Model declares relations but no relation builder is registered | Import the relational connector so it installs one`,\n });\n }\n\n const builtRelations = builder({ source: modelMeta.schema, relations });\n\n modelMeta._builtRelations = builtRelations?.relations;\n return modelMeta._builtRelations;\n }\n\n /**\n * Models registered for a datasource, relations resolved lazily. `schema`/`relations` stay\n * `unknown` - the registry is shared across connectors, so each connector narrows at its call\n * site.\n */\n getModels(opts: { dataSource: string | TClass<IDataSource> }): Array<{\n tableName: string;\n schema: unknown;\n relations?: unknown;\n }> {\n const modelClasses = this.getDataSourceModelClasses({ dataSource: opts.dataSource });\n\n const rs = Array.from(modelClasses)\n .map(modelClass => {\n // Read straight off the class: a class -> name -> modelRegistry round-trip collapses two\n // same-named models onto one entry, silently swapping schemas. `modelRegistry` stays\n // name-keyed for the by-name APIs that need it.\n const entry: IModelRegistryEntry = {\n target: modelClass as AnyType,\n metadata:\n this.getModelMetadata({ target: modelClass }) ?? ({ settings: {} } as AnyType),\n schema: (modelClass as AnyType).schema,\n relationsResolver: (modelClass as AnyType).relations,\n };\n\n if (entry.schema === undefined) {\n return null;\n }\n\n return {\n tableName: this.resolveModelKey({ modelClass }),\n schema: entry.schema,\n relations: this.resolveModelRelations(entry),\n };\n })\n .filter((item): item is NonNullable<typeof item> => {\n return item !== undefined && item !== null;\n });\n\n return rs;\n }\n\n /**\n * Like getModels but returns only resolved model classes - used by BaseSearchDataSource, which\n * has no pgTable to resolve.\n */\n getModelClasses(opts: { dataSource: string | TClass<IDataSource> }): Array<TClass<unknown>> {\n // Straight from the stored class refs: a name round-trip through the shared modelRegistry\n // would hand back whichever same-named class registered last.\n return Array.from(this.getDataSourceModelClasses({ dataSource: opts.dataSource }));\n }\n\n /** The key a model occupies in `modelRegistry` - its table name, or its class name when it has none. */\n resolveModelKey(opts: { modelClass: TClass<AnyType> }): string {\n const { modelClass } = opts;\n const modelMetadata = this.getModelMetadata({ target: modelClass });\n\n return (\n [modelMetadata?.tableName, (modelClass as AnyType).TABLE_NAME].find(Boolean) ??\n modelClass.name\n );\n }\n\n /** Assembles table schemas + relations for a datasource's registered models. */\n buildSchema(opts: { dataSource: string | TClass<IDataSource> }): {\n schema: Record<string, unknown>;\n relations: Record<string, unknown>;\n } {\n const { dataSource } = opts;\n const models = this.getModels({ dataSource });\n\n const rs: {\n schema: Record<string, unknown>;\n relations: Record<string, unknown>;\n } = { schema: {}, relations: {} };\n\n for (const model of models) {\n if (model.schema) {\n rs.schema[model.tableName] = model.schema;\n }\n\n if (model.relations) {\n rs.relations[`${model.tableName}Relations`] = model.relations;\n }\n }\n\n return rs;\n }\n\n hasModels(opts: { dataSource: string | TClass<IDataSource> }): boolean {\n return this.getDataSourceModelClasses({ dataSource: opts.dataSource }).size > 0;\n }\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"repository.mixin.js","sourceRoot":"","sources":["../../../../../src/helpers/inversion/mixins/repository.mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IDataSource } from '@/base/datasources';\nimport type { AbstractEntity } from '@/base/models';\nimport type { AnyType, TClass, TMixinTarget } from '@venizia/ignis-helpers/common';\nimport { resolveValue } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { MetadataRegistry as _MetadataRegistry } from '@venizia/ignis-inversion';\nimport { MetadataKeys } from '../common/keys';\nimport { RelationBuilderRegistry } from '../common/relation-builder';\nimport type {\n IModelMetadata,\n IModelRegistryEntry,\n IRepositoryBinding,\n IResolvedRepositoryMetadata,\n TRepositoryMetadata,\n} from '../common/types';\n\nexport const RepositoryMetadataMixin = <\n BaseClass extends TMixinTarget<\n _MetadataRegistry & {\n modelRegistry: Map<string, IModelRegistryEntry>;\n getModelMetadata(opts: { target: object }): IModelMetadata | undefined;\n }\n >,\n>(\n baseClass: BaseClass,\n) => {\n return class extends baseClass {\n /** By repository class name, for the by-name API. Two classes may share a name; `repositoryBindingsByClass` cannot confuse them. */\n repositoryBindings: Map<string, IRepositoryBinding<AbstractEntity>>;\n\n /** By repository class: a minified build renames classes, and two chunks may give two of them one name. */\n repositoryBindingsByClass: Map<Function, IRepositoryBinding<AbstractEntity>>;\n\n /**\n * The model classes each datasource owns, keyed by the datasource class - or by the string a\n * repository named it with (`dataSource: 'PgDataSource'`), which only a class of that name\n * can match. Never by class name alone: a minified build gives two datasources one name.\n */\n datasourceModels: Map<string | Function, Set<TClass<AnyType>>>;\n\n setRepositoryMetadata<\n Target extends object = object,\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n >(opts: {\n target: Target;\n metadata: TRepositoryMetadata<Model, DataSource> & {\n _resolved?: IResolvedRepositoryMetadata<Model, DataSource>;\n };\n }): void {\n const { target, metadata } = opts;\n Reflect.defineMetadata(MetadataKeys.REPOSITORY, metadata, target);\n }\n\n getRepositoryMetadata<Target extends object = object>(opts: {\n target: Target;\n }): (TRepositoryMetadata & { _resolved?: IResolvedRepositoryMetadata }) | undefined {\n const { target } = opts;\n return Reflect.getMetadata(MetadataKeys.REPOSITORY, target);\n }\n\n /** Registers a repository binding (called by @repository) linking a repository to its model + datasource. */\n registerRepositoryBinding<\n Model extends AbstractEntity = AbstractEntity,\n DataSource extends IDataSource = IDataSource,\n >(opts: IRepositoryBinding<Model, DataSource>) {\n // Every member of the binding may be a resolver, the escape hatch for circular imports.\n // Reading `.name` off the resolver keys the registry by the arrow's inferred name, and the\n // datasource then silently discovers no schema.\n const repositoryClass = resolveValue({ value: opts.repository });\n this.repositoryBindings.set(repositoryClass.name, opts);\n this.repositoryBindingsByClass.set(repositoryClass, opts);\n\n const dataSourceRef = resolveValue({ value: opts.dataSource });\n const modelClass = resolveValue({ value: opts.model });\n\n if (!this.datasourceModels.has(dataSourceRef)) {\n this.datasourceModels.set(dataSourceRef, new Set());\n }\n\n this.datasourceModels.get(dataSourceRef)!.add(modelClass);\n }\n\n /** By class, walking up to the nearest decorated parent; by name only for callers holding a name. */\n getRepositoryBinding(\n opts: { target: Function } | { name: string },\n ): IRepositoryBinding<AbstractEntity> | undefined {\n if ('name' in opts) {\n return this.repositoryBindings.get(opts.name);\n }\n\n for (\n let current: Function | null = opts.target;\n current && current !== Function.prototype;\n current = Object.getPrototypeOf(current)\n ) {\n const binding = this.repositoryBindingsByClass.get(current);\n if (binding) {\n return binding;\n }\n }\n\n return undefined;\n }\n\n /** A class finds what was registered under it, and under a string equal to its name. */\n getDataSourceModelClasses(opts: {\n dataSource: string | TClass<IDataSource>;\n }): Set<TClass<AnyType>> {\n const { dataSource } = opts;\n\n if (typeof dataSource === 'string') {\n return this.datasourceModels.get(dataSource) ?? new Set();\n }\n\n return new Set([\n ...(this.datasourceModels.get(dataSource) ?? []),\n ...(this.datasourceModels.get(dataSource.name) ?? []),\n ]);\n }\n\n /**\n * Resolves and caches relations for a model entry - called lazily from buildSchema() so that\n * every `@model` class is registered first, which avoids circular-dependency ordering issues.\n * @internal\n */\n resolveModelRelations(modelMeta: IModelRegistryEntry): unknown {\n if (modelMeta._builtRelations !== undefined) {\n return modelMeta._builtRelations;\n }\n\n if (!modelMeta.relationsResolver) {\n return undefined;\n }\n\n const relations = resolveValue({ value: modelMeta.relationsResolver });\n\n if (!relations || !modelMeta.schema) {\n return undefined;\n }\n\n const builder = RelationBuilderRegistry.resolve();\n\n // Relations were declared but no connector installed a builder - silently dropping them\n // would surface much later as an empty `with` clause.\n if (!builder) {\n throw getError({\n message: `[RepositoryMetadataMixin][resolveModelRelations] Model declares relations but no relation builder is registered | Import the relational connector so it installs one`,\n });\n }\n\n const builtRelations = builder({ source: modelMeta.schema, relations });\n\n modelMeta._builtRelations = builtRelations?.relations;\n return modelMeta._builtRelations;\n }\n\n /**\n * Models registered for a datasource, relations resolved lazily. `schema`/`relations` stay\n * `unknown` - the registry is shared across connectors, so each connector narrows at its call\n * site.\n */\n getModels(opts: { dataSource: string | TClass<IDataSource> }): Array<{\n tableName: string;\n schema: unknown;\n relations?: unknown;\n }> {\n const modelClasses = this.getDataSourceModelClasses({ dataSource: opts.dataSource });\n\n const rs = Array.from(modelClasses)\n .map((modelClass) => {\n // Read straight off the class: a class -> name -> modelRegistry round-trip collapses two\n // same-named models onto one entry, silently swapping schemas. `modelRegistry` stays\n // name-keyed for the by-name APIs that need it.\n const entry: IModelRegistryEntry = {\n target: modelClass as AnyType,\n metadata:\n this.getModelMetadata({ target: modelClass }) ?? ({ settings: {} } as AnyType),\n schema: (modelClass as AnyType).schema,\n relationsResolver: (modelClass as AnyType).relations,\n };\n\n if (entry.schema === undefined) {\n return null;\n }\n\n return {\n tableName: this.resolveModelKey({ modelClass }),\n schema: entry.schema,\n relations: this.resolveModelRelations(entry),\n };\n })\n .filter((item): item is NonNullable<typeof item> => {\n return item !== undefined && item !== null;\n });\n\n return rs;\n }\n\n /**\n * Like getModels but returns only resolved model classes - used by BaseSearchDataSource, which\n * has no pgTable to resolve.\n */\n getModelClasses(opts: { dataSource: string | TClass<IDataSource> }): Array<TClass<unknown>> {\n // Straight from the stored class refs: a name round-trip through the shared modelRegistry\n // would hand back whichever same-named class registered last.\n return Array.from(this.getDataSourceModelClasses({ dataSource: opts.dataSource }));\n }\n\n /** The key a model occupies in `modelRegistry` - its table name, or its class name when it has none. */\n resolveModelKey(opts: { modelClass: TClass<AnyType> }): string {\n const { modelClass } = opts;\n const modelMetadata = this.getModelMetadata({ target: modelClass });\n\n return (\n [modelMetadata?.tableName, (modelClass as AnyType).TABLE_NAME].find(Boolean) ??\n modelClass.name\n );\n }\n\n /** Assembles table schemas + relations for a datasource's registered models. */\n buildSchema(opts: { dataSource: string | TClass<IDataSource> }): {\n schema: Record<string, unknown>;\n relations: Record<string, unknown>;\n } {\n const { dataSource } = opts;\n const models = this.getModels({ dataSource });\n\n const rs: {\n schema: Record<string, unknown>;\n relations: Record<string, unknown>;\n } = { schema: {}, relations: {} };\n\n for (const model of models) {\n if (model.schema) {\n rs.schema[model.tableName] = model.schema;\n }\n\n if (model.relations) {\n rs.relations[`${model.tableName}Relations`] = model.relations;\n }\n }\n\n return rs;\n }\n\n hasModels(opts: { dataSource: string | TClass<IDataSource> }): boolean {\n return this.getDataSourceModelClasses({ dataSource: opts.dataSource }).size > 0;\n }\n };\n};\n"]}
|
package/dist/cjs/repository.d.ts
CHANGED
|
@@ -28,5 +28,5 @@ export type { IDataSource } from './base/datasources/common/types';
|
|
|
28
28
|
export { AbstractEntity } from './base/models/base';
|
|
29
29
|
export { SchemaTypes } from './base/models/common/constants';
|
|
30
30
|
export type { TIdSchemaType, TSchemaType } from './base/models/common';
|
|
31
|
-
export type { TFilter, TInclusion, TWhere } from '@venizia/ignis-filter';
|
|
31
|
+
export type { TByIdFilter, TFields, TFilter, TInclusion, TRow, TSelectedRow, TWhere, } from '@venizia/ignis-filter';
|
|
32
32
|
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACrB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAI5F,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAEnG,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGvE,YAAY,
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACrB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAI5F,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAEnG,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGvE,YAAY,EACV,WAAW,EACX,OAAO,EACP,OAAO,EACP,UAAU,EACV,IAAI,EACJ,YAAY,EACZ,MAAM,GACP,MAAM,uBAAuB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAEH,8DAAuE;AAA9D,8GAAA,kBAAkB,OAAA;AAC3B,wDAAiE;AAAxD,8GAAA,kBAAkB,OAAA;AAY3B,oEAA0E;AAAjE,yGAAA,cAAc,OAAA;AAEvB,gGAAgG;AAChG,yCAAyC;AACzC,8EAAgF;AAAvE,qHAAA,kBAAkB,OAAA;AAC3B,0EAA4E;AAAnE,iHAAA,gBAAgB,OAAA;AAGzB,mGAAmG;AACnG,mEAAmE;AACnE,kEAK8C;AAJ5C,0GAAA,aAAa,OAAA;AACb,8GAAA,iBAAiB,OAAA;AACjB,sHAAA,yBAAyB,OAAA;AACzB,4GAAA,eAAe,OAAA;AAGjB,oDAAwE;AAA/D,6GAAA,cAAc,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AACzC,2DAA8D;AAArD,kHAAA,iBAAiB,OAAA;AAK1B,mGAAmG;AACnG,qFAAqF;AACrF,2CAAoD;AAA3C,sGAAA,cAAc,OAAA;AACvB,4DAA6D;AAApD,wGAAA,WAAW,OAAA","sourcesContent":["/**\n * The persistence contract, and nothing about how a row is served or validated.\n *\n * A repository talks to a datasource. `AbstractDataSource` is engine-neutral - its only required\n * member is `configure()` - so \"an HTTP request to another server\" is a datasource in the same sense\n * Drizzle-over-Postgres is one: same role, different transport. This entry exists so a consumer can\n * implement that without taking the OpenAPI layer, which `base/repositories` reaches through\n * `query-schemas` and `result-schemas`.\n *\n * Both halves already speak `@venizia/ignis-filter`, so a consumer on another transport shares the\n * query vocabulary rather than translating into one.\n *\n * Weight is a contract, checked by `src/__tests__/bundle/browser-weight.test.ts`.\n */\n\nexport { AbstractRepository } from '@/base/repositories/core/abstract';\nexport { AbstractDataSource } from '@/base/datasources/abstract';\n\nexport type {\n ICreatableRepository,\n ICrudRepository,\n IDeletableRepository,\n IPersistableRepository,\n IReadableRepository,\n IRepository,\n IUpdatableRepository,\n} from '@/base/repositories/common/types/contracts';\n\nexport { buildDataRange } from '@/base/repositories/common/types/results';\n\n// How a client reads what an IGNIS server answers - shared by the http connector and any client\n// that reads the same server without it.\nexport { HttpResponseReader } from '@/base/repositories/common/response-reader';\nexport { HttpExtraRequest } from '@/base/repositories/common/extra-request';\nexport type { TExtraRequest, TExtraResult } from '@/base/repositories/common/extra-request';\n\n// What a repository on any transport raises and bounds itself by - the constants, the error codes,\n// and the helper an engine that lacks an operation throws through.\nexport {\n DEFAULT_LIMIT,\n DEFAULT_MAX_LIMIT,\n RepositoryOperationScopes,\n RepositoryTypes,\n} from '@/base/repositories/common/constants';\nexport type { TRepositoryType } from '@/base/repositories/common/constants';\nexport { CoreErrorCodes, SearchErrorCodes } from '@/common/error-codes';\nexport { throwNotSupported } from '@/utilities/error.utility';\nexport type { TCount, TDataRange, TDataWithRange } from '@/base/repositories/common/types/results';\n\nexport type { IDataSource } from '@/base/datasources/common/types';\n\n// `IRepository` names an entity, so a consumer implementing the contract needs the base to extend.\n// Engine-neutral like the datasource: a name, `getSchema({ type })`, and an id type.\nexport { AbstractEntity } from '@/base/models/base';\nexport { SchemaTypes } from '@/base/models/common/constants';\nexport type { TIdSchemaType, TSchemaType } from '@/base/models/common';\n\n// The query vocabulary both transports share.\nexport type {
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAEH,8DAAuE;AAA9D,8GAAA,kBAAkB,OAAA;AAC3B,wDAAiE;AAAxD,8GAAA,kBAAkB,OAAA;AAY3B,oEAA0E;AAAjE,yGAAA,cAAc,OAAA;AAEvB,gGAAgG;AAChG,yCAAyC;AACzC,8EAAgF;AAAvE,qHAAA,kBAAkB,OAAA;AAC3B,0EAA4E;AAAnE,iHAAA,gBAAgB,OAAA;AAGzB,mGAAmG;AACnG,mEAAmE;AACnE,kEAK8C;AAJ5C,0GAAA,aAAa,OAAA;AACb,8GAAA,iBAAiB,OAAA;AACjB,sHAAA,yBAAyB,OAAA;AACzB,4GAAA,eAAe,OAAA;AAGjB,oDAAwE;AAA/D,6GAAA,cAAc,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AACzC,2DAA8D;AAArD,kHAAA,iBAAiB,OAAA;AAK1B,mGAAmG;AACnG,qFAAqF;AACrF,2CAAoD;AAA3C,sGAAA,cAAc,OAAA;AACvB,4DAA6D;AAApD,wGAAA,WAAW,OAAA","sourcesContent":["/**\n * The persistence contract, and nothing about how a row is served or validated.\n *\n * A repository talks to a datasource. `AbstractDataSource` is engine-neutral - its only required\n * member is `configure()` - so \"an HTTP request to another server\" is a datasource in the same sense\n * Drizzle-over-Postgres is one: same role, different transport. This entry exists so a consumer can\n * implement that without taking the OpenAPI layer, which `base/repositories` reaches through\n * `query-schemas` and `result-schemas`.\n *\n * Both halves already speak `@venizia/ignis-filter`, so a consumer on another transport shares the\n * query vocabulary rather than translating into one.\n *\n * Weight is a contract, checked by `src/__tests__/bundle/browser-weight.test.ts`.\n */\n\nexport { AbstractRepository } from '@/base/repositories/core/abstract';\nexport { AbstractDataSource } from '@/base/datasources/abstract';\n\nexport type {\n ICreatableRepository,\n ICrudRepository,\n IDeletableRepository,\n IPersistableRepository,\n IReadableRepository,\n IRepository,\n IUpdatableRepository,\n} from '@/base/repositories/common/types/contracts';\n\nexport { buildDataRange } from '@/base/repositories/common/types/results';\n\n// How a client reads what an IGNIS server answers - shared by the http connector and any client\n// that reads the same server without it.\nexport { HttpResponseReader } from '@/base/repositories/common/response-reader';\nexport { HttpExtraRequest } from '@/base/repositories/common/extra-request';\nexport type { TExtraRequest, TExtraResult } from '@/base/repositories/common/extra-request';\n\n// What a repository on any transport raises and bounds itself by - the constants, the error codes,\n// and the helper an engine that lacks an operation throws through.\nexport {\n DEFAULT_LIMIT,\n DEFAULT_MAX_LIMIT,\n RepositoryOperationScopes,\n RepositoryTypes,\n} from '@/base/repositories/common/constants';\nexport type { TRepositoryType } from '@/base/repositories/common/constants';\nexport { CoreErrorCodes, SearchErrorCodes } from '@/common/error-codes';\nexport { throwNotSupported } from '@/utilities/error.utility';\nexport type { TCount, TDataRange, TDataWithRange } from '@/base/repositories/common/types/results';\n\nexport type { IDataSource } from '@/base/datasources/common/types';\n\n// `IRepository` names an entity, so a consumer implementing the contract needs the base to extend.\n// Engine-neutral like the datasource: a name, `getSchema({ type })`, and an id type.\nexport { AbstractEntity } from '@/base/models/base';\nexport { SchemaTypes } from '@/base/models/common/constants';\nexport type { TIdSchemaType, TSchemaType } from '@/base/models/common';\n\n// The query vocabulary both transports share.\nexport type {\n TByIdFilter,\n TFields,\n TFilter,\n TInclusion,\n TRow,\n TSelectedRow,\n TWhere,\n} from '@venizia/ignis-filter';\n"]}
|
|
@@ -59,7 +59,7 @@ export class AbstractApplication extends Container {
|
|
|
59
59
|
throw getError({
|
|
60
60
|
statusCode: HTTP.ResultCodes.RS_5.InternalServerError,
|
|
61
61
|
message: `[executePostStartHooks] Failed post-start hook(s): ${failures
|
|
62
|
-
.map(failure => `${failure.identifier} (${failure.error})`)
|
|
62
|
+
.map((failure) => `${failure.identifier} (${failure.error})`)
|
|
63
63
|
.join(', ')}`,
|
|
64
64
|
});
|
|
65
65
|
}
|
|
@@ -83,7 +83,7 @@ export class AbstractApplication extends Container {
|
|
|
83
83
|
registerCoreBindings() {
|
|
84
84
|
this.bind({
|
|
85
85
|
key: CoreBindings.APPLICATION_INSTANCE,
|
|
86
|
-
}).toProvider(_ => this);
|
|
86
|
+
}).toProvider((_) => this);
|
|
87
87
|
}
|
|
88
88
|
init() {
|
|
89
89
|
this.registerCoreBindings();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../src/base/applications/abstract.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../../src/base/applications/abstract.ts"],"names":[],"mappings":"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","sourcesContent":["import { CoreBindings } from '@/common/bindings';\nimport { Container } from '@/helpers/inversion/container';\nimport type { ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { HTTP } from '@venizia/ignis-helpers/common';\nimport type { IApplicationConfigs, IApplicationInfo } from './common';\n\nexport abstract class AbstractApplication extends Container {\n protected configs: IApplicationConfigs;\n protected projectRoot: string;\n\n private postStartHooks: Array<{ identifier: string; hook: () => ValueOrPromise<void> }> = [];\n private postStopHooks: Array<{ identifier: string; hook: () => ValueOrPromise<void> }> = [];\n\n constructor(opts: { scope: string; config: IApplicationConfigs }) {\n const { scope, config } = opts;\n super({ scope });\n\n this.configs = Object.assign({}, config, {\n asyncContext: {\n enable: config?.asyncContext?.enable ?? this.getDefaultAsyncContextEnabled(),\n },\n });\n\n this.projectRoot = this.getProjectRoot();\n this.logger.for('constructor').info('Project root: %s', this.projectRoot);\n }\n\n abstract getAppInfo(): ValueOrPromise<IApplicationInfo>;\n abstract preConfigure(): ValueOrPromise<void>;\n\n /**\n * Runs after every registration sweep (datasources, components, controllers) has already\n * completed. Registering a new one here is not auto-registered and silently does nothing -\n * call `configure()` manually instead.\n */\n abstract postConfigure(): ValueOrPromise<void>;\n\n abstract staticConfigure(): void;\n\n abstract setupMiddlewares(opts?: {\n middlewares?: Record<string | symbol, any>;\n }): ValueOrPromise<void>;\n\n abstract initialize(): Promise<void>;\n\n protected getDefaultAsyncContextEnabled(): boolean {\n return false;\n }\n\n getProjectConfigs(): IApplicationConfigs {\n return this.configs;\n }\n\n getProjectRoot(): string {\n const projectRoot = '';\n this.bind<string>({ key: CoreBindings.APPLICATION_PROJECT_ROOT }).toValue(projectRoot);\n return projectRoot;\n }\n\n registerPostStartHook(opts: { identifier: string; hook: () => ValueOrPromise<void> }) {\n this.postStartHooks.push(opts);\n this.logger\n .for(this.registerPostStartHook.name)\n .debug('Registered post-start hook | identifier: %s', opts.identifier);\n }\n\n /** Runs every post-start hook in isolation - the server is already listening, so a throwing hook must not cancel the ones behind it; failures are collected and reported as one error at the end. */\n protected async executePostStartHooks() {\n if (this.postStartHooks.length === 0) {\n return;\n }\n\n const logger = this.logger.for(this.executePostStartHooks.name);\n logger.info('Executing %s post-start hook(s)...', this.postStartHooks.length);\n\n const failures: Array<{ identifier: string; error: unknown }> = [];\n\n for (const { identifier, hook } of this.postStartHooks) {\n const t = performance.now();\n\n try {\n await hook();\n } catch (error) {\n logger.error('Failed to execute hook | identifier: %s | error: %s', identifier, error);\n failures.push({ identifier, error });\n continue;\n }\n\n logger.info(\n 'Executed hook | identifier: %s | took: %s (ms)',\n identifier,\n performance.now() - t,\n );\n }\n\n if (failures.length === 0) {\n return;\n }\n\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: `[executePostStartHooks] Failed post-start hook(s): ${failures\n .map((failure) => `${failure.identifier} (${failure.error})`)\n .join(', ')}`,\n });\n }\n\n registerPostStopHook(opts: { identifier: string; hook: () => ValueOrPromise<void> }) {\n this.postStopHooks.push(opts);\n this.logger\n .for(this.registerPostStopHook.name)\n .debug('Registered post-stop hook | identifier: %s', opts.identifier);\n }\n\n protected async executePostStopHooks() {\n const logger = this.logger.for(this.executePostStopHooks.name);\n for (const { identifier, hook } of this.postStopHooks) {\n try {\n await hook();\n } catch (error) {\n logger.error('Post-stop hook failed | identifier: %s | error: %s', identifier, error);\n }\n }\n }\n\n protected registerCoreBindings() {\n this.bind<typeof this>({\n key: CoreBindings.APPLICATION_INSTANCE,\n }).toProvider((_) => this);\n }\n\n init() {\n this.registerCoreBindings();\n }\n}\n"]}
|
|
@@ -35,7 +35,7 @@ export class ArtifactGroup {
|
|
|
35
35
|
/** A group carrying only `kinds` - for a slicer that splits `configs.artifacts` by run mode. The source group is resolved when artifacts are registered, never here. */
|
|
36
36
|
static pick(opts) {
|
|
37
37
|
const { group, kinds } = opts;
|
|
38
|
-
const slice = (index) => Object.fromEntries(kinds.filter(kind => index[kind] !== undefined).map(kind => [kind, index[kind]]));
|
|
38
|
+
const slice = (index) => Object.fromEntries(kinds.filter((kind) => index[kind] !== undefined).map((kind) => [kind, index[kind]]));
|
|
39
39
|
return new ArtifactGroup({
|
|
40
40
|
folder: group.folder,
|
|
41
41
|
site: group.site,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-group.js","sourceRoot":"","sources":["../../../../src/base/applications/artifact-group.ts"],"names":[],"mappings":"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","sourcesContent":["import { SingletonRealm } from '@/helpers/singleton-realm';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { IArtifactGroup, IArtifactIndex } from './common';\n\ntype TGroupResolver = (opts: { group: IArtifactGroup }) => Promise<IArtifactIndex>;\n\n/** A typed slice of a shared package's artifacts - every decorated class under a directory named `folder` in the package that defined it. A package declares one per domain, once; an application borrows it in `configs.artifacts`. The content is filled by `@venizia/ignis-boot`: inlined when the application is built, or resolved from source when artifacts are registered. */\nexport class ArtifactGroup implements IArtifactGroup {\n /** A string brand, so the group protocol is structural: `@venizia/ignis-boot/auto` builds one without depending on the kernel. */\n static readonly BRAND_KEY = 'isArtifactGroup';\n /** The realm slot `@venizia/ignis-boot` fills with the resolver for groups defined without content. */\n static readonly SINGLETON_REALM_KEY = 'artifact-group-resolver';\n\n readonly isArtifactGroup = true as const;\n readonly resolve: (() => Promise<IArtifactIndex>) | undefined;\n readonly kinds: ReadonlyArray<keyof IArtifactIndex> | undefined;\n\n private constructor(opts: {\n folder: string | undefined;\n site: string | undefined;\n content: IArtifactIndex | undefined;\n resolve?: () => Promise<IArtifactIndex>;\n kinds?: ReadonlyArray<keyof IArtifactIndex>;\n ignore?: ReadonlyArray<string>;\n }) {\n this.folder = opts.folder;\n this.site = opts.site;\n this.content = opts.content;\n this.resolve = opts.resolve;\n this.kinds = opts.kinds;\n this.ignore = opts.ignore;\n }\n\n readonly folder: string | undefined;\n readonly site: string | undefined;\n readonly content: IArtifactIndex | undefined;\n readonly ignore: ReadonlyArray<string> | undefined;\n\n /** `content` is written by the build plugin; a hand-written group passes only `folder`. */\n static define(opts: { folder: string; content?: IArtifactIndex }): ArtifactGroup {\n return new ArtifactGroup({\n folder: opts.folder,\n site: ArtifactGroup.callSite(),\n content: opts.content,\n });\n }\n\n /** Every decorated class of the calling package - an application's own artifacts, picked by its call site, so several applications in one process each get their own. `ignore` takes the globs `ignis-artifacts --ignore` takes, relative to the package `src`. `content` is written by the build plugin. */\n static application(\n opts: { ignore?: ReadonlyArray<string>; content?: IArtifactIndex } = {},\n ): ArtifactGroup {\n return new ArtifactGroup({\n folder: undefined,\n site: ArtifactGroup.callSite(),\n content: opts.content,\n ignore: opts.ignore,\n });\n }\n\n /** A group carrying only `kinds` - for a slicer that splits `configs.artifacts` by run mode. The source group is resolved when artifacts are registered, never here. */\n static pick(opts: {\n group: IArtifactGroup;\n kinds: ReadonlyArray<keyof IArtifactIndex>;\n }): ArtifactGroup {\n const { group, kinds } = opts;\n const slice = (index: IArtifactIndex): IArtifactIndex =>\n Object.fromEntries(\n kinds.filter(kind => index[kind] !== undefined).map(kind => [kind, index[kind]]),\n );\n\n return new ArtifactGroup({\n folder: group.folder,\n site: group.site,\n content: group.content ? slice(group.content) : undefined,\n resolve: async () => slice(await ArtifactGroup.resolveContent({ group })),\n kinds,\n ignore: group.ignore,\n });\n }\n\n /** A group's classes: inlined by a build, else its own `resolve()`, else the resolver `@venizia/ignis-boot/auto` installs. */\n static async resolveContent(opts: { group: IArtifactGroup }): Promise<IArtifactIndex> {\n const { group } = opts;\n if (group.content) {\n return group.content;\n }\n if (group.resolve) {\n return group.resolve();\n }\n const resolve = ArtifactGroup.getResolver();\n if (!resolve) {\n throw getError({\n message: `[ArtifactGroup] '${group.folder ?? '<application>'}' has no content | Import @venizia/ignis-boot/auto in the application (it resolves groups from source), or add IgnisArtifactsPlugin to the build's plugins`,\n });\n }\n return resolve({ group });\n }\n\n /** Positional on purpose: a type predicate narrows its own parameter, and an options object would narrow the wrapper instead of `value`. */\n static isGroup(value: unknown): value is IArtifactGroup {\n return (\n typeof value === 'object' &&\n value !== null &&\n ArtifactGroup.BRAND_KEY in value &&\n value[ArtifactGroup.BRAND_KEY] === true\n );\n }\n\n static setResolver(opts: { resolve: TGroupResolver | undefined }): void {\n ArtifactGroup.holder().resolve = opts.resolve;\n }\n\n static getResolver(): TGroupResolver | undefined {\n return ArtifactGroup.holder().resolve;\n }\n\n /** The error a walker over `configs.artifacts` gets for reading a kind off a group - loud, never an empty list. */\n static unreadKindError(opts: { folder: string | undefined }): Error {\n return getError({\n message: `[ArtifactGroup] '${opts.folder ?? '<application>'}' is resolved when artifacts are registered | A function that walks configs.artifacts must pass a group through untouched (ArtifactGroup.isGroup) instead of reading its kinds`,\n });\n }\n\n get configurations(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get dataSources(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get components(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get repositories(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get services(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get controllers(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n private static holder(): { resolve: TGroupResolver | undefined } {\n return SingletonRealm.resolve({\n key: ArtifactGroup.SINGLETON_REALM_KEY,\n create: () => ({ resolve: undefined }),\n });\n }\n\n /** The module that declared the group, read from the call stack. */\n private static callSite(): string | undefined {\n // A stack trace, not a failure: reading the call site needs an Error object, and nothing is thrown.\n // eslint-disable-next-line venizia/no-new-error\n return ArtifactGroup.siteFromStack({ stack: new Error().stack ?? '' });\n }\n\n /** The first frame outside the kernel's own `artifact-group` file: POSIX and Windows paths, `file://` URLs (decoded, drive kept), parentheses inside a path. */\n static siteFromStack(opts: { stack: string }): string | undefined {\n for (const raw of opts.stack.split('\\n').slice(1)) {\n const frame = raw.trim().replace(/^at\\s+/, '');\n const opening = frame.indexOf(' (');\n const location = frame.endsWith(')') && opening >= 0 ? frame.slice(opening + 2, -1) : frame;\n let file = location.replace(/:\\d+:\\d+$/, '');\n if (file.startsWith('file://')) {\n file = decodeURIComponent(file.slice('file://'.length)).replace(/^\\/([A-Za-z]:\\/)/, '$1');\n }\n const isPath = file.startsWith('/') || /^[A-Za-z]:[\\\\/]/.test(file);\n if (isPath && !/(?:^|[\\\\/])artifact-group\\.(?:ts|js)$/.test(file)) {\n return file;\n }\n }\n return undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-group.js","sourceRoot":"","sources":["../../../../src/base/applications/artifact-group.ts"],"names":[],"mappings":"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","sourcesContent":["import { SingletonRealm } from '@/helpers/singleton-realm';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { IArtifactGroup, IArtifactIndex } from './common';\n\ntype TGroupResolver = (opts: { group: IArtifactGroup }) => Promise<IArtifactIndex>;\n\n/** A typed slice of a shared package's artifacts - every decorated class under a directory named `folder` in the package that defined it. A package declares one per domain, once; an application borrows it in `configs.artifacts`. The content is filled by `@venizia/ignis-boot`: inlined when the application is built, or resolved from source when artifacts are registered. */\nexport class ArtifactGroup implements IArtifactGroup {\n /** A string brand, so the group protocol is structural: `@venizia/ignis-boot/auto` builds one without depending on the kernel. */\n static readonly BRAND_KEY = 'isArtifactGroup';\n /** The realm slot `@venizia/ignis-boot` fills with the resolver for groups defined without content. */\n static readonly SINGLETON_REALM_KEY = 'artifact-group-resolver';\n\n readonly isArtifactGroup = true as const;\n readonly resolve: (() => Promise<IArtifactIndex>) | undefined;\n readonly kinds: ReadonlyArray<keyof IArtifactIndex> | undefined;\n\n private constructor(opts: {\n folder: string | undefined;\n site: string | undefined;\n content: IArtifactIndex | undefined;\n resolve?: () => Promise<IArtifactIndex>;\n kinds?: ReadonlyArray<keyof IArtifactIndex>;\n ignore?: ReadonlyArray<string>;\n }) {\n this.folder = opts.folder;\n this.site = opts.site;\n this.content = opts.content;\n this.resolve = opts.resolve;\n this.kinds = opts.kinds;\n this.ignore = opts.ignore;\n }\n\n readonly folder: string | undefined;\n readonly site: string | undefined;\n readonly content: IArtifactIndex | undefined;\n readonly ignore: ReadonlyArray<string> | undefined;\n\n /** `content` is written by the build plugin; a hand-written group passes only `folder`. */\n static define(opts: { folder: string; content?: IArtifactIndex }): ArtifactGroup {\n return new ArtifactGroup({\n folder: opts.folder,\n site: ArtifactGroup.callSite(),\n content: opts.content,\n });\n }\n\n /** Every decorated class of the calling package - an application's own artifacts, picked by its call site, so several applications in one process each get their own. `ignore` takes the globs `ignis-artifacts --ignore` takes, relative to the package `src`. `content` is written by the build plugin. */\n static application(\n opts: { ignore?: ReadonlyArray<string>; content?: IArtifactIndex } = {},\n ): ArtifactGroup {\n return new ArtifactGroup({\n folder: undefined,\n site: ArtifactGroup.callSite(),\n content: opts.content,\n ignore: opts.ignore,\n });\n }\n\n /** A group carrying only `kinds` - for a slicer that splits `configs.artifacts` by run mode. The source group is resolved when artifacts are registered, never here. */\n static pick(opts: {\n group: IArtifactGroup;\n kinds: ReadonlyArray<keyof IArtifactIndex>;\n }): ArtifactGroup {\n const { group, kinds } = opts;\n const slice = (index: IArtifactIndex): IArtifactIndex =>\n Object.fromEntries(\n kinds.filter((kind) => index[kind] !== undefined).map((kind) => [kind, index[kind]]),\n );\n\n return new ArtifactGroup({\n folder: group.folder,\n site: group.site,\n content: group.content ? slice(group.content) : undefined,\n resolve: async () => slice(await ArtifactGroup.resolveContent({ group })),\n kinds,\n ignore: group.ignore,\n });\n }\n\n /** A group's classes: inlined by a build, else its own `resolve()`, else the resolver `@venizia/ignis-boot/auto` installs. */\n static async resolveContent(opts: { group: IArtifactGroup }): Promise<IArtifactIndex> {\n const { group } = opts;\n if (group.content) {\n return group.content;\n }\n if (group.resolve) {\n return group.resolve();\n }\n const resolve = ArtifactGroup.getResolver();\n if (!resolve) {\n throw getError({\n message: `[ArtifactGroup] '${group.folder ?? '<application>'}' has no content | Import @venizia/ignis-boot/auto in the application (it resolves groups from source), or add IgnisArtifactsPlugin to the build's plugins`,\n });\n }\n return resolve({ group });\n }\n\n /** Positional on purpose: a type predicate narrows its own parameter, and an options object would narrow the wrapper instead of `value`. */\n static isGroup(value: unknown): value is IArtifactGroup {\n return (\n typeof value === 'object' &&\n value !== null &&\n ArtifactGroup.BRAND_KEY in value &&\n value[ArtifactGroup.BRAND_KEY] === true\n );\n }\n\n static setResolver(opts: { resolve: TGroupResolver | undefined }): void {\n ArtifactGroup.holder().resolve = opts.resolve;\n }\n\n static getResolver(): TGroupResolver | undefined {\n return ArtifactGroup.holder().resolve;\n }\n\n /** The error a walker over `configs.artifacts` gets for reading a kind off a group - loud, never an empty list. */\n static unreadKindError(opts: { folder: string | undefined }): Error {\n return getError({\n message: `[ArtifactGroup] '${opts.folder ?? '<application>'}' is resolved when artifacts are registered | A function that walks configs.artifacts must pass a group through untouched (ArtifactGroup.isGroup) instead of reading its kinds`,\n });\n }\n\n get configurations(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get dataSources(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get components(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get repositories(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get services(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n get controllers(): never {\n throw ArtifactGroup.unreadKindError({ folder: this.folder });\n }\n\n private static holder(): { resolve: TGroupResolver | undefined } {\n return SingletonRealm.resolve({\n key: ArtifactGroup.SINGLETON_REALM_KEY,\n create: () => ({ resolve: undefined }),\n });\n }\n\n /** The module that declared the group, read from the call stack. */\n private static callSite(): string | undefined {\n // A stack trace, not a failure: reading the call site needs an Error object, and nothing is thrown.\n // eslint-disable-next-line venizia/no-new-error\n return ArtifactGroup.siteFromStack({ stack: new Error().stack ?? '' });\n }\n\n /** The first frame outside the kernel's own `artifact-group` file: POSIX and Windows paths, `file://` URLs (decoded, drive kept), parentheses inside a path. */\n static siteFromStack(opts: { stack: string }): string | undefined {\n for (const raw of opts.stack.split('\\n').slice(1)) {\n const frame = raw.trim().replace(/^at\\s+/, '');\n const opening = frame.indexOf(' (');\n const location = frame.endsWith(')') && opening >= 0 ? frame.slice(opening + 2, -1) : frame;\n let file = location.replace(/:\\d+:\\d+$/, '');\n if (file.startsWith('file://')) {\n file = decodeURIComponent(file.slice('file://'.length)).replace(/^\\/([A-Za-z]:\\/)/, '$1');\n }\n const isPath = file.startsWith('/') || /^[A-Za-z]:[\\\\/]/.test(file);\n if (isPath && !/(?:^|[\\\\/])artifact-group\\.(?:ts|js)$/.test(file)) {\n return file;\n }\n }\n return undefined;\n }\n}\n"]}
|
|
@@ -107,8 +107,8 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
107
107
|
for (const prereq of afterList) {
|
|
108
108
|
// A string names a class, the only form that can; a class is matched by identity.
|
|
109
109
|
const prereqClass = typeof prereq === 'function'
|
|
110
|
-
? classes.find(candidate => candidate === prereq)
|
|
111
|
-
: classes.find(candidate => candidate.name === String(prereq));
|
|
110
|
+
? classes.find((candidate) => candidate === prereq)
|
|
111
|
+
: classes.find((candidate) => candidate.name === String(prereq));
|
|
112
112
|
if (!prereqClass) {
|
|
113
113
|
const prereqName = typeof prereq === 'function' ? prereq.name : String(prereq);
|
|
114
114
|
throw getError({
|
|
@@ -122,7 +122,7 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
122
122
|
// Kahn's algorithm. Siblings run in class-name order; a minified build renames classes, so an
|
|
123
123
|
// order that matters belongs in `after`.
|
|
124
124
|
const byName = (a, b) => a.name.localeCompare(b.name);
|
|
125
|
-
const available = classes.filter(target => inDegree.get(target) === 0).sort(byName);
|
|
125
|
+
const available = classes.filter((target) => inDegree.get(target) === 0).sort(byName);
|
|
126
126
|
const sorted = [];
|
|
127
127
|
while (available.length > 0) {
|
|
128
128
|
const current = available.shift();
|
|
@@ -138,8 +138,8 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
138
138
|
}
|
|
139
139
|
if (sorted.length !== classes.length) {
|
|
140
140
|
const unvisited = classes
|
|
141
|
-
.filter(target => !sorted.includes(target))
|
|
142
|
-
.map(target => target.name);
|
|
141
|
+
.filter((target) => !sorted.includes(target))
|
|
142
|
+
.map((target) => target.name);
|
|
143
143
|
throw getError({
|
|
144
144
|
message: `[sortConfigurationsTopologically] Dependency cycle detected in configurations: ${unvisited.join(', ')}`,
|
|
145
145
|
});
|
|
@@ -148,7 +148,7 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
148
148
|
}
|
|
149
149
|
/** Every entry of a kind must be a class. `undefined` is what an import cycle leaves - the index was read before a class's module finished loading - so it gets a message that names the cause instead of a crash on `.name`. */
|
|
150
150
|
assertClasses(opts) {
|
|
151
|
-
const position = (opts.classes ?? []).findIndex(target => typeof target !== 'function');
|
|
151
|
+
const position = (opts.classes ?? []).findIndex((target) => typeof target !== 'function');
|
|
152
152
|
if (position >= 0) {
|
|
153
153
|
throw getError({
|
|
154
154
|
message: `[ArtifactIndex] '${opts.field}' lists an entry that is not a class (position ${position}) | Usually an import cycle: the index was read before that class's module finished loading. The module that imports the index (or @venizia/ignis-boot/auto) must not define decorated classes or be imported by them`,
|
|
@@ -162,7 +162,7 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
162
162
|
return this.flatten({ input: await this.contentOf({ group: input }), application });
|
|
163
163
|
}
|
|
164
164
|
if (Array.isArray(input)) {
|
|
165
|
-
const nested = await Promise.all(input.map(entry => this.flatten({ input: entry, application })));
|
|
165
|
+
const nested = await Promise.all(input.map((entry) => this.flatten({ input: entry, application })));
|
|
166
166
|
return nested.flat();
|
|
167
167
|
}
|
|
168
168
|
if (this.isConditional(input)) {
|
|
@@ -184,7 +184,7 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
184
184
|
this.assertClasses({ field, classes });
|
|
185
185
|
}
|
|
186
186
|
const kinds = Object.values(content);
|
|
187
|
-
const names = kinds.flatMap(classes => (classes ?? []).map(target => target.name));
|
|
187
|
+
const names = kinds.flatMap((classes) => (classes ?? []).map((target) => target.name));
|
|
188
188
|
if (names.length === 0 && !group.kinds) {
|
|
189
189
|
throw getError({
|
|
190
190
|
message: `[ArtifactGroup] '${group.folder ?? '<application>'}' resolved to no class | Defined in ${group.site ?? 'an unknown module'} - check the folder name and that its classes carry a stereotype decorator`,
|
|
@@ -203,9 +203,9 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
203
203
|
const registry = MetadataRegistry.getInstance();
|
|
204
204
|
// De-duplicated: discovery and a declared index can name the same class, and registering it
|
|
205
205
|
// twice trips `bootChecks.binding.allowOverride: false`. First mention wins its position.
|
|
206
|
-
const listed = [...new Set(indexes.flatMap(index => [...(index[field] ?? [])]))];
|
|
206
|
+
const listed = [...new Set(indexes.flatMap((index) => [...(index[field] ?? [])]))];
|
|
207
207
|
this.assertClasses({ field, classes: listed });
|
|
208
|
-
const decisions = await Promise.all(listed.map(target => this.isSelected({ target, application })));
|
|
208
|
+
const decisions = await Promise.all(listed.map((target) => this.isSelected({ target, application })));
|
|
209
209
|
const kept = listed.filter((target, position) => {
|
|
210
210
|
if (decisions[position]) {
|
|
211
211
|
return true;
|
|
@@ -220,7 +220,7 @@ export class ArtifactIndexHelper extends BaseHelper {
|
|
|
220
220
|
order: registry.getArtifactMetadata({ target })?.order ?? 0,
|
|
221
221
|
}))
|
|
222
222
|
.sort((a, b) => a.order - b.order || a.position - b.position)
|
|
223
|
-
.map(entry => entry.target);
|
|
223
|
+
.map((entry) => entry.target);
|
|
224
224
|
}
|
|
225
225
|
async isSelected(opts) {
|
|
226
226
|
const { target, application } = opts;
|