@api-client/core 0.20.6 → 0.20.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/build/src/modeling/ApiModel.d.ts.map +1 -1
  2. package/build/src/modeling/ApiModel.js +9 -5
  3. package/build/src/modeling/ApiModel.js.map +1 -1
  4. package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
  5. package/build/src/modeling/ExposedEntity.js +55 -4
  6. package/build/src/modeling/ExposedEntity.js.map +1 -1
  7. package/build/src/modeling/RuntimeApiModel.d.ts.map +1 -1
  8. package/build/src/modeling/RuntimeApiModel.js +6 -2
  9. package/build/src/modeling/RuntimeApiModel.js.map +1 -1
  10. package/build/src/modeling/generators/RuntimeModelGenerator.d.ts +15 -0
  11. package/build/src/modeling/generators/RuntimeModelGenerator.d.ts.map +1 -0
  12. package/build/src/modeling/generators/RuntimeModelGenerator.js +78 -0
  13. package/build/src/modeling/generators/RuntimeModelGenerator.js.map +1 -0
  14. package/build/src/modeling/helpers/endpointHelpers.d.ts +6 -1
  15. package/build/src/modeling/helpers/endpointHelpers.d.ts.map +1 -1
  16. package/build/src/modeling/helpers/endpointHelpers.js +43 -4
  17. package/build/src/modeling/helpers/endpointHelpers.js.map +1 -1
  18. package/build/src/modeling/validation/api_model_rules.d.ts.map +1 -1
  19. package/build/src/modeling/validation/api_model_rules.js +17 -0
  20. package/build/src/modeling/validation/api_model_rules.js.map +1 -1
  21. package/build/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +3 -3
  23. package/src/modeling/ApiModel.ts +9 -5
  24. package/src/modeling/ExposedEntity.ts +62 -4
  25. package/src/modeling/RuntimeApiModel.ts +7 -2
  26. package/src/modeling/generators/RuntimeModelGenerator.ts +79 -0
  27. package/src/modeling/helpers/endpointHelpers.ts +51 -4
  28. package/src/modeling/validation/api_model_rules.ts +19 -0
  29. package/tests/unit/modeling/RuntimeApiModel.spec.ts +17 -3
  30. package/tests/unit/modeling/api_model_expose_entity.spec.ts +2 -1
  31. package/tests/unit/modeling/exposed_entity.spec.ts +95 -0
  32. package/tests/unit/modeling/generators/OasGenerator.spec.ts +8 -8
  33. package/tests/unit/modeling/generators/RuntimeModelGenerator.spec.ts +192 -0
  34. package/tests/unit/modeling/helpers/endpointHelpers.spec.ts +10 -3
  35. package/tests/unit/modeling/validation/api_model_rules.spec.ts +35 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ import { DependentModel } from './DependentModel.js';
7
7
  import { observed, toRaw } from '../decorators/observed.js';
8
8
  import pluralize from '@jarrodek/pluralize';
9
9
  import { createDomainKey } from './helpers/keying.js';
10
+ import { paramNameFor } from './helpers/endpointHelpers.js';
10
11
  import { ExposedEntity } from './ExposedEntity.js';
11
12
  import { RateLimitingConfiguration } from './rules/RateLimitingConfiguration.js';
12
13
  import { restoreAccessRule } from './rules/index.js';
@@ -388,14 +389,15 @@ let ApiModel = (() => {
388
389
  }
389
390
  const name = domainEntity.info.name || '';
390
391
  const segment = pluralize(name.toLocaleLowerCase());
392
+ const paramName = paramNameFor(name);
391
393
  let relativeCollectionPath = `/${segment}`;
392
- let relativeResourcePath = `/${segment}/{id}`;
394
+ let relativeResourcePath = `/${segment}/{${paramName}}`;
393
395
  // Check for root path collision and resolve by appending a number
394
396
  let counter = 1;
395
397
  const originalCollectionPath = relativeCollectionPath;
396
398
  while (this.findCollectionPathCollision(relativeCollectionPath)) {
397
399
  relativeCollectionPath = `${originalCollectionPath}-${counter}`;
398
- relativeResourcePath = `${relativeCollectionPath}/{id}`;
400
+ relativeResourcePath = `${relativeCollectionPath}/{${paramName}}`;
399
401
  counter++;
400
402
  }
401
403
  const newEntity = {
@@ -471,13 +473,14 @@ let ApiModel = (() => {
471
473
  if (targetDomEntity) {
472
474
  const name = targetDomEntity.info.name || '';
473
475
  const segment = pluralize(name.toLocaleLowerCase());
476
+ const paramName = paramNameFor(name);
474
477
  let relativeCollectionPath = `/${segment}`;
475
- let relativeResourcePath = `/${segment}/{id}`;
478
+ let relativeResourcePath = `/${segment}/{${paramName}}`;
476
479
  let counter = 1;
477
480
  const originalCollectionPath = relativeCollectionPath;
478
481
  while (this.findResourcePathCollision(relativeCollectionPath)) {
479
482
  relativeCollectionPath = `${originalCollectionPath}-${counter}`;
480
- relativeResourcePath = `${relativeCollectionPath}/{id}`;
483
+ relativeResourcePath = `${relativeCollectionPath}/{${paramName}}`;
481
484
  counter++;
482
485
  }
483
486
  // 2. Update properties to make it root
@@ -498,8 +501,9 @@ let ApiModel = (() => {
498
501
  const name = association.info.name || '';
499
502
  const segment = pluralize(name.toLocaleLowerCase());
500
503
  const isCollection = association.multiple !== false;
504
+ const paramName = paramNameFor(targetDomainEntity.info.name || '');
501
505
  const relativeCollectionPath = isCollection ? `/${segment}` : undefined;
502
- const relativeResourcePath = isCollection ? `/${segment}/{id}` : `/${segment}`;
506
+ const relativeResourcePath = isCollection ? `/${segment}/{${paramName}}` : `/${segment}`;
503
507
  // Create nested exposure
504
508
  const nestedExposure = {
505
509
  kind: ExposedEntityKind,
@@ -1 +1 @@
1
- {"version":3,"file":"ApiModel.js","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { nanoid } from '../nanoid.js'\nimport { ApiModelKind, DataDomainKind, ExposedEntityKind } from '../models/kinds.js'\nimport { type ThingSchema, Thing } from '../models/Thing.js'\nimport type {\n AssociationTarget,\n AuthenticationStrategy,\n AuthorizationStrategy,\n ExposedEntitySchema,\n SessionConfiguration,\n ExposeOptions,\n OffsetPaginationStrategy,\n CursorPaginationStrategy,\n} from './types.js'\nimport { DataDomain } from './DataDomain.js'\nimport { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js'\nimport { observed, toRaw } from '../decorators/observed.js'\nimport pluralize from '@jarrodek/pluralize'\nimport { createDomainKey } from './helpers/keying.js'\nimport { ExposedEntity } from './ExposedEntity.js'\nimport { AccessRule, AccessRuleSchema } from './rules/AccessRule.js'\nimport { RateLimitingConfiguration, RateLimitingConfigurationSchema } from './rules/RateLimitingConfiguration.js'\nimport { restoreAccessRule } from './rules/index.js'\nimport { Exception } from '../exceptions/exception.js'\n\n/**\n * Contact information for the exposed API.\n */\nexport interface ApiContact {\n /**\n * The identifying name of the contact person/organization.\n */\n name?: string\n /**\n * The URL pointing to the contact information. MUST be in the format of a URL.\n */\n url?: string\n /**\n * The email address of the contact person/organization. MUST be in the format of an email address.\n */\n email?: string\n}\n\n/**\n * License information for the exposed API.\n */\nexport interface ApiLicense {\n /**\n * The license name used for the API. It is recommended to be an SPDX license identifier.\n */\n name: string\n /**\n * A URL to the license used for the API. MUST be in the format of a URL.\n */\n url?: string\n}\n\nexport interface ApiModelSchema extends DependentModelSchema {\n /**\n * The data domain kind recognizable by the ecosystem.\n */\n kind: typeof ApiModelKind\n /**\n * The unique key of the API model schema.\n * This is a stable identifier that does not change across versions.\n */\n key: string\n /**\n * Contains the name, display name, description, and the version of the API model schema.\n */\n info: ThingSchema\n /**\n * The designated Data Entity that represents a \"User\".\n * This entity should be marked with the \"User\" semantic in the Data Modeler.\n *\n * This property is required to publish the API.\n */\n user?: AssociationTarget\n\n /**\n * Configuration for how users prove their identity.\n * The API model is invalid if this is not set.\n */\n authentication?: AuthenticationStrategy\n\n /**\n * Configuration for what authenticated users are allowed to do.\n * The API model is invalid if this is not set.\n */\n authorization?: AuthorizationStrategy\n\n /**\n * Configuration for the transport and payload of the user session.\n * The API model is invalid if this is not set.\n */\n session?: SessionConfiguration\n /**\n * The specific subset of Data Entities to be exposed by this API.\n * These are the entities that are included in the data domain schema.\n */\n exposes: ExposedEntitySchema[]\n\n /**\n * Optional array of access rules that define the access control policies\n * for the API. These rules are used to enforce security and permissions\n * on the exposed entities.\n *\n * These rules apply to all exposed entities and actions. An API action\n * can declare its own access rules, which will override these.\n */\n accessRule?: AccessRuleSchema[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n rateLimiting?: RateLimitingConfigurationSchema\n /**\n * A URL to the Terms of Service for the API.\n */\n termsOfService?: string\n /**\n * The contact information for the exposed API.\n */\n contact?: ApiContact\n /**\n * The license information for the API.\n */\n license?: ApiLicense\n /**\n * The pagination strategy used by all endpoints in this API. The configuration\n * is shared across all endpoints to ensure consistency and security.\n * This defines how the results are paginated when retrieving a collection of resources.\n */\n pagination: CursorPaginationStrategy | OffsetPaginationStrategy\n}\n\nexport class ApiModel extends DependentModel {\n /**\n * The data domain kind recognizable by the ecosystem.\n */\n kind: typeof ApiModelKind\n /**\n * The unique key of the data domain schema.\n * This is a stable identifier that does not change across versions.\n */\n key: string\n\n /**\n * The description of the domain property.\n */\n info: Thing\n /**\n * The designated Data Entity that represents a \"User\".\n * This entity must be marked with the \"User\" semantic in the Data Modeler.\n *\n * This property is required to publish the API.\n */\n user?: AssociationTarget\n\n /**\n * Configuration for how users prove their identity.\n * The API model is invalid if this is not set.\n */\n authentication?: AuthenticationStrategy\n\n /**\n * Configuration for what authenticated users are allowed to do.\n * The API model is invalid if this is not set.\n */\n authorization?: AuthorizationStrategy\n\n /**\n * Configuration for the transport and payload of the user session.\n * The API model is invalid if this is not set.\n */\n session?: SessionConfiguration\n /**\n * The specific subset of Data Entities to be exposed by this API.\n * These are the entities that are included in the data domain schema.\n *\n * The `key` is the key of the exposed entity. Using a Map to allow for quick lookups.\n */\n @observed() accessor exposes: Map<string, ExposedEntity>\n /**\n * Optional array of access rules that define the access control policies\n * for the API. These rules are used to enforce security and permissions\n * on the exposed entities.\n *\n * These rules apply to all exposed entities and actions. An API action\n * can declare its own access rules, which will override these.\n */\n @observed() accessor accessRule: AccessRule[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n @observed() accessor rateLimiting: RateLimitingConfiguration | undefined\n /**\n * A URL to the Terms of Service for the API.\n */\n @observed() accessor termsOfService: string | undefined\n /**\n * The contact information for the exposed API.\n */\n @observed({ deep: true }) accessor contact: ApiContact | undefined\n /**\n * The license information for the API.\n */\n @observed({ deep: true }) accessor license: ApiLicense | undefined\n /**\n * The pagination strategy used by all endpoints in this API.\n * This defines how the results are paginated when retrieving a collection of resources.\n */\n @observed({ deep: true }) accessor pagination: CursorPaginationStrategy | OffsetPaginationStrategy\n\n /**\n * When the initializing flag is set to true,\n * the domain is not notified of changes.\n */\n #initializing = true\n\n /**\n * When the notifying flag is set to true,\n * the domain is pending a notification.\n * No other notifications will be sent until\n * the current notification is sent.\n */\n #notifying = false\n\n /**\n * A convenience getter that returns the DataDomain associated with this API model.\n * Since the API model can have only one DataDomain,\n * this getter returns the first dependency in the list.\n *\n * The parent interface `DependentModel` allows for multiple dependencies,\n * to unify the dependency management across different models.\n */\n get domain(): DataDomain | undefined {\n if (this.dependencyList.length === 0) {\n return undefined\n }\n const domain = this.dependencyList[0]\n return this.dependencies.get(domain.key)\n }\n\n static createSchema(input: Partial<ApiModelSchema> = {}): ApiModelSchema {\n const { key = nanoid(), exposes = [], pagination } = input\n const info = Thing.fromJSON(input.info, { name: 'Unnamed API' }).toJSON()\n const result: ApiModelSchema = {\n kind: ApiModelKind,\n key,\n info,\n exposes,\n pagination: pagination ? structuredClone(pagination) : { kind: 'cursor' },\n }\n if (input.user) {\n result.user = structuredClone(input.user)\n }\n if (input.dependencyList) {\n result.dependencyList = structuredClone(input.dependencyList)\n }\n if (input.authentication) {\n result.authentication = structuredClone(input.authentication)\n }\n if (input.authorization) {\n result.authorization = structuredClone(input.authorization)\n }\n if (input.session) {\n result.session = structuredClone(input.session)\n }\n if (Array.isArray(input.accessRule)) {\n result.accessRule = structuredClone(input.accessRule)\n }\n if (input.rateLimiting) {\n result.rateLimiting = structuredClone(input.rateLimiting)\n }\n if (input.termsOfService) {\n result.termsOfService = input.termsOfService\n }\n if (input.contact) {\n result.contact = structuredClone(input.contact)\n }\n if (input.license) {\n result.license = structuredClone(input.license)\n }\n return result\n }\n\n constructor(state?: Partial<ApiModelSchema>, domain?: DomainDependency) {\n const init = ApiModel.createSchema(state)\n const instances: DataDomain[] = []\n if (domain instanceof DataDomain) {\n if (domain.readOnly) {\n instances.push(domain)\n } else {\n // eslint-disable-next-line no-console\n console.warn(`Domain ${domain.key} is not read only, cloning it. This may have performance implications.`)\n instances.push(domain.clone({ readOnly: true }))\n }\n } else if (typeof domain === 'object' && domain.kind === DataDomainKind) {\n instances.push(new DataDomain(domain, undefined, { readOnly: true }))\n } else if (domain) {\n throw new Exception(`Invalid domain provided. Expected a DataDomain instance or schema.`, {\n code: 'E_DOMAIN_INVALID',\n help: 'It looks like the provided data domain is not a valid instance or domain schema.',\n })\n }\n // Note that since we're using the `DependentModel` class, but the API Model can have only one dependency,\n // we keep the reference to the data domain under the `dependencyList` property.\n // It is all handled by the parent class `DependentModel`. This way we simplify the dependency management (loading)\n // process when the API model is loaded from the API.\n if (domain) {\n if (!domain.info.version) {\n throw new Exception(`Domain ${domain.key} must have a version.`, {\n code: 'E_DOMAIN_NO_VERSION',\n // eslint-disable-next-line max-len\n help: 'Before attaching the data domain, give it a version name. Only versioned domains can be attached to an API model.',\n })\n }\n init.dependencyList = [{ key: domain.key, version: domain.info.version }]\n }\n super(init.dependencyList, instances)\n this.kind = init.kind\n this.key = init.key\n this.info = new Thing(init.info)\n this.user = init.user\n this.pagination = init.pagination ? structuredClone(init.pagination) : { kind: 'cursor' }\n if (init.authentication) {\n this.authentication = structuredClone(init.authentication)\n }\n if (init.authorization) {\n this.authorization = structuredClone(init.authorization)\n }\n if (init.session) {\n this.session = structuredClone(init.session)\n }\n if (Array.isArray(init.exposes)) {\n this.exposes = new Map(init.exposes.map((e) => [e.key, new ExposedEntity(this, e)]))\n } else {\n this.exposes = new Map()\n }\n if (Array.isArray(init.accessRule)) {\n this.accessRule = init.accessRule.map((rule) => restoreAccessRule(this, rule))\n } else {\n this.accessRule = []\n }\n if (init.rateLimiting) {\n this.rateLimiting = new RateLimitingConfiguration(init.rateLimiting)\n }\n if (init.termsOfService) {\n this.termsOfService = init.termsOfService\n }\n if (init.contact) {\n this.contact = init.contact\n }\n if (init.license) {\n this.license = init.license\n }\n this.#initializing = false\n this.info.addEventListener('change', () => {\n this.notifyChange()\n })\n }\n\n toJSON(): ApiModelSchema {\n const result: ApiModelSchema = {\n kind: this.kind,\n key: this.key,\n info: this.info.toJSON(),\n exposes: Array.from(this.exposes.values()).map((e) => e.toJSON()),\n pagination: structuredClone(toRaw(this, this.pagination)) as CursorPaginationStrategy | OffsetPaginationStrategy,\n }\n if (this.user) {\n result.user = { ...this.user }\n }\n if (this.dependencyList.length > 0) {\n result.dependencyList = structuredClone(this.dependencyList)\n }\n if (this.authentication) {\n result.authentication = structuredClone(this.authentication)\n }\n if (this.authorization) {\n result.authorization = structuredClone(this.authorization)\n }\n if (this.session) {\n result.session = structuredClone(this.session)\n }\n if (Array.isArray(this.accessRule) && this.accessRule.length > 0) {\n result.accessRule = this.accessRule.map((rule) => rule.toJSON())\n }\n if (this.rateLimiting) {\n result.rateLimiting = this.rateLimiting.toJSON()\n }\n if (this.termsOfService) {\n result.termsOfService = this.termsOfService\n }\n if (this.contact) {\n result.contact = structuredClone(toRaw(this, this.contact))\n }\n if (this.license) {\n result.license = structuredClone(toRaw(this, this.license))\n }\n return result\n }\n\n /**\n * This function is used internally by all domain elements to notify that something has changed.\n * Since we want to notify listeners after the operation commits, we use microtask\n * to ensure that the event is dispatched after the current operation.\n */\n notifyChange() {\n if (this.#notifying || this.#initializing) {\n return\n }\n this.#notifying = true\n queueMicrotask(() => {\n this.#notifying = false\n const event = new Event('change')\n this.dispatchEvent(event)\n })\n }\n\n /**\n * Exposes a new entity in the API model.\n * If the entity already exists, it returns the existing one.\n *\n * The logic regarding exposing an entity:\n * - If the entity is already exposed as a root entity, it returns the existing one.\n * - If the entity has an association, we expose that entity as a nested entity (by setting the parent property).\n * - If the associated entity is already exposed as a root entity, we do not follow the association.\n *\n * @param entity The entity key and domain to expose.\n * @returns The exposed entity.\n */\n exposeEntity(entity: AssociationTarget, options?: ExposeOptions): ExposedEntity {\n const domain = this.domain\n if (!domain) {\n throw new Exception(`No domain attached to API model`, {\n code: 'E_NO_DOMAIN',\n help: 'Attach a data domain to the API model before exposing entities.',\n })\n }\n // checks whether the entity is already exposed as a root exposure.\n let existing: ExposedEntity | undefined\n for (const exp of this.exposes.values()) {\n if (exp.isRoot && exp.entity.key === entity.key) {\n existing = exp\n break\n }\n }\n if (existing) {\n throw new Exception(`Entity ${entity.key} is already exposed.`, {\n code: 'E_ENTITY_ALREADY_EXPOSED',\n help: 'Do not try to expose already exposed entity.',\n })\n }\n const domainEntity = domain.findEntity(entity.key, entity.domain)\n if (!domainEntity) {\n throw new Exception(`Entity not found in domain: ${entity.key}`, {\n code: 'E_NO_ENTITY',\n help: 'Make sure the entity you are trying to expose exists in the data domain.',\n })\n }\n const name = domainEntity.info.name || ''\n const segment = pluralize(name.toLocaleLowerCase())\n let relativeCollectionPath = `/${segment}`\n let relativeResourcePath = `/${segment}/{id}`\n\n // Check for root path collision and resolve by appending a number\n let counter = 1\n const originalCollectionPath = relativeCollectionPath\n while (this.findCollectionPathCollision(relativeCollectionPath)) {\n relativeCollectionPath = `${originalCollectionPath}-${counter}`\n relativeResourcePath = `${relativeCollectionPath}/{id}`\n counter++\n }\n\n const newEntity: ExposedEntitySchema = {\n kind: ExposedEntityKind,\n key: nanoid(),\n entity: { ...entity },\n actions: [],\n isRoot: true,\n collectionPath: relativeCollectionPath,\n resourcePath: relativeResourcePath,\n hasCollection: true,\n }\n if (options) {\n newEntity.exposeOptions = { ...options }\n }\n const created = new ExposedEntity(this, newEntity)\n this.exposes.set(created.key, created)\n\n // Follow associations if requested\n if (options?.followAssociations) {\n if (options?.maxDepth === undefined || options.maxDepth > 0) {\n this.followEntityAssociations(newEntity, options)\n }\n }\n this.notifyChange()\n return created\n }\n\n /**\n * Follows associations for a newly exposed entity if configured to do so.\n * This creates nested exposures based on the entity's associations.\n *\n * @param parentExposure The root exposure to follow associations from\n * @param options The expose options containing follow configuration\n */\n private followEntityAssociations(parentExposure: ExposedEntitySchema, options: ExposeOptions): void {\n const domain = this.domain\n if (!domain) {\n throw new Exception(`No domain attached to API model`, {\n code: 'E_NO_DOMAIN',\n })\n }\n const maxDepth = options.maxDepth ?? 6\n const follow = (currentEntity: AssociationTarget, parentKey: string, depth: number, currentPath: string[]) => {\n // Find the domain entity\n const domainEntity = domain.findEntity(currentEntity.key, currentEntity.domain)\n if (!domainEntity) return\n\n // Iterate through associations\n for (const association of domainEntity.listAssociations()) {\n for (const target of association.targets) {\n // Skip self-referencing associations\n if (target.key === currentEntity.key && target.domain === currentEntity.domain) {\n continue\n }\n\n const targetKeys = createDomainKey(target)\n // Circular dependency check: if this entity is already in our *current* traversal path\n if (currentPath.includes(targetKeys)) {\n continue\n }\n\n // Check if this entity is ALREADY exposed anywhere in the model\n let existingExposure: ExposedEntity | undefined\n for (const exp of this.exposes.values()) {\n if (exp.entity.key === target.key) {\n existingExposure = exp\n break\n }\n }\n\n if (existingExposure) {\n // If it's already exposed and NOT root (i.e., it's currently a nested child of someone else),\n // promote it to ROOT to avoid duplicating it or deeply nesting it in multiple places.\n if (!existingExposure.isRoot) {\n // 1. Calculate new root paths (handling collisions)\n const targetDomEntity = domain.findEntity(target.key, target.domain)\n if (targetDomEntity) {\n const name = targetDomEntity.info.name || ''\n const segment = pluralize(name.toLocaleLowerCase())\n let relativeCollectionPath = `/${segment}`\n let relativeResourcePath = `/${segment}/{id}`\n\n let counter = 1\n const originalCollectionPath = relativeCollectionPath\n while (this.findResourcePathCollision(relativeCollectionPath)) {\n relativeCollectionPath = `${originalCollectionPath}-${counter}`\n relativeResourcePath = `${relativeCollectionPath}/{id}`\n counter++\n }\n\n // 2. Update properties to make it root\n existingExposure.isRoot = true\n existingExposure.parent = undefined\n existingExposure.collectionPath = relativeCollectionPath\n existingExposure.resourcePath = relativeResourcePath\n existingExposure.hasCollection = true\n }\n }\n // Whether it was already root or we just promoted it, we stop following here.\n continue\n }\n\n // Find the target domain entity for path generation\n const targetDomainEntity = domain.findEntity(target.key, target.domain)\n if (!targetDomainEntity) continue\n\n const name = association.info.name || ''\n const segment = pluralize(name.toLocaleLowerCase())\n const isCollection = association.multiple !== false\n const relativeCollectionPath = isCollection ? `/${segment}` : undefined\n const relativeResourcePath = isCollection ? `/${segment}/{id}` : `/${segment}`\n // Create nested exposure\n const nestedExposure: ExposedEntitySchema = {\n kind: ExposedEntityKind,\n key: nanoid(),\n entity: { ...target },\n actions: [],\n isRoot: false,\n collectionPath: relativeCollectionPath,\n resourcePath: relativeResourcePath,\n hasCollection: isCollection,\n parent: {\n key: parentKey,\n association: {\n key: association.key,\n domain: currentEntity.domain,\n },\n depth: depth + 1,\n },\n }\n\n const inst = new ExposedEntity(this, nestedExposure)\n this.exposes.set(inst.key, inst)\n if (depth + 1 >= maxDepth) {\n nestedExposure.truncated = true\n } else {\n // Recursively follow associations\n follow(target, nestedExposure.key, depth + 1, [...currentPath, targetKeys])\n }\n }\n }\n }\n\n // Start following from the root exposure\n // Initial path contains the root entity itself\n const rootKey = createDomainKey(parentExposure.entity)\n follow(parentExposure.entity, parentExposure.key, 0, [rootKey])\n }\n\n /**\n * Removes an exposed entity from the API model.\n * This also removes any nested exposed entities that are children of the removed entity.\n *\n * @param key The key of the exposed entity to remove.\n */\n removeExposedEntity(key: string): void {\n if (!this.exposes.has(key)) {\n throw new Exception(`Exposed entity with key \"${key}\" not found.`, {\n code: 'E_NO_EXPOSURE',\n help: 'The exposed entity you are trying to remove does not exist.',\n })\n }\n this.removeWithChildren(key)\n }\n\n private removeWithChildren(key: string): void {\n if (!this.exposes.has(key)) {\n return\n }\n // Remove the parent itself\n this.exposes.delete(key)\n // Remove all children recursively\n const removeChildren = (parentKey: string) => {\n // Find all exposures whose parent.key matches parentKey\n for (const child of this.exposes.values()) {\n if (child.parent?.key === parentKey) {\n removeChildren(child.key)\n this.exposes.delete(child.key)\n }\n }\n }\n // Then also remove children\n removeChildren(key)\n this.notifyChange()\n }\n\n /**\n * Clears the API model for a new data domain change.\n * This method resets the dependencies, exposes, user,\n * authentication, authorization, and session properties.\n */\n cleanForDomainChange(): void {\n this.dependencies.clear()\n this.dependencyList = []\n this.exposes = new Map()\n this.user = undefined\n if (this.session) {\n this.session.properties = []\n }\n }\n\n /**\n * Attaches a DataDomain to this API model.\n * This method clears any existing dependencies and sets the new domain.\n *\n * @param domain The DataDomain to attach to this API model.\n * @throws Error if the domain does not have a version set in its info.\n */\n attachDataDomain(domain: DataDomain): void {\n if (!domain.info.version) {\n throw new Exception(`Cannot attach DataDomain without a version. Please set the version in the domain info.`, {\n code: 'E_DOMAIN_NO_VERSION',\n // eslint-disable-next-line max-len\n help: 'Before attaching the data domain, give it a version name. Only versioned domains can be attached to an API model.',\n })\n }\n this.cleanForDomainChange()\n this.dependencies.set(domain.key, domain)\n this.dependencyList = [{ key: domain.key, version: domain.info.version }]\n this.notifyChange()\n }\n\n /**\n * Finds an existing root exposed entity that has the given resource path.\n * Useful for detecting path collisions when adding or updating an exposed entity.\n *\n * @param path The resource path to check for collisions.\n * @param ignore Optional key of an exposed entity to ignore during the check (usually the entity being updated).\n * @returns The colliding `ExposedEntity` if found, otherwise `undefined`.\n */\n findResourcePathCollision(path: string, ignore?: string): ExposedEntity | undefined {\n for (const e of this.exposes.values()) {\n if (ignore && e.key === ignore) {\n continue\n }\n if (e.isRoot && e.resourcePath === path) {\n return e\n }\n }\n return undefined\n }\n\n /**\n * Finds an existing root exposed entity that has the given collection path.\n * Useful for detecting path collisions when adding or updating an exposed entity.\n *\n * @param path The collection path to check for collisions.\n * @param ignore Optional key of an exposed entity to ignore during the check (usually the entity being updated).\n * @returns The colliding `ExposedEntity` if found, otherwise `undefined`.\n */\n findCollectionPathCollision(path: string, ignore?: string): ExposedEntity | undefined {\n for (const e of this.exposes.values()) {\n if (ignore && e.key === ignore) {\n continue\n }\n if (e.isRoot && e.hasCollection && e.collectionPath === path) {\n return e\n }\n }\n return undefined\n }\n}\n"]}
1
+ {"version":3,"file":"ApiModel.js","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { nanoid } from '../nanoid.js'\nimport { ApiModelKind, DataDomainKind, ExposedEntityKind } from '../models/kinds.js'\nimport { type ThingSchema, Thing } from '../models/Thing.js'\nimport type {\n AssociationTarget,\n AuthenticationStrategy,\n AuthorizationStrategy,\n ExposedEntitySchema,\n SessionConfiguration,\n ExposeOptions,\n OffsetPaginationStrategy,\n CursorPaginationStrategy,\n} from './types.js'\nimport { DataDomain } from './DataDomain.js'\nimport { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js'\nimport { observed, toRaw } from '../decorators/observed.js'\nimport pluralize from '@jarrodek/pluralize'\nimport { createDomainKey } from './helpers/keying.js'\nimport { paramNameFor } from './helpers/endpointHelpers.js'\nimport { ExposedEntity } from './ExposedEntity.js'\nimport { AccessRule, AccessRuleSchema } from './rules/AccessRule.js'\nimport { RateLimitingConfiguration, RateLimitingConfigurationSchema } from './rules/RateLimitingConfiguration.js'\nimport { restoreAccessRule } from './rules/index.js'\nimport { Exception } from '../exceptions/exception.js'\n\n/**\n * Contact information for the exposed API.\n */\nexport interface ApiContact {\n /**\n * The identifying name of the contact person/organization.\n */\n name?: string\n /**\n * The URL pointing to the contact information. MUST be in the format of a URL.\n */\n url?: string\n /**\n * The email address of the contact person/organization. MUST be in the format of an email address.\n */\n email?: string\n}\n\n/**\n * License information for the exposed API.\n */\nexport interface ApiLicense {\n /**\n * The license name used for the API. It is recommended to be an SPDX license identifier.\n */\n name: string\n /**\n * A URL to the license used for the API. MUST be in the format of a URL.\n */\n url?: string\n}\n\nexport interface ApiModelSchema extends DependentModelSchema {\n /**\n * The data domain kind recognizable by the ecosystem.\n */\n kind: typeof ApiModelKind\n /**\n * The unique key of the API model schema.\n * This is a stable identifier that does not change across versions.\n */\n key: string\n /**\n * Contains the name, display name, description, and the version of the API model schema.\n */\n info: ThingSchema\n /**\n * The designated Data Entity that represents a \"User\".\n * This entity should be marked with the \"User\" semantic in the Data Modeler.\n *\n * This property is required to publish the API.\n */\n user?: AssociationTarget\n\n /**\n * Configuration for how users prove their identity.\n * The API model is invalid if this is not set.\n */\n authentication?: AuthenticationStrategy\n\n /**\n * Configuration for what authenticated users are allowed to do.\n * The API model is invalid if this is not set.\n */\n authorization?: AuthorizationStrategy\n\n /**\n * Configuration for the transport and payload of the user session.\n * The API model is invalid if this is not set.\n */\n session?: SessionConfiguration\n /**\n * The specific subset of Data Entities to be exposed by this API.\n * These are the entities that are included in the data domain schema.\n */\n exposes: ExposedEntitySchema[]\n\n /**\n * Optional array of access rules that define the access control policies\n * for the API. These rules are used to enforce security and permissions\n * on the exposed entities.\n *\n * These rules apply to all exposed entities and actions. An API action\n * can declare its own access rules, which will override these.\n */\n accessRule?: AccessRuleSchema[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n rateLimiting?: RateLimitingConfigurationSchema\n /**\n * A URL to the Terms of Service for the API.\n */\n termsOfService?: string\n /**\n * The contact information for the exposed API.\n */\n contact?: ApiContact\n /**\n * The license information for the API.\n */\n license?: ApiLicense\n /**\n * The pagination strategy used by all endpoints in this API. The configuration\n * is shared across all endpoints to ensure consistency and security.\n * This defines how the results are paginated when retrieving a collection of resources.\n */\n pagination: CursorPaginationStrategy | OffsetPaginationStrategy\n}\n\nexport class ApiModel extends DependentModel {\n /**\n * The data domain kind recognizable by the ecosystem.\n */\n kind: typeof ApiModelKind\n /**\n * The unique key of the data domain schema.\n * This is a stable identifier that does not change across versions.\n */\n key: string\n\n /**\n * The description of the domain property.\n */\n info: Thing\n /**\n * The designated Data Entity that represents a \"User\".\n * This entity must be marked with the \"User\" semantic in the Data Modeler.\n *\n * This property is required to publish the API.\n */\n user?: AssociationTarget\n\n /**\n * Configuration for how users prove their identity.\n * The API model is invalid if this is not set.\n */\n authentication?: AuthenticationStrategy\n\n /**\n * Configuration for what authenticated users are allowed to do.\n * The API model is invalid if this is not set.\n */\n authorization?: AuthorizationStrategy\n\n /**\n * Configuration for the transport and payload of the user session.\n * The API model is invalid if this is not set.\n */\n session?: SessionConfiguration\n /**\n * The specific subset of Data Entities to be exposed by this API.\n * These are the entities that are included in the data domain schema.\n *\n * The `key` is the key of the exposed entity. Using a Map to allow for quick lookups.\n */\n @observed() accessor exposes: Map<string, ExposedEntity>\n /**\n * Optional array of access rules that define the access control policies\n * for the API. These rules are used to enforce security and permissions\n * on the exposed entities.\n *\n * These rules apply to all exposed entities and actions. An API action\n * can declare its own access rules, which will override these.\n */\n @observed() accessor accessRule: AccessRule[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n @observed() accessor rateLimiting: RateLimitingConfiguration | undefined\n /**\n * A URL to the Terms of Service for the API.\n */\n @observed() accessor termsOfService: string | undefined\n /**\n * The contact information for the exposed API.\n */\n @observed({ deep: true }) accessor contact: ApiContact | undefined\n /**\n * The license information for the API.\n */\n @observed({ deep: true }) accessor license: ApiLicense | undefined\n /**\n * The pagination strategy used by all endpoints in this API.\n * This defines how the results are paginated when retrieving a collection of resources.\n */\n @observed({ deep: true }) accessor pagination: CursorPaginationStrategy | OffsetPaginationStrategy\n\n /**\n * When the initializing flag is set to true,\n * the domain is not notified of changes.\n */\n #initializing = true\n\n /**\n * When the notifying flag is set to true,\n * the domain is pending a notification.\n * No other notifications will be sent until\n * the current notification is sent.\n */\n #notifying = false\n\n /**\n * A convenience getter that returns the DataDomain associated with this API model.\n * Since the API model can have only one DataDomain,\n * this getter returns the first dependency in the list.\n *\n * The parent interface `DependentModel` allows for multiple dependencies,\n * to unify the dependency management across different models.\n */\n get domain(): DataDomain | undefined {\n if (this.dependencyList.length === 0) {\n return undefined\n }\n const domain = this.dependencyList[0]\n return this.dependencies.get(domain.key)\n }\n\n static createSchema(input: Partial<ApiModelSchema> = {}): ApiModelSchema {\n const { key = nanoid(), exposes = [], pagination } = input\n const info = Thing.fromJSON(input.info, { name: 'Unnamed API' }).toJSON()\n const result: ApiModelSchema = {\n kind: ApiModelKind,\n key,\n info,\n exposes,\n pagination: pagination ? structuredClone(pagination) : { kind: 'cursor' },\n }\n if (input.user) {\n result.user = structuredClone(input.user)\n }\n if (input.dependencyList) {\n result.dependencyList = structuredClone(input.dependencyList)\n }\n if (input.authentication) {\n result.authentication = structuredClone(input.authentication)\n }\n if (input.authorization) {\n result.authorization = structuredClone(input.authorization)\n }\n if (input.session) {\n result.session = structuredClone(input.session)\n }\n if (Array.isArray(input.accessRule)) {\n result.accessRule = structuredClone(input.accessRule)\n }\n if (input.rateLimiting) {\n result.rateLimiting = structuredClone(input.rateLimiting)\n }\n if (input.termsOfService) {\n result.termsOfService = input.termsOfService\n }\n if (input.contact) {\n result.contact = structuredClone(input.contact)\n }\n if (input.license) {\n result.license = structuredClone(input.license)\n }\n return result\n }\n\n constructor(state?: Partial<ApiModelSchema>, domain?: DomainDependency) {\n const init = ApiModel.createSchema(state)\n const instances: DataDomain[] = []\n if (domain instanceof DataDomain) {\n if (domain.readOnly) {\n instances.push(domain)\n } else {\n // eslint-disable-next-line no-console\n console.warn(`Domain ${domain.key} is not read only, cloning it. This may have performance implications.`)\n instances.push(domain.clone({ readOnly: true }))\n }\n } else if (typeof domain === 'object' && domain.kind === DataDomainKind) {\n instances.push(new DataDomain(domain, undefined, { readOnly: true }))\n } else if (domain) {\n throw new Exception(`Invalid domain provided. Expected a DataDomain instance or schema.`, {\n code: 'E_DOMAIN_INVALID',\n help: 'It looks like the provided data domain is not a valid instance or domain schema.',\n })\n }\n // Note that since we're using the `DependentModel` class, but the API Model can have only one dependency,\n // we keep the reference to the data domain under the `dependencyList` property.\n // It is all handled by the parent class `DependentModel`. This way we simplify the dependency management (loading)\n // process when the API model is loaded from the API.\n if (domain) {\n if (!domain.info.version) {\n throw new Exception(`Domain ${domain.key} must have a version.`, {\n code: 'E_DOMAIN_NO_VERSION',\n // eslint-disable-next-line max-len\n help: 'Before attaching the data domain, give it a version name. Only versioned domains can be attached to an API model.',\n })\n }\n init.dependencyList = [{ key: domain.key, version: domain.info.version }]\n }\n super(init.dependencyList, instances)\n this.kind = init.kind\n this.key = init.key\n this.info = new Thing(init.info)\n this.user = init.user\n this.pagination = init.pagination ? structuredClone(init.pagination) : { kind: 'cursor' }\n if (init.authentication) {\n this.authentication = structuredClone(init.authentication)\n }\n if (init.authorization) {\n this.authorization = structuredClone(init.authorization)\n }\n if (init.session) {\n this.session = structuredClone(init.session)\n }\n if (Array.isArray(init.exposes)) {\n this.exposes = new Map(init.exposes.map((e) => [e.key, new ExposedEntity(this, e)]))\n } else {\n this.exposes = new Map()\n }\n if (Array.isArray(init.accessRule)) {\n this.accessRule = init.accessRule.map((rule) => restoreAccessRule(this, rule))\n } else {\n this.accessRule = []\n }\n if (init.rateLimiting) {\n this.rateLimiting = new RateLimitingConfiguration(init.rateLimiting)\n }\n if (init.termsOfService) {\n this.termsOfService = init.termsOfService\n }\n if (init.contact) {\n this.contact = init.contact\n }\n if (init.license) {\n this.license = init.license\n }\n this.#initializing = false\n this.info.addEventListener('change', () => {\n this.notifyChange()\n })\n }\n\n toJSON(): ApiModelSchema {\n const result: ApiModelSchema = {\n kind: this.kind,\n key: this.key,\n info: this.info.toJSON(),\n exposes: Array.from(this.exposes.values()).map((e) => e.toJSON()),\n pagination: structuredClone(toRaw(this, this.pagination)) as CursorPaginationStrategy | OffsetPaginationStrategy,\n }\n if (this.user) {\n result.user = { ...this.user }\n }\n if (this.dependencyList.length > 0) {\n result.dependencyList = structuredClone(this.dependencyList)\n }\n if (this.authentication) {\n result.authentication = structuredClone(this.authentication)\n }\n if (this.authorization) {\n result.authorization = structuredClone(this.authorization)\n }\n if (this.session) {\n result.session = structuredClone(this.session)\n }\n if (Array.isArray(this.accessRule) && this.accessRule.length > 0) {\n result.accessRule = this.accessRule.map((rule) => rule.toJSON())\n }\n if (this.rateLimiting) {\n result.rateLimiting = this.rateLimiting.toJSON()\n }\n if (this.termsOfService) {\n result.termsOfService = this.termsOfService\n }\n if (this.contact) {\n result.contact = structuredClone(toRaw(this, this.contact))\n }\n if (this.license) {\n result.license = structuredClone(toRaw(this, this.license))\n }\n return result\n }\n\n /**\n * This function is used internally by all domain elements to notify that something has changed.\n * Since we want to notify listeners after the operation commits, we use microtask\n * to ensure that the event is dispatched after the current operation.\n */\n notifyChange() {\n if (this.#notifying || this.#initializing) {\n return\n }\n this.#notifying = true\n queueMicrotask(() => {\n this.#notifying = false\n const event = new Event('change')\n this.dispatchEvent(event)\n })\n }\n\n /**\n * Exposes a new entity in the API model.\n * If the entity already exists, it returns the existing one.\n *\n * The logic regarding exposing an entity:\n * - If the entity is already exposed as a root entity, it returns the existing one.\n * - If the entity has an association, we expose that entity as a nested entity (by setting the parent property).\n * - If the associated entity is already exposed as a root entity, we do not follow the association.\n *\n * @param entity The entity key and domain to expose.\n * @returns The exposed entity.\n */\n exposeEntity(entity: AssociationTarget, options?: ExposeOptions): ExposedEntity {\n const domain = this.domain\n if (!domain) {\n throw new Exception(`No domain attached to API model`, {\n code: 'E_NO_DOMAIN',\n help: 'Attach a data domain to the API model before exposing entities.',\n })\n }\n // checks whether the entity is already exposed as a root exposure.\n let existing: ExposedEntity | undefined\n for (const exp of this.exposes.values()) {\n if (exp.isRoot && exp.entity.key === entity.key) {\n existing = exp\n break\n }\n }\n if (existing) {\n throw new Exception(`Entity ${entity.key} is already exposed.`, {\n code: 'E_ENTITY_ALREADY_EXPOSED',\n help: 'Do not try to expose already exposed entity.',\n })\n }\n const domainEntity = domain.findEntity(entity.key, entity.domain)\n if (!domainEntity) {\n throw new Exception(`Entity not found in domain: ${entity.key}`, {\n code: 'E_NO_ENTITY',\n help: 'Make sure the entity you are trying to expose exists in the data domain.',\n })\n }\n const name = domainEntity.info.name || ''\n const segment = pluralize(name.toLocaleLowerCase())\n const paramName = paramNameFor(name)\n let relativeCollectionPath = `/${segment}`\n let relativeResourcePath = `/${segment}/{${paramName}}`\n\n // Check for root path collision and resolve by appending a number\n let counter = 1\n const originalCollectionPath = relativeCollectionPath\n while (this.findCollectionPathCollision(relativeCollectionPath)) {\n relativeCollectionPath = `${originalCollectionPath}-${counter}`\n relativeResourcePath = `${relativeCollectionPath}/{${paramName}}`\n counter++\n }\n\n const newEntity: ExposedEntitySchema = {\n kind: ExposedEntityKind,\n key: nanoid(),\n entity: { ...entity },\n actions: [],\n isRoot: true,\n collectionPath: relativeCollectionPath,\n resourcePath: relativeResourcePath,\n hasCollection: true,\n }\n if (options) {\n newEntity.exposeOptions = { ...options }\n }\n const created = new ExposedEntity(this, newEntity)\n this.exposes.set(created.key, created)\n\n // Follow associations if requested\n if (options?.followAssociations) {\n if (options?.maxDepth === undefined || options.maxDepth > 0) {\n this.followEntityAssociations(newEntity, options)\n }\n }\n this.notifyChange()\n return created\n }\n\n /**\n * Follows associations for a newly exposed entity if configured to do so.\n * This creates nested exposures based on the entity's associations.\n *\n * @param parentExposure The root exposure to follow associations from\n * @param options The expose options containing follow configuration\n */\n private followEntityAssociations(parentExposure: ExposedEntitySchema, options: ExposeOptions): void {\n const domain = this.domain\n if (!domain) {\n throw new Exception(`No domain attached to API model`, {\n code: 'E_NO_DOMAIN',\n })\n }\n const maxDepth = options.maxDepth ?? 6\n const follow = (currentEntity: AssociationTarget, parentKey: string, depth: number, currentPath: string[]) => {\n // Find the domain entity\n const domainEntity = domain.findEntity(currentEntity.key, currentEntity.domain)\n if (!domainEntity) return\n\n // Iterate through associations\n for (const association of domainEntity.listAssociations()) {\n for (const target of association.targets) {\n // Skip self-referencing associations\n if (target.key === currentEntity.key && target.domain === currentEntity.domain) {\n continue\n }\n\n const targetKeys = createDomainKey(target)\n // Circular dependency check: if this entity is already in our *current* traversal path\n if (currentPath.includes(targetKeys)) {\n continue\n }\n\n // Check if this entity is ALREADY exposed anywhere in the model\n let existingExposure: ExposedEntity | undefined\n for (const exp of this.exposes.values()) {\n if (exp.entity.key === target.key) {\n existingExposure = exp\n break\n }\n }\n\n if (existingExposure) {\n // If it's already exposed and NOT root (i.e., it's currently a nested child of someone else),\n // promote it to ROOT to avoid duplicating it or deeply nesting it in multiple places.\n if (!existingExposure.isRoot) {\n // 1. Calculate new root paths (handling collisions)\n const targetDomEntity = domain.findEntity(target.key, target.domain)\n if (targetDomEntity) {\n const name = targetDomEntity.info.name || ''\n const segment = pluralize(name.toLocaleLowerCase())\n const paramName = paramNameFor(name)\n let relativeCollectionPath = `/${segment}`\n let relativeResourcePath = `/${segment}/{${paramName}}`\n\n let counter = 1\n const originalCollectionPath = relativeCollectionPath\n while (this.findResourcePathCollision(relativeCollectionPath)) {\n relativeCollectionPath = `${originalCollectionPath}-${counter}`\n relativeResourcePath = `${relativeCollectionPath}/{${paramName}}`\n counter++\n }\n\n // 2. Update properties to make it root\n existingExposure.isRoot = true\n existingExposure.parent = undefined\n existingExposure.collectionPath = relativeCollectionPath\n existingExposure.resourcePath = relativeResourcePath\n existingExposure.hasCollection = true\n }\n }\n // Whether it was already root or we just promoted it, we stop following here.\n continue\n }\n\n // Find the target domain entity for path generation\n const targetDomainEntity = domain.findEntity(target.key, target.domain)\n if (!targetDomainEntity) continue\n\n const name = association.info.name || ''\n const segment = pluralize(name.toLocaleLowerCase())\n const isCollection = association.multiple !== false\n const paramName = paramNameFor(targetDomainEntity.info.name || '')\n const relativeCollectionPath = isCollection ? `/${segment}` : undefined\n const relativeResourcePath = isCollection ? `/${segment}/{${paramName}}` : `/${segment}`\n // Create nested exposure\n const nestedExposure: ExposedEntitySchema = {\n kind: ExposedEntityKind,\n key: nanoid(),\n entity: { ...target },\n actions: [],\n isRoot: false,\n collectionPath: relativeCollectionPath,\n resourcePath: relativeResourcePath,\n hasCollection: isCollection,\n parent: {\n key: parentKey,\n association: {\n key: association.key,\n domain: currentEntity.domain,\n },\n depth: depth + 1,\n },\n }\n\n const inst = new ExposedEntity(this, nestedExposure)\n this.exposes.set(inst.key, inst)\n if (depth + 1 >= maxDepth) {\n nestedExposure.truncated = true\n } else {\n // Recursively follow associations\n follow(target, nestedExposure.key, depth + 1, [...currentPath, targetKeys])\n }\n }\n }\n }\n\n // Start following from the root exposure\n // Initial path contains the root entity itself\n const rootKey = createDomainKey(parentExposure.entity)\n follow(parentExposure.entity, parentExposure.key, 0, [rootKey])\n }\n\n /**\n * Removes an exposed entity from the API model.\n * This also removes any nested exposed entities that are children of the removed entity.\n *\n * @param key The key of the exposed entity to remove.\n */\n removeExposedEntity(key: string): void {\n if (!this.exposes.has(key)) {\n throw new Exception(`Exposed entity with key \"${key}\" not found.`, {\n code: 'E_NO_EXPOSURE',\n help: 'The exposed entity you are trying to remove does not exist.',\n })\n }\n this.removeWithChildren(key)\n }\n\n private removeWithChildren(key: string): void {\n if (!this.exposes.has(key)) {\n return\n }\n // Remove the parent itself\n this.exposes.delete(key)\n // Remove all children recursively\n const removeChildren = (parentKey: string) => {\n // Find all exposures whose parent.key matches parentKey\n for (const child of this.exposes.values()) {\n if (child.parent?.key === parentKey) {\n removeChildren(child.key)\n this.exposes.delete(child.key)\n }\n }\n }\n // Then also remove children\n removeChildren(key)\n this.notifyChange()\n }\n\n /**\n * Clears the API model for a new data domain change.\n * This method resets the dependencies, exposes, user,\n * authentication, authorization, and session properties.\n */\n cleanForDomainChange(): void {\n this.dependencies.clear()\n this.dependencyList = []\n this.exposes = new Map()\n this.user = undefined\n if (this.session) {\n this.session.properties = []\n }\n }\n\n /**\n * Attaches a DataDomain to this API model.\n * This method clears any existing dependencies and sets the new domain.\n *\n * @param domain The DataDomain to attach to this API model.\n * @throws Error if the domain does not have a version set in its info.\n */\n attachDataDomain(domain: DataDomain): void {\n if (!domain.info.version) {\n throw new Exception(`Cannot attach DataDomain without a version. Please set the version in the domain info.`, {\n code: 'E_DOMAIN_NO_VERSION',\n // eslint-disable-next-line max-len\n help: 'Before attaching the data domain, give it a version name. Only versioned domains can be attached to an API model.',\n })\n }\n this.cleanForDomainChange()\n this.dependencies.set(domain.key, domain)\n this.dependencyList = [{ key: domain.key, version: domain.info.version }]\n this.notifyChange()\n }\n\n /**\n * Finds an existing root exposed entity that has the given resource path.\n * Useful for detecting path collisions when adding or updating an exposed entity.\n *\n * @param path The resource path to check for collisions.\n * @param ignore Optional key of an exposed entity to ignore during the check (usually the entity being updated).\n * @returns The colliding `ExposedEntity` if found, otherwise `undefined`.\n */\n findResourcePathCollision(path: string, ignore?: string): ExposedEntity | undefined {\n for (const e of this.exposes.values()) {\n if (ignore && e.key === ignore) {\n continue\n }\n if (e.isRoot && e.resourcePath === path) {\n return e\n }\n }\n return undefined\n }\n\n /**\n * Finds an existing root exposed entity that has the given collection path.\n * Useful for detecting path collisions when adding or updating an exposed entity.\n *\n * @param path The collection path to check for collisions.\n * @param ignore Optional key of an exposed entity to ignore during the check (usually the entity being updated).\n * @returns The colliding `ExposedEntity` if found, otherwise `undefined`.\n */\n findCollectionPathCollision(path: string, ignore?: string): ExposedEntity | undefined {\n for (const e of this.exposes.values()) {\n if (ignore && e.key === ignore) {\n continue\n }\n if (e.isRoot && e.hasCollection && e.collectionPath === path) {\n return e\n }\n }\n return undefined\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ExposedEntity.d.ts","sourceRoot":"","sources":["../../../src/modeling/ExposedEntity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAuC,MAAM,oBAAoB,CAAA;AAC1G,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,kBAAkB,CAAA;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAA;AAChF,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAc,SAAQ,WAAW;;IAC5C;;OAEG;IACH,IAAI,EAAE,OAAO,iBAAiB,CAAA;IAE9B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;OAEG;IACS,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAE9C;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAA;IAEtB;;;OAGG;IACS,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAEvD;;;OAGG;IACS,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAEzC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;;OAIG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IAExB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B;;OAEG;IACS,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAA;IAEtC;;OAEG;IACS,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,SAAS,CAAA;IAEzD;;OAEG;IACS,QAAQ,CAAC,YAAY,EAAE,yBAAyB,GAAG,SAAS,CAAA;IAExE;;;;;OAKG;IACuB,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAErF;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAcnB;;OAEG;IACH,GAAG,EAAE,QAAQ,CAAA;IAEb,MAAM,CAAC,YAAY,CAAC,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAAG,mBAAmB;gBAmDtE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAyBjE,YAAY;IAaZ,MAAM,IAAI,mBAAmB;IAoC7B;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM;IA4C9B;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM;IA6E5B;;;;;OAKG;IACH,uBAAuB,IAAI,MAAM;IAcjC;;;;;;OAMG;IACH,yBAAyB,IAAI,MAAM,GAAG,SAAS;IAe/C;;OAEG;IACH,WAAW,IAAI,UAAU,EAAE;IAc3B;;OAEG;IACH,kBAAkB,IAAI,yBAAyB,EAAE;IAgBjD;;;OAGG;IACH,sBAAsB,IAAI,aAAa,EAAE;IAgBzC;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM;IAY1C;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAI7C;;;;;OAKG;IACH,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAYjD;;;;;;;OAOG;IACH,wBAAwB,IAAI,IAAI;CA+BjC"}
1
+ {"version":3,"file":"ExposedEntity.d.ts","sourceRoot":"","sources":["../../../src/modeling/ExposedEntity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAuC,MAAM,oBAAoB,CAAA;AAC1G,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,kBAAkB,CAAA;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAA;AAChF,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAc,SAAQ,WAAW;;IAC5C;;OAEG;IACH,IAAI,EAAE,OAAO,iBAAiB,CAAA;IAE9B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;OAEG;IACS,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAE9C;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAA;IAEtB;;;OAGG;IACS,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAEvD;;;OAGG;IACS,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAEzC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;;OAIG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IAExB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B;;OAEG;IACS,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAA;IAEtC;;OAEG;IACS,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,SAAS,CAAA;IAEzD;;OAEG;IACS,QAAQ,CAAC,YAAY,EAAE,yBAAyB,GAAG,SAAS,CAAA;IAExE;;;;;OAKG;IACuB,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAErF;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAcnB;;OAEG;IACH,GAAG,EAAE,QAAQ,CAAA;IAEb,MAAM,CAAC,YAAY,CAAC,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAAG,mBAAmB;gBAmDtE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAyBjE,YAAY;IAaZ,MAAM,IAAI,mBAAmB;IAoC7B;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM;IA6D9B;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM;IAsH5B;;;;;OAKG;IACH,uBAAuB,IAAI,MAAM;IAcjC;;;;;;OAMG;IACH,yBAAyB,IAAI,MAAM,GAAG,SAAS;IAe/C;;OAEG;IACH,WAAW,IAAI,UAAU,EAAE;IAc3B;;OAEG;IACH,kBAAkB,IAAI,yBAAyB,EAAE;IAgBjD;;;OAGG;IACH,sBAAsB,IAAI,aAAa,EAAE;IAgBzC;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM;IAY1C;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAI7C;;;;;OAKG;IACH,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAYjD;;;;;;;OAOG;IACH,wBAAwB,IAAI,IAAI;CA+BjC"}
@@ -4,7 +4,7 @@ import { Exception } from '../exceptions/exception.js';
4
4
  import { ExposedEntityKind } from '../models/kinds.js';
5
5
  import { nanoid } from '../nanoid.js';
6
6
  import { createActionFromKind, restoreAction } from './actions/index.js';
7
- import { ensureLeadingSlash, joinPaths } from './helpers/endpointHelpers.js';
7
+ import { ensureLeadingSlash, joinPaths, paramNameFor } from './helpers/endpointHelpers.js';
8
8
  import { restoreAccessRule } from './rules/index.js';
9
9
  import { RateLimitingConfiguration } from './rules/RateLimitingConfiguration.js';
10
10
  /**
@@ -312,16 +312,29 @@ let ExposedEntity = (() => {
312
312
  });
313
313
  }
314
314
  }
315
- // Preserve current parameter name if present, otherwise default to {id}
316
- let param = '{id}';
317
- if (this.resourcePath) {
315
+ // Preserve current parameter name if present, otherwise default to semantic param name
316
+ let param = '';
317
+ if (this.resourcePath && this.resourcePath !== '/') {
318
318
  const curSegments = this.resourcePath.split('/').filter(Boolean);
319
319
  const maybeParam = curSegments[1];
320
320
  if (maybeParam && /^\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(maybeParam)) {
321
321
  param = maybeParam;
322
322
  }
323
323
  }
324
+ if (!param) {
325
+ const entityObj = this.api.domain?.findEntity(this.entity.key, this.entity.domain);
326
+ if (!entityObj || !entityObj.info.name) {
327
+ // Never fall back to a default like '{id}' here. Silent param generation failures must throw
328
+ // to prevent runtime/OAS collisions.
329
+ throw new Exception('Cannot generate a semantic parameter name because the associated entity or its name is missing.', {
330
+ code: 'E_ENTITY_NOT_FOUND',
331
+ help: 'Ensure the exposed entity points to a valid domain entity with a defined name.',
332
+ });
333
+ }
334
+ param = `{${paramNameFor(entityObj.info.name)}}`;
335
+ }
324
336
  const nextResource = `${normalizedCollection}/${param}`;
337
+ this.#validateParameterCollisions(nextResource);
325
338
  this.collectionPath = normalizedCollection;
326
339
  this.resourcePath = nextResource;
327
340
  // rely on ApiModel.exposes deep observation to notify on property sets
@@ -374,6 +387,7 @@ let ExposedEntity = (() => {
374
387
  });
375
388
  }
376
389
  if (this.resourcePath !== cleaned) {
390
+ this.#validateParameterCollisions(`/${s1}/${s2}`);
377
391
  this.resourcePath = `/${s1}/${s2}`;
378
392
  }
379
393
  return;
@@ -396,9 +410,46 @@ let ExposedEntity = (() => {
396
410
  }
397
411
  }
398
412
  if (this.resourcePath !== cleaned) {
413
+ this.#validateParameterCollisions(`/${segments[0]}`);
399
414
  this.resourcePath = `/${segments[0]}`;
400
415
  }
401
416
  }
417
+ #checkDuplicatesInPaths(paths) {
418
+ const absolute = paths.join('/');
419
+ const params = [...absolute.matchAll(/\{([^}]+)\}/g)].map((m) => m[1]);
420
+ const seen = new Set();
421
+ for (const p of params) {
422
+ if (seen.has(p)) {
423
+ throw new Exception(`Duplicate path parameter "{${p}}" detected in branch hierarchy.`, {
424
+ code: 'E_PATH_PARAM_COLLISION',
425
+ help: 'Change the parameter name in either this resource or its ancestor to ensure unique parameter names.',
426
+ });
427
+ }
428
+ seen.add(p);
429
+ }
430
+ }
431
+ #validateDescendantCollisions(parentKey, ancestorPaths) {
432
+ for (const exposure of this.api.exposes.values()) {
433
+ if (exposure.parent?.key === parentKey) {
434
+ const currentPaths = [...ancestorPaths, exposure.resourcePath];
435
+ this.#checkDuplicatesInPaths(currentPaths);
436
+ this.#validateDescendantCollisions(exposure.key, currentPaths);
437
+ }
438
+ }
439
+ }
440
+ #validateParameterCollisions(tempResourcePath) {
441
+ const paths = [tempResourcePath];
442
+ let parentKey = this.parent?.key;
443
+ while (parentKey) {
444
+ const parent = this.api.exposes.get(parentKey);
445
+ if (!parent)
446
+ break;
447
+ paths.unshift(parent.resourcePath);
448
+ parentKey = parent.parent?.key;
449
+ }
450
+ this.#checkDuplicatesInPaths(paths);
451
+ this.#validateDescendantCollisions(this.key, paths);
452
+ }
402
453
  /**
403
454
  * Computes the absolute path for this exposure's resource endpoint by
404
455
  * walking up the exposure tree using `parent.key` until reaching a root exposure.
@@ -1 +1 @@
1
- {"version":3,"file":"ExposedEntity.js","sourceRoot":"","sources":["../../../src/modeling/ExposedEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import { observed, toRaw } from '../decorators/observed.js'\nimport { Exception } from '../exceptions/exception.js'\nimport { ExposedEntityKind } from '../models/kinds.js'\nimport { nanoid } from '../nanoid.js'\nimport { Action } from './actions/Action.js'\nimport { ActionKind, type ApiActionSchema, createActionFromKind, restoreAction } from './actions/index.js'\nimport type { ApiModel } from './ApiModel.js'\nimport { ensureLeadingSlash, joinPaths } from './helpers/endpointHelpers.js'\nimport { AccessRule } from './rules/AccessRule.js'\nimport { type RateLimitRule, restoreAccessRule } from './rules/index.js'\nimport { RateLimitingConfiguration } from './rules/RateLimitingConfiguration.js'\nimport type {\n AssociationTarget,\n ExposeOptions,\n ExposeParentRef,\n ExposedEntitySchema,\n PaginationContract,\n} from './types.js'\n\n/**\n * A class that specializes in representing an exposed Data Entity within an API Model.\n *\n * ## Design Note\n * This class enforces strict path constraints (e.g., single-segment collection paths like `/users`,\n * two-segment resource paths like `/users/{id}`).\n * This is an intentional design choice to support a UI paradigm for non-technical users, ensuring that\n * path segments are configured individually at each level of the exposure hierarchy.\n *\n * Flexibility is achieved by chaining exposed entities (parent/child relationships), where the final\n * absolute path is composed of all ancestral paths. See `getAbsoluteResourcePath()` and `getAbsoluteCollectionPath()`.\n *\n * @fires change - Emitted when the exposed entity has changed.\n */\nexport class ExposedEntity extends EventTarget {\n /**\n * The exposed entity kind recognizable by the ecosystem.\n */\n kind: typeof ExposedEntityKind\n\n /**\n * The unique key of the exposed entity.\n * This is a stable identifier that does not change across versions.\n */\n key: string\n\n /**\n * A pointer to a Data Entity from the Data Domain.\n */\n @observed() accessor entity: AssociationTarget\n\n /**\n * Indicates whether this exposure has a collection endpoint.\n * A collection endpoint is optional for nested exposures where the association is 1:1\n * and the schema is embedded directly under the parent resource.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n hasCollection: boolean\n\n /**\n * Path to the collection endpoint for this exposure.\n * Starts with '/'. Not set for 1:1 nested exposures where collection does not exist.\n */\n @observed() accessor collectionPath: string | undefined\n\n /**\n * Path to the resource endpoint for this exposure.\n * Starts with '/'. For 1:1 nested exposures the resource path typically does not include an id segment.\n */\n @observed() accessor resourcePath: string\n\n /**\n * Whether this exposure is a root exposure (top-level collection).\n * If this is set then the `parent` reference must be populated.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n isRoot?: boolean\n\n /**\n * Parent reference when this exposure was created via following an association.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n parent?: ExposeParentRef\n\n /**\n * Expose-time config used to create this exposure (persisted for auditing/UI).\n * This is only populated for the root exposure. All children exposures inherit this config.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n exposeOptions?: ExposeOptions\n\n /**\n * The list of enabled API actions for this exposure (List/Read/Create/etc.)\n */\n @observed() accessor actions: Action[]\n\n /**\n * Optional array of access rules that define the access control policies for this exposure.\n */\n @observed() accessor accessRule: AccessRule[] | undefined\n\n /**\n * Optional configuration for rate limiting for this exposure.\n */\n @observed() accessor rateLimiting: RateLimitingConfiguration | undefined\n\n /**\n * Pagination contract for this exposure.\n * Defines a list of fields that can be used for filtering, sorting, and searching.\n * The pagination contract is only valid for that specific exposure. It cannot be inherited\n * by other exposures.\n */\n @observed({ deep: true }) accessor paginationContract: PaginationContract | undefined\n\n /**\n * When true, generation for this exposure hit configured limits\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n truncated?: boolean\n\n /**\n * When the notifying flag is set to true,\n * the domain is pending a notification.\n * No other notifications will be sent until\n * the current notification is sent.\n */\n #notifying = false\n /**\n * When the initializing flag is set to true,\n * the domain is not notified of changes.\n */\n #initializing = true\n /**\n * A reference to the parent API Model instance.\n */\n api: ApiModel\n\n static createSchema(input: Partial<ExposedEntitySchema> = {}): ExposedEntitySchema {\n const {\n key = nanoid(),\n entity = { key: '' },\n collectionPath,\n resourcePath = '/',\n hasCollection = true,\n isRoot,\n parent,\n exposeOptions,\n actions = [],\n accessRule,\n rateLimiting,\n truncated,\n paginationContract,\n } = input\n const result: ExposedEntitySchema = {\n kind: ExposedEntityKind,\n key,\n entity: { ...entity },\n hasCollection,\n resourcePath,\n actions: actions.map((a) => ({ ...a })),\n }\n if (collectionPath !== undefined) {\n result.collectionPath = collectionPath\n }\n if (isRoot !== undefined) {\n result.isRoot = isRoot\n }\n if (parent !== undefined) {\n result.parent = { ...parent }\n }\n if (exposeOptions !== undefined) {\n result.exposeOptions = { ...exposeOptions }\n }\n if (Array.isArray(accessRule)) {\n result.accessRule = accessRule.map((ar) => ({ ...ar }))\n }\n if (rateLimiting !== undefined) {\n result.rateLimiting = { ...rateLimiting }\n }\n if (truncated !== undefined) {\n result.truncated = truncated\n }\n if (paginationContract !== undefined) {\n result.paginationContract = structuredClone(paginationContract)\n }\n return result\n }\n\n constructor(model: ApiModel, state?: Partial<ExposedEntitySchema>) {\n super()\n this.api = model\n const init = ExposedEntity.createSchema(state)\n this.kind = init.kind\n this.key = init.key\n this.entity = init.entity\n this.hasCollection = init.hasCollection\n this.collectionPath = init.collectionPath\n this.resourcePath = init.resourcePath\n this.isRoot = init.isRoot\n this.parent = init.parent\n this.exposeOptions = init.exposeOptions\n this.actions = init.actions ? init.actions.map((a) => restoreAction(this, a)) : []\n this.accessRule = init.accessRule ? init.accessRule.map((ar) => restoreAccessRule(this, ar)) : []\n if (init.rateLimiting) {\n this.rateLimiting = new RateLimitingConfiguration(init.rateLimiting)\n }\n this.truncated = init.truncated\n if (init.paginationContract) {\n this.paginationContract = structuredClone(init.paginationContract)\n }\n this.#initializing = false\n }\n\n notifyChange() {\n if (this.#notifying || this.#initializing) {\n return\n }\n this.#notifying = true\n queueMicrotask(() => {\n this.#notifying = false\n const event = new Event('change')\n this.dispatchEvent(event)\n this.api.notifyChange()\n })\n }\n\n toJSON(): ExposedEntitySchema {\n const result: ExposedEntitySchema = {\n kind: this.kind,\n key: this.key,\n entity: { ...this.entity },\n resourcePath: this.resourcePath,\n actions: this.actions.map((a) => a.toJSON()),\n hasCollection: this.hasCollection,\n }\n if (this.collectionPath !== undefined) {\n result.collectionPath = this.collectionPath\n }\n if (this.isRoot !== undefined) {\n result.isRoot = this.isRoot\n }\n if (this.parent !== undefined) {\n result.parent = { ...this.parent }\n }\n if (this.exposeOptions !== undefined) {\n result.exposeOptions = { ...this.exposeOptions }\n }\n if (Array.isArray(this.accessRule) && this.accessRule.length > 0) {\n result.accessRule = this.accessRule.map((ar) => ar.toJSON())\n }\n if (this.rateLimiting !== undefined) {\n result.rateLimiting = this.rateLimiting.toJSON()\n }\n if (this.truncated !== undefined) {\n result.truncated = this.truncated\n }\n if (this.paginationContract) {\n result.paginationContract = structuredClone(toRaw(this, this.paginationContract))\n }\n return result\n }\n\n /**\n * Sets a new collection path for this exposed entity.\n *\n * It:\n * - updates the collectionPath property\n * - updates the absoluteCollectionPath property accordingly\n * - updates the resourcePath accordingly.\n * @param path The new path to set.\n */\n setCollectionPath(path: string) {\n if (!this.hasCollection) {\n throw new Exception(`Cannot set collection path on an exposure that does not have a collection`, {\n code: 'E_PATH_MISSING',\n help: 'The exposed entity you are trying to set a collection path for does not have a collection.',\n })\n }\n const cleaned = ensureLeadingSlash(path)\n // Ensure exactly one non-empty segment\n const segments = cleaned.split('/').filter(Boolean)\n if (segments.length !== 1) {\n throw new Exception(`Collection path must contain exactly one segment. Received: \"${path}\"`, {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set path must have a single path segment (e.g., `/products`)',\n })\n }\n const normalizedCollection = `/${segments[0]}`\n\n // Check for collision if this is a root entity\n if (this.isRoot) {\n const collision = this.api.findCollectionPathCollision(normalizedCollection, this.key)\n if (collision) {\n throw new Exception(`Collection path \"${normalizedCollection}\" is already in use by another root entity.`, {\n code: 'E_PATH_INUSE',\n help: 'The set path is already in use by another root entity.',\n })\n }\n }\n\n // Preserve current parameter name if present, otherwise default to {id}\n let param = '{id}'\n if (this.resourcePath) {\n const curSegments = this.resourcePath.split('/').filter(Boolean)\n const maybeParam = curSegments[1]\n if (maybeParam && /^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(maybeParam)) {\n param = maybeParam\n }\n }\n const nextResource = `${normalizedCollection}/${param}`\n this.collectionPath = normalizedCollection\n this.resourcePath = nextResource\n // rely on ApiModel.exposes deep observation to notify on property sets\n }\n\n /**\n * Sets a new resource path for this exposed entity.\n *\n * Rules:\n * - Must start with '/'.\n * - If this exposure has a collection, the path must be exactly the collection path plus a single\n * parameter segment (e.g. `/products/{productId}`) and only the parameter name may vary.\n * - If this exposure does NOT have a collection, the path can be any two segments (e.g. `/profile/{id}` or `/a/b`).\n */\n setResourcePath(path: string) {\n const cleaned = ensureLeadingSlash(path)\n const segments = cleaned.split('/').filter(Boolean)\n\n if (this.hasCollection) {\n if (!this.collectionPath) {\n // Why do we throw this error? We should just create it from the resource path...\n throw new Exception('Cannot set resource path: missing collection path for this exposure', {\n code: 'E_PATH_MISSING',\n help: 'Set the collection path on the exposed entity first.',\n })\n }\n const colSegments = this.collectionPath.split('/').filter(Boolean)\n if (colSegments.length !== 1) {\n throw new Exception(`Invalid stored collection path \"${this.collectionPath}\"`, {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set collection path must have a single path segment (e.g., `/products`)',\n })\n }\n if (segments.length !== 2) {\n throw new Exception(\n `Resource path must be exactly two segments (collection + parameter). Received: \"${cleaned}\"`,\n {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set resource path must have exactly two segments (collection + parameter).',\n }\n )\n }\n const [s1, s2] = segments\n if (s1 !== colSegments[0]) {\n throw new Exception(\n `Resource path must start with the collection segment \"${colSegments[0]}\". Received: \"${s1}\"`,\n {\n code: 'E_PATH_MISMATCH',\n help: 'Set the resource path to the same value as the collection path + the parameter value.',\n }\n )\n }\n // s2 must be a parameter segment {name}\n if (!/^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(s2)) {\n throw new Exception(`The second segment must be a parameter in braces, e.g. {id}. Received: \"${s2}\"`, {\n code: 'E_PARAMETER_INVALID',\n help: 'Use the braces to surround the parameter name, e.g., {productId}.',\n })\n }\n if (this.resourcePath !== cleaned) {\n this.resourcePath = `/${s1}/${s2}`\n }\n return\n }\n\n // No collection: allow exactly one segment\n if (segments.length !== 1) {\n throw new Exception(\n `Resource path must contain exactly one segment when no collection is present. Received: \"${cleaned}\"`,\n {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set resource path must have exactly one segment.',\n }\n )\n }\n // Check for collision if this is a root entity (singleton case)\n if (this.isRoot) {\n const collision = this.api.findResourcePathCollision(cleaned, this.key)\n if (collision) {\n throw new Exception(`Resource path \"${cleaned}\" is already in use by another root entity.`, {\n code: 'E_PATH_INUSE',\n help: 'The set path is already in use by another root entity.',\n })\n }\n }\n\n if (this.resourcePath !== cleaned) {\n this.resourcePath = `/${segments[0]}`\n }\n }\n\n /**\n * Computes the absolute path for this exposure's resource endpoint by\n * walking up the exposure tree using `parent.key` until reaching a root exposure.\n * The absolute path is composed by concatenating each ancestor's resource path\n * with this exposure's resource path.\n */\n getAbsoluteResourcePath(): string {\n let absolute = ensureLeadingSlash(this.resourcePath)\n // Traverse parents, always joining with the parent's resource path\n let parentKey = this.parent?.key\n while (parentKey) {\n const parent = this.api.exposes.get(parentKey)\n if (!parent) break\n const parentResource = ensureLeadingSlash(parent.resourcePath)\n absolute = joinPaths(parentResource, absolute)\n parentKey = parent.parent?.key\n }\n return absolute\n }\n\n /**\n * Computes the absolute path for this exposure's collection endpoint (if any)\n * by walking up the exposure tree using `parent.key` until reaching a root exposure.\n * The absolute path is composed by concatenating each ancestor's resource path\n * with this exposure's collection path.\n * Returns undefined if this exposure has no collection.\n */\n getAbsoluteCollectionPath(): string | undefined {\n if (!this.hasCollection || !this.collectionPath) return undefined\n let absolute = ensureLeadingSlash(this.collectionPath)\n // Traverse parents, always joining with the parent's resource path\n let parentKey = this.parent?.key\n while (parentKey) {\n const parent = this.api.exposes.get(parentKey)\n if (!parent) break\n const parentResource = ensureLeadingSlash(parent.resourcePath)\n absolute = joinPaths(parentResource, absolute)\n parentKey = parent.parent?.key\n }\n return absolute\n }\n\n /**\n * Returns all access rules for this exposure, including the ones from all the parents up to the API.\n */\n getAllRules(): AccessRule[] {\n const rules: AccessRule[] = []\n this.api.accessRule.forEach((rule) => rules.push(rule))\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: ExposedEntity | undefined = this\n while (current) {\n if (current.accessRule) {\n rules.push(...current.accessRule)\n }\n current = current.parent ? this.api.exposes.get(current.parent.key) : undefined\n }\n return rules\n }\n\n /**\n * Returns all rate limiters for this exposure, including the ones from all the parents up to the API.\n */\n getAllRateLimiters(): RateLimitingConfiguration[] {\n const rateLimiters: RateLimitingConfiguration[] = []\n if (this.api.rateLimiting) {\n rateLimiters.push(this.api.rateLimiting)\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: ExposedEntity | undefined = this\n while (current) {\n if (current.rateLimiting) {\n rateLimiters.push(current.rateLimiting)\n }\n current = current.parent ? this.api.exposes.get(current.parent.key) : undefined\n }\n return rateLimiters\n }\n\n /**\n * Returns all rate limiter rules for this exposure, including the ones from all the parents up to the API.\n * Similar to the getAllRules() method, but it flattens the rate limiters into a single list of rules.\n */\n getAllRateLimiterRules(): RateLimitRule[] {\n const rules: RateLimitRule[] = []\n if (this.api.rateLimiting) {\n rules.push(...this.api.rateLimiting.rules)\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: ExposedEntity | undefined = this\n while (current) {\n if (current.rateLimiting) {\n rules.push(...current.rateLimiting.rules)\n }\n current = current.parent ? this.api.exposes.get(current.parent.key) : undefined\n }\n return rules\n }\n\n /**\n * Adds an action to the exposure.\n * @param schema The schema of the action to add.\n * @returns The added action.\n */\n addAction(schema: ApiActionSchema): Action {\n if (this.actions.some((action) => action.kind === schema.kind)) {\n throw new Exception(`Action of kind \"${schema.kind}\" already exists for this exposure`, {\n code: 'E_ACTION_USED',\n help: \"There's no need to add an API action again.\",\n })\n }\n const action = restoreAction(this, schema)\n this.actions.push(action)\n return action\n }\n\n /**\n * @deprecated Use {@link addActionFromKind()} instead.\n */\n addCrudAction(actionKind: ActionKind): Action {\n return this.addActionFromKind(actionKind)\n }\n\n /**\n * Adds an action of a given kind to the exposure.\n *\n * @param actionKind The kind of the action to add.\n * @returns The added action.\n */\n addActionFromKind(actionKind: ActionKind): Action {\n if (this.actions.some((action) => action.kind === actionKind)) {\n throw new Exception(`Action of kind \"${actionKind}\" already exists for this exposure`, {\n code: 'E_ACTION_USED',\n help: \"There's no need to add an API action again.\",\n })\n }\n const action = createActionFromKind(this, actionKind)\n this.actions.push(action)\n return action\n }\n\n /**\n * Scans for the indexed and search properties in the `DomainEntity`\n * and recreates the `paginationContract` with all indexed/searched fields.\n *\n * Note, this is a destructive action designed as a helper function when creating\n * an exposed entity to fill up default values. Should not be used if the user\n * didn't request that.\n */\n createPaginationContract(): void {\n const entity = this.api.domain?.findEntity(this.entity.key, this.entity.domain)\n if (!entity) {\n throw new Exception(`Entity \"${this.entity.key}\" not found\"`, {\n code: 'E_ENTITY_NOT_FOUND',\n help: 'The set entity does not exist.',\n })\n }\n if (!this.paginationContract) {\n this.paginationContract = {\n filterableFields: [],\n searchableFields: [],\n sortableFields: [],\n }\n } else {\n this.paginationContract.filterableFields = []\n this.paginationContract.searchableFields = []\n this.paginationContract.sortableFields = []\n }\n for (const prop of entity.properties) {\n // indexed properties allow sorting and filtering in the List action.\n if (prop.index) {\n this.paginationContract.filterableFields.push(prop.key)\n this.paginationContract.sortableFields.push(prop.key)\n }\n // search properties allow full-text search in the Search action.\n if (prop.search) {\n this.paginationContract.searchableFields.push(prop.key)\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ExposedEntity.js","sourceRoot":"","sources":["../../../src/modeling/ExposedEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import { observed, toRaw } from '../decorators/observed.js'\nimport { Exception } from '../exceptions/exception.js'\nimport { ExposedEntityKind } from '../models/kinds.js'\nimport { nanoid } from '../nanoid.js'\nimport { Action } from './actions/Action.js'\nimport { ActionKind, type ApiActionSchema, createActionFromKind, restoreAction } from './actions/index.js'\nimport type { ApiModel } from './ApiModel.js'\nimport { ensureLeadingSlash, joinPaths, paramNameFor } from './helpers/endpointHelpers.js'\nimport { AccessRule } from './rules/AccessRule.js'\nimport { type RateLimitRule, restoreAccessRule } from './rules/index.js'\nimport { RateLimitingConfiguration } from './rules/RateLimitingConfiguration.js'\nimport type {\n AssociationTarget,\n ExposeOptions,\n ExposeParentRef,\n ExposedEntitySchema,\n PaginationContract,\n} from './types.js'\n\n/**\n * A class that specializes in representing an exposed Data Entity within an API Model.\n *\n * ## Design Note\n * This class enforces strict path constraints (e.g., single-segment collection paths like `/users`,\n * two-segment resource paths like `/users/{id}`).\n * This is an intentional design choice to support a UI paradigm for non-technical users, ensuring that\n * path segments are configured individually at each level of the exposure hierarchy.\n *\n * Flexibility is achieved by chaining exposed entities (parent/child relationships), where the final\n * absolute path is composed of all ancestral paths. See `getAbsoluteResourcePath()` and `getAbsoluteCollectionPath()`.\n *\n * @fires change - Emitted when the exposed entity has changed.\n */\nexport class ExposedEntity extends EventTarget {\n /**\n * The exposed entity kind recognizable by the ecosystem.\n */\n kind: typeof ExposedEntityKind\n\n /**\n * The unique key of the exposed entity.\n * This is a stable identifier that does not change across versions.\n */\n key: string\n\n /**\n * A pointer to a Data Entity from the Data Domain.\n */\n @observed() accessor entity: AssociationTarget\n\n /**\n * Indicates whether this exposure has a collection endpoint.\n * A collection endpoint is optional for nested exposures where the association is 1:1\n * and the schema is embedded directly under the parent resource.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n hasCollection: boolean\n\n /**\n * Path to the collection endpoint for this exposure.\n * Starts with '/'. Not set for 1:1 nested exposures where collection does not exist.\n */\n @observed() accessor collectionPath: string | undefined\n\n /**\n * Path to the resource endpoint for this exposure.\n * Starts with '/'. For 1:1 nested exposures the resource path typically does not include an id segment.\n */\n @observed() accessor resourcePath: string\n\n /**\n * Whether this exposure is a root exposure (top-level collection).\n * If this is set then the `parent` reference must be populated.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n isRoot?: boolean\n\n /**\n * Parent reference when this exposure was created via following an association.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n parent?: ExposeParentRef\n\n /**\n * Expose-time config used to create this exposure (persisted for auditing/UI).\n * This is only populated for the root exposure. All children exposures inherit this config.\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n exposeOptions?: ExposeOptions\n\n /**\n * The list of enabled API actions for this exposure (List/Read/Create/etc.)\n */\n @observed() accessor actions: Action[]\n\n /**\n * Optional array of access rules that define the access control policies for this exposure.\n */\n @observed() accessor accessRule: AccessRule[] | undefined\n\n /**\n * Optional configuration for rate limiting for this exposure.\n */\n @observed() accessor rateLimiting: RateLimitingConfiguration | undefined\n\n /**\n * Pagination contract for this exposure.\n * Defines a list of fields that can be used for filtering, sorting, and searching.\n * The pagination contract is only valid for that specific exposure. It cannot be inherited\n * by other exposures.\n */\n @observed({ deep: true }) accessor paginationContract: PaginationContract | undefined\n\n /**\n * When true, generation for this exposure hit configured limits\n *\n * Note that this property is not observed for changes as it is immutable after creation.\n */\n truncated?: boolean\n\n /**\n * When the notifying flag is set to true,\n * the domain is pending a notification.\n * No other notifications will be sent until\n * the current notification is sent.\n */\n #notifying = false\n /**\n * When the initializing flag is set to true,\n * the domain is not notified of changes.\n */\n #initializing = true\n /**\n * A reference to the parent API Model instance.\n */\n api: ApiModel\n\n static createSchema(input: Partial<ExposedEntitySchema> = {}): ExposedEntitySchema {\n const {\n key = nanoid(),\n entity = { key: '' },\n collectionPath,\n resourcePath = '/',\n hasCollection = true,\n isRoot,\n parent,\n exposeOptions,\n actions = [],\n accessRule,\n rateLimiting,\n truncated,\n paginationContract,\n } = input\n const result: ExposedEntitySchema = {\n kind: ExposedEntityKind,\n key,\n entity: { ...entity },\n hasCollection,\n resourcePath,\n actions: actions.map((a) => ({ ...a })),\n }\n if (collectionPath !== undefined) {\n result.collectionPath = collectionPath\n }\n if (isRoot !== undefined) {\n result.isRoot = isRoot\n }\n if (parent !== undefined) {\n result.parent = { ...parent }\n }\n if (exposeOptions !== undefined) {\n result.exposeOptions = { ...exposeOptions }\n }\n if (Array.isArray(accessRule)) {\n result.accessRule = accessRule.map((ar) => ({ ...ar }))\n }\n if (rateLimiting !== undefined) {\n result.rateLimiting = { ...rateLimiting }\n }\n if (truncated !== undefined) {\n result.truncated = truncated\n }\n if (paginationContract !== undefined) {\n result.paginationContract = structuredClone(paginationContract)\n }\n return result\n }\n\n constructor(model: ApiModel, state?: Partial<ExposedEntitySchema>) {\n super()\n this.api = model\n const init = ExposedEntity.createSchema(state)\n this.kind = init.kind\n this.key = init.key\n this.entity = init.entity\n this.hasCollection = init.hasCollection\n this.collectionPath = init.collectionPath\n this.resourcePath = init.resourcePath\n this.isRoot = init.isRoot\n this.parent = init.parent\n this.exposeOptions = init.exposeOptions\n this.actions = init.actions ? init.actions.map((a) => restoreAction(this, a)) : []\n this.accessRule = init.accessRule ? init.accessRule.map((ar) => restoreAccessRule(this, ar)) : []\n if (init.rateLimiting) {\n this.rateLimiting = new RateLimitingConfiguration(init.rateLimiting)\n }\n this.truncated = init.truncated\n if (init.paginationContract) {\n this.paginationContract = structuredClone(init.paginationContract)\n }\n this.#initializing = false\n }\n\n notifyChange() {\n if (this.#notifying || this.#initializing) {\n return\n }\n this.#notifying = true\n queueMicrotask(() => {\n this.#notifying = false\n const event = new Event('change')\n this.dispatchEvent(event)\n this.api.notifyChange()\n })\n }\n\n toJSON(): ExposedEntitySchema {\n const result: ExposedEntitySchema = {\n kind: this.kind,\n key: this.key,\n entity: { ...this.entity },\n resourcePath: this.resourcePath,\n actions: this.actions.map((a) => a.toJSON()),\n hasCollection: this.hasCollection,\n }\n if (this.collectionPath !== undefined) {\n result.collectionPath = this.collectionPath\n }\n if (this.isRoot !== undefined) {\n result.isRoot = this.isRoot\n }\n if (this.parent !== undefined) {\n result.parent = { ...this.parent }\n }\n if (this.exposeOptions !== undefined) {\n result.exposeOptions = { ...this.exposeOptions }\n }\n if (Array.isArray(this.accessRule) && this.accessRule.length > 0) {\n result.accessRule = this.accessRule.map((ar) => ar.toJSON())\n }\n if (this.rateLimiting !== undefined) {\n result.rateLimiting = this.rateLimiting.toJSON()\n }\n if (this.truncated !== undefined) {\n result.truncated = this.truncated\n }\n if (this.paginationContract) {\n result.paginationContract = structuredClone(toRaw(this, this.paginationContract))\n }\n return result\n }\n\n /**\n * Sets a new collection path for this exposed entity.\n *\n * It:\n * - updates the collectionPath property\n * - updates the absoluteCollectionPath property accordingly\n * - updates the resourcePath accordingly.\n * @param path The new path to set.\n */\n setCollectionPath(path: string) {\n if (!this.hasCollection) {\n throw new Exception(`Cannot set collection path on an exposure that does not have a collection`, {\n code: 'E_PATH_MISSING',\n help: 'The exposed entity you are trying to set a collection path for does not have a collection.',\n })\n }\n const cleaned = ensureLeadingSlash(path)\n // Ensure exactly one non-empty segment\n const segments = cleaned.split('/').filter(Boolean)\n if (segments.length !== 1) {\n throw new Exception(`Collection path must contain exactly one segment. Received: \"${path}\"`, {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set path must have a single path segment (e.g., `/products`)',\n })\n }\n const normalizedCollection = `/${segments[0]}`\n\n // Check for collision if this is a root entity\n if (this.isRoot) {\n const collision = this.api.findCollectionPathCollision(normalizedCollection, this.key)\n if (collision) {\n throw new Exception(`Collection path \"${normalizedCollection}\" is already in use by another root entity.`, {\n code: 'E_PATH_INUSE',\n help: 'The set path is already in use by another root entity.',\n })\n }\n }\n\n // Preserve current parameter name if present, otherwise default to semantic param name\n let param = ''\n if (this.resourcePath && this.resourcePath !== '/') {\n const curSegments = this.resourcePath.split('/').filter(Boolean)\n const maybeParam = curSegments[1]\n if (maybeParam && /^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(maybeParam)) {\n param = maybeParam\n }\n }\n\n if (!param) {\n const entityObj = this.api.domain?.findEntity(this.entity.key, this.entity.domain)\n if (!entityObj || !entityObj.info.name) {\n // Never fall back to a default like '{id}' here. Silent param generation failures must throw\n // to prevent runtime/OAS collisions.\n throw new Exception(\n 'Cannot generate a semantic parameter name because the associated entity or its name is missing.',\n {\n code: 'E_ENTITY_NOT_FOUND',\n help: 'Ensure the exposed entity points to a valid domain entity with a defined name.',\n }\n )\n }\n param = `{${paramNameFor(entityObj.info.name)}}`\n }\n const nextResource = `${normalizedCollection}/${param}`\n this.#validateParameterCollisions(nextResource)\n this.collectionPath = normalizedCollection\n this.resourcePath = nextResource\n // rely on ApiModel.exposes deep observation to notify on property sets\n }\n\n /**\n * Sets a new resource path for this exposed entity.\n *\n * Rules:\n * - Must start with '/'.\n * - If this exposure has a collection, the path must be exactly the collection path plus a single\n * parameter segment (e.g. `/products/{productId}`) and only the parameter name may vary.\n * - If this exposure does NOT have a collection, the path can be any two segments (e.g. `/profile/{id}` or `/a/b`).\n */\n setResourcePath(path: string) {\n const cleaned = ensureLeadingSlash(path)\n const segments = cleaned.split('/').filter(Boolean)\n\n if (this.hasCollection) {\n if (!this.collectionPath) {\n // Why do we throw this error? We should just create it from the resource path...\n throw new Exception('Cannot set resource path: missing collection path for this exposure', {\n code: 'E_PATH_MISSING',\n help: 'Set the collection path on the exposed entity first.',\n })\n }\n const colSegments = this.collectionPath.split('/').filter(Boolean)\n if (colSegments.length !== 1) {\n throw new Exception(`Invalid stored collection path \"${this.collectionPath}\"`, {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set collection path must have a single path segment (e.g., `/products`)',\n })\n }\n if (segments.length !== 2) {\n throw new Exception(\n `Resource path must be exactly two segments (collection + parameter). Received: \"${cleaned}\"`,\n {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set resource path must have exactly two segments (collection + parameter).',\n }\n )\n }\n const [s1, s2] = segments\n if (s1 !== colSegments[0]) {\n throw new Exception(\n `Resource path must start with the collection segment \"${colSegments[0]}\". Received: \"${s1}\"`,\n {\n code: 'E_PATH_MISMATCH',\n help: 'Set the resource path to the same value as the collection path + the parameter value.',\n }\n )\n }\n // s2 must be a parameter segment {name}\n if (!/^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(s2)) {\n throw new Exception(`The second segment must be a parameter in braces, e.g. {id}. Received: \"${s2}\"`, {\n code: 'E_PARAMETER_INVALID',\n help: 'Use the braces to surround the parameter name, e.g., {productId}.',\n })\n }\n if (this.resourcePath !== cleaned) {\n this.#validateParameterCollisions(`/${s1}/${s2}`)\n this.resourcePath = `/${s1}/${s2}`\n }\n return\n }\n\n // No collection: allow exactly one segment\n if (segments.length !== 1) {\n throw new Exception(\n `Resource path must contain exactly one segment when no collection is present. Received: \"${cleaned}\"`,\n {\n code: 'E_PATH_SEGMENT_SIZE',\n help: 'The set resource path must have exactly one segment.',\n }\n )\n }\n // Check for collision if this is a root entity (singleton case)\n if (this.isRoot) {\n const collision = this.api.findResourcePathCollision(cleaned, this.key)\n if (collision) {\n throw new Exception(`Resource path \"${cleaned}\" is already in use by another root entity.`, {\n code: 'E_PATH_INUSE',\n help: 'The set path is already in use by another root entity.',\n })\n }\n }\n\n if (this.resourcePath !== cleaned) {\n this.#validateParameterCollisions(`/${segments[0]}`)\n this.resourcePath = `/${segments[0]}`\n }\n }\n\n #checkDuplicatesInPaths(paths: string[]) {\n const absolute = paths.join('/')\n const params = [...absolute.matchAll(/\\{([^}]+)\\}/g)].map((m) => m[1])\n const seen = new Set<string>()\n for (const p of params) {\n if (seen.has(p)) {\n throw new Exception(`Duplicate path parameter \"{${p}}\" detected in branch hierarchy.`, {\n code: 'E_PATH_PARAM_COLLISION',\n help: 'Change the parameter name in either this resource or its ancestor to ensure unique parameter names.',\n })\n }\n seen.add(p)\n }\n }\n\n #validateDescendantCollisions(parentKey: string, ancestorPaths: string[]) {\n for (const exposure of this.api.exposes.values()) {\n if (exposure.parent?.key === parentKey) {\n const currentPaths = [...ancestorPaths, exposure.resourcePath]\n this.#checkDuplicatesInPaths(currentPaths)\n this.#validateDescendantCollisions(exposure.key, currentPaths)\n }\n }\n }\n\n #validateParameterCollisions(tempResourcePath: string) {\n const paths: string[] = [tempResourcePath]\n let parentKey = this.parent?.key\n while (parentKey) {\n const parent = this.api.exposes.get(parentKey)\n if (!parent) break\n paths.unshift(parent.resourcePath)\n parentKey = parent.parent?.key\n }\n\n this.#checkDuplicatesInPaths(paths)\n this.#validateDescendantCollisions(this.key, paths)\n }\n\n /**\n * Computes the absolute path for this exposure's resource endpoint by\n * walking up the exposure tree using `parent.key` until reaching a root exposure.\n * The absolute path is composed by concatenating each ancestor's resource path\n * with this exposure's resource path.\n */\n getAbsoluteResourcePath(): string {\n let absolute = ensureLeadingSlash(this.resourcePath)\n // Traverse parents, always joining with the parent's resource path\n let parentKey = this.parent?.key\n while (parentKey) {\n const parent = this.api.exposes.get(parentKey)\n if (!parent) break\n const parentResource = ensureLeadingSlash(parent.resourcePath)\n absolute = joinPaths(parentResource, absolute)\n parentKey = parent.parent?.key\n }\n return absolute\n }\n\n /**\n * Computes the absolute path for this exposure's collection endpoint (if any)\n * by walking up the exposure tree using `parent.key` until reaching a root exposure.\n * The absolute path is composed by concatenating each ancestor's resource path\n * with this exposure's collection path.\n * Returns undefined if this exposure has no collection.\n */\n getAbsoluteCollectionPath(): string | undefined {\n if (!this.hasCollection || !this.collectionPath) return undefined\n let absolute = ensureLeadingSlash(this.collectionPath)\n // Traverse parents, always joining with the parent's resource path\n let parentKey = this.parent?.key\n while (parentKey) {\n const parent = this.api.exposes.get(parentKey)\n if (!parent) break\n const parentResource = ensureLeadingSlash(parent.resourcePath)\n absolute = joinPaths(parentResource, absolute)\n parentKey = parent.parent?.key\n }\n return absolute\n }\n\n /**\n * Returns all access rules for this exposure, including the ones from all the parents up to the API.\n */\n getAllRules(): AccessRule[] {\n const rules: AccessRule[] = []\n this.api.accessRule.forEach((rule) => rules.push(rule))\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: ExposedEntity | undefined = this\n while (current) {\n if (current.accessRule) {\n rules.push(...current.accessRule)\n }\n current = current.parent ? this.api.exposes.get(current.parent.key) : undefined\n }\n return rules\n }\n\n /**\n * Returns all rate limiters for this exposure, including the ones from all the parents up to the API.\n */\n getAllRateLimiters(): RateLimitingConfiguration[] {\n const rateLimiters: RateLimitingConfiguration[] = []\n if (this.api.rateLimiting) {\n rateLimiters.push(this.api.rateLimiting)\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: ExposedEntity | undefined = this\n while (current) {\n if (current.rateLimiting) {\n rateLimiters.push(current.rateLimiting)\n }\n current = current.parent ? this.api.exposes.get(current.parent.key) : undefined\n }\n return rateLimiters\n }\n\n /**\n * Returns all rate limiter rules for this exposure, including the ones from all the parents up to the API.\n * Similar to the getAllRules() method, but it flattens the rate limiters into a single list of rules.\n */\n getAllRateLimiterRules(): RateLimitRule[] {\n const rules: RateLimitRule[] = []\n if (this.api.rateLimiting) {\n rules.push(...this.api.rateLimiting.rules)\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: ExposedEntity | undefined = this\n while (current) {\n if (current.rateLimiting) {\n rules.push(...current.rateLimiting.rules)\n }\n current = current.parent ? this.api.exposes.get(current.parent.key) : undefined\n }\n return rules\n }\n\n /**\n * Adds an action to the exposure.\n * @param schema The schema of the action to add.\n * @returns The added action.\n */\n addAction(schema: ApiActionSchema): Action {\n if (this.actions.some((action) => action.kind === schema.kind)) {\n throw new Exception(`Action of kind \"${schema.kind}\" already exists for this exposure`, {\n code: 'E_ACTION_USED',\n help: \"There's no need to add an API action again.\",\n })\n }\n const action = restoreAction(this, schema)\n this.actions.push(action)\n return action\n }\n\n /**\n * @deprecated Use {@link addActionFromKind()} instead.\n */\n addCrudAction(actionKind: ActionKind): Action {\n return this.addActionFromKind(actionKind)\n }\n\n /**\n * Adds an action of a given kind to the exposure.\n *\n * @param actionKind The kind of the action to add.\n * @returns The added action.\n */\n addActionFromKind(actionKind: ActionKind): Action {\n if (this.actions.some((action) => action.kind === actionKind)) {\n throw new Exception(`Action of kind \"${actionKind}\" already exists for this exposure`, {\n code: 'E_ACTION_USED',\n help: \"There's no need to add an API action again.\",\n })\n }\n const action = createActionFromKind(this, actionKind)\n this.actions.push(action)\n return action\n }\n\n /**\n * Scans for the indexed and search properties in the `DomainEntity`\n * and recreates the `paginationContract` with all indexed/searched fields.\n *\n * Note, this is a destructive action designed as a helper function when creating\n * an exposed entity to fill up default values. Should not be used if the user\n * didn't request that.\n */\n createPaginationContract(): void {\n const entity = this.api.domain?.findEntity(this.entity.key, this.entity.domain)\n if (!entity) {\n throw new Exception(`Entity \"${this.entity.key}\" not found\"`, {\n code: 'E_ENTITY_NOT_FOUND',\n help: 'The set entity does not exist.',\n })\n }\n if (!this.paginationContract) {\n this.paginationContract = {\n filterableFields: [],\n searchableFields: [],\n sortableFields: [],\n }\n } else {\n this.paginationContract.filterableFields = []\n this.paginationContract.searchableFields = []\n this.paginationContract.sortableFields = []\n }\n for (const prop of entity.properties) {\n // indexed properties allow sorting and filtering in the List action.\n if (prop.index) {\n this.paginationContract.filterableFields.push(prop.key)\n this.paginationContract.sortableFields.push(prop.key)\n }\n // search properties allow full-text search in the Search action.\n if (prop.search) {\n this.paginationContract.searchableFields.push(prop.key)\n }\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/RuntimeApiModel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RuntimeApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/RuntimeApiModel.ts"],"names":[],"mappings":"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"}