@api-client/core 0.19.19 → 0.19.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/authorization/Utils.js +3 -3
- package/build/src/authorization/Utils.js.map +1 -1
- package/build/src/modeling/ApiModel.d.ts +16 -5
- package/build/src/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +17 -2
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/ApiValidation.d.ts.map +1 -1
- package/build/src/modeling/ApiValidation.js +2 -1
- package/build/src/modeling/ApiValidation.js.map +1 -1
- package/build/src/modeling/DomainProperty.d.ts +12 -0
- package/build/src/modeling/DomainProperty.d.ts.map +1 -1
- package/build/src/modeling/DomainProperty.js +23 -28
- package/build/src/modeling/DomainProperty.js.map +1 -1
- package/build/src/modeling/DomainSerialization.js +1 -1
- package/build/src/modeling/DomainSerialization.js.map +1 -1
- package/build/src/modeling/ExposedEntity.d.ts +15 -1
- package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
- package/build/src/modeling/ExposedEntity.js +42 -4
- package/build/src/modeling/ExposedEntity.js.map +1 -1
- package/build/src/modeling/actions/Action.d.ts.map +1 -1
- package/build/src/modeling/actions/Action.js +1 -0
- package/build/src/modeling/actions/Action.js.map +1 -1
- package/build/src/modeling/actions/ListAction.d.ts +3 -17
- package/build/src/modeling/actions/ListAction.d.ts.map +1 -1
- package/build/src/modeling/actions/ListAction.js +18 -38
- package/build/src/modeling/actions/ListAction.js.map +1 -1
- package/build/src/modeling/actions/SearchAction.d.ts +4 -4
- package/build/src/modeling/actions/SearchAction.d.ts.map +1 -1
- package/build/src/modeling/actions/SearchAction.js +16 -13
- package/build/src/modeling/actions/SearchAction.js.map +1 -1
- package/build/src/modeling/generators/oas_312/OasGenerator.d.ts +32 -0
- package/build/src/modeling/generators/oas_312/OasGenerator.d.ts.map +1 -0
- package/build/src/modeling/generators/oas_312/OasGenerator.js +1452 -0
- package/build/src/modeling/generators/oas_312/OasGenerator.js.map +1 -0
- package/build/src/modeling/generators/oas_312/OasSchemaGenerator.d.ts +27 -0
- package/build/src/modeling/generators/oas_312/OasSchemaGenerator.d.ts.map +1 -0
- package/build/src/modeling/generators/oas_312/OasSchemaGenerator.js +295 -0
- package/build/src/modeling/generators/oas_312/OasSchemaGenerator.js.map +1 -0
- package/build/src/modeling/generators/oas_312/types.d.ts +1010 -0
- package/build/src/modeling/generators/oas_312/types.d.ts.map +1 -0
- package/build/src/modeling/generators/oas_312/types.js +2 -0
- package/build/src/modeling/generators/oas_312/types.js.map +1 -0
- package/build/src/modeling/generators/oas_320/OasGenerator.d.ts +16 -0
- package/build/src/modeling/generators/oas_320/OasGenerator.d.ts.map +1 -0
- package/build/src/modeling/generators/oas_320/OasGenerator.js +306 -0
- package/build/src/modeling/generators/oas_320/OasGenerator.js.map +1 -0
- package/build/src/modeling/generators/oas_320/OasSchemaGenerator.d.ts +25 -0
- package/build/src/modeling/generators/oas_320/OasSchemaGenerator.d.ts.map +1 -0
- package/build/src/modeling/generators/oas_320/OasSchemaGenerator.js +237 -0
- package/build/src/modeling/generators/oas_320/OasSchemaGenerator.js.map +1 -0
- package/build/src/modeling/generators/oas_320/types.d.ts +1219 -0
- package/build/src/modeling/generators/oas_320/types.d.ts.map +1 -0
- package/build/src/modeling/generators/oas_320/types.js +2 -0
- package/build/src/modeling/generators/oas_320/types.js.map +1 -0
- package/build/src/modeling/types.d.ts +50 -13
- package/build/src/modeling/types.d.ts.map +1 -1
- package/build/src/modeling/types.js.map +1 -1
- package/build/src/modeling/validation/api_model_rules.d.ts +1 -0
- package/build/src/modeling/validation/api_model_rules.d.ts.map +1 -1
- package/build/src/modeling/validation/api_model_rules.js +105 -29
- package/build/src/modeling/validation/api_model_rules.js.map +1 -1
- package/build/src/models/ProjectRequest.d.ts.map +1 -1
- package/build/src/models/ProjectRequest.js +0 -4
- package/build/src/models/ProjectRequest.js.map +1 -1
- package/build/src/models/transformers/ArcDexieTransformer.d.ts.map +1 -1
- package/build/src/models/transformers/ArcDexieTransformer.js +0 -4
- package/build/src/models/transformers/ArcDexieTransformer.js.map +1 -1
- package/build/src/models/transformers/ImportUtils.js +1 -1
- package/build/src/models/transformers/ImportUtils.js.map +1 -1
- package/build/src/models/transformers/PostmanBackupTransformer.d.ts.map +1 -1
- package/build/src/models/transformers/PostmanBackupTransformer.js +0 -4
- package/build/src/models/transformers/PostmanBackupTransformer.js.map +1 -1
- package/build/src/runtime/constants.d.ts +7 -0
- package/build/src/runtime/constants.d.ts.map +1 -0
- package/build/src/runtime/constants.js +8 -0
- package/build/src/runtime/constants.js.map +1 -0
- package/build/src/runtime/http-engine/ntlm/Des.d.ts.map +1 -1
- package/build/src/runtime/http-engine/ntlm/Des.js +1 -0
- package/build/src/runtime/http-engine/ntlm/Des.js.map +1 -1
- package/build/src/runtime/variables/EvalFunctions.d.ts.map +1 -1
- package/build/src/runtime/variables/EvalFunctions.js +0 -1
- package/build/src/runtime/variables/EvalFunctions.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/eslint.config.js +6 -0
- package/package.json +3 -1
- package/src/authorization/Utils.ts +3 -3
- package/src/modeling/ApiModel.ts +23 -8
- package/src/modeling/ApiValidation.ts +2 -0
- package/src/modeling/DomainProperty.ts +22 -18
- package/src/modeling/DomainSerialization.ts +1 -1
- package/src/modeling/ExposedEntity.ts +44 -4
- package/src/modeling/actions/Action.ts +1 -0
- package/src/modeling/actions/ListAction.ts +12 -30
- package/src/modeling/actions/SearchAction.ts +11 -8
- package/src/modeling/generators/oas_312/OasGenerator.ts +1685 -0
- package/src/modeling/generators/oas_312/OasSchemaGenerator.ts +322 -0
- package/src/modeling/generators/oas_312/types.ts +1052 -0
- package/src/modeling/generators/oas_320/OasGenerator.ts +359 -0
- package/src/modeling/generators/oas_320/OasSchemaGenerator.ts +255 -0
- package/src/modeling/generators/oas_320/types.ts +1259 -0
- package/src/modeling/types.ts +55 -22
- package/src/modeling/validation/api_model_rules.ts +103 -32
- package/src/models/ProjectRequest.ts +0 -4
- package/src/models/transformers/ArcDexieTransformer.ts +0 -4
- package/src/models/transformers/ImportUtils.ts +1 -1
- package/src/models/transformers/PostmanBackupTransformer.ts +0 -5
- package/src/runtime/constants.ts +9 -0
- package/src/runtime/http-engine/ntlm/Des.ts +1 -0
- package/src/runtime/variables/EvalFunctions.ts +0 -1
- package/tests/test-utils.ts +6 -2
- package/tests/unit/decorators/observed.spec.ts +8 -24
- package/tests/unit/decorators/observed_recursive.spec.ts +0 -1
- package/tests/unit/events/EventsTestHelpers.ts +0 -1
- package/tests/unit/events/events_polyfills.ts +0 -1
- package/tests/unit/legacy-transformers/DataTestHelper.ts +0 -2
- package/tests/unit/legacy-transformers/LegacyExportProcessor.spec.ts +0 -1
- package/tests/unit/modeling/actions/ListAction.spec.ts +9 -69
- package/tests/unit/modeling/actions/SearchAction.spec.ts +9 -35
- package/tests/unit/modeling/api_model.spec.ts +28 -0
- package/tests/unit/modeling/definitions/sku.spec.ts +0 -2
- package/tests/unit/modeling/domain_property.spec.ts +20 -1
- package/tests/unit/modeling/exposed_entity.spec.ts +71 -0
- package/tests/unit/modeling/generators/OasGenerator.spec.ts +302 -0
- package/tests/unit/modeling/validation/api_model_rules.spec.ts +113 -15
|
@@ -30,14 +30,14 @@ export function sanityCheck(settings) {
|
|
|
30
30
|
checkUrl(settings.authorizationUri);
|
|
31
31
|
}
|
|
32
32
|
catch (e) {
|
|
33
|
-
throw new Error(`authorizationUri: ${e.message}
|
|
33
|
+
throw new Error(`authorizationUri: ${e.message}`, { cause: e });
|
|
34
34
|
}
|
|
35
35
|
if (settings.accessTokenUri) {
|
|
36
36
|
try {
|
|
37
37
|
checkUrl(settings.accessTokenUri);
|
|
38
38
|
}
|
|
39
39
|
catch (e) {
|
|
40
|
-
throw new Error(`accessTokenUri: ${e.message}
|
|
40
|
+
throw new Error(`accessTokenUri: ${e.message}`, { cause: e });
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -46,7 +46,7 @@ export function sanityCheck(settings) {
|
|
|
46
46
|
checkUrl(settings.accessTokenUri);
|
|
47
47
|
}
|
|
48
48
|
catch (e) {
|
|
49
|
-
throw new Error(`accessTokenUri: ${e.message}
|
|
49
|
+
throw new Error(`accessTokenUri: ${e.message}`, { cause: e });
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../src/authorization/Utils.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,SAAS,CAAC,2BAA2B,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,QAA8B;IACxD,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAmB,CAAC,EAAE,CAAC;QAC9E,IAAI,CAAC;YACH,QAAQ,CAAC,QAAQ,CAAC,gBAA0B,CAAC,CAAA;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,qBAAsB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../src/authorization/Utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOAuth2Authorization } from '../models/Authorization.js'\n\n/**\n * Checks if the URL has valid scheme for OAuth flow.\n *\n * Do not use this to validate redirect URIs as they can use any protocol.\n *\n * @param url The url value to test\n * @throws {TypeError} When passed value is not set, empty, or not a string\n * @throws {Error} When passed value is not a valid URL for OAuth 2 flow\n */\nexport function checkUrl(url: string): void {\n if (!url) {\n throw new TypeError('the value is missing')\n }\n if (typeof url !== 'string') {\n throw new TypeError('the value is not a string')\n }\n if (!url.startsWith('http://') && !url.startsWith('https://')) {\n throw new Error('the value has invalid scheme')\n }\n}\n\n/**\n * Checks if basic configuration of the OAuth 2 request is valid an can proceed\n * with authentication.\n * @param settings authorization settings\n * @throws {Error} When settings are not valid\n */\nexport function sanityCheck(settings: IOAuth2Authorization): void {\n if (['implicit', 'authorization_code'].includes(settings.grantType as string)) {\n try {\n checkUrl(settings.authorizationUri as string)\n } catch (e) {\n throw new Error(`authorizationUri: ${(e as Error).message}`, { cause: e })\n }\n if (settings.accessTokenUri) {\n try {\n checkUrl(settings.accessTokenUri)\n } catch (e) {\n throw new Error(`accessTokenUri: ${(e as Error).message}`, { cause: e })\n }\n }\n } else if (settings.accessTokenUri) {\n try {\n checkUrl(settings.accessTokenUri)\n } catch (e) {\n throw new Error(`accessTokenUri: ${(e as Error).message}`, { cause: e })\n }\n }\n}\n\n/**\n * Generates a random string of characters.\n *\n * @returns A random string.\n */\nexport function randomString(): string {\n const array = new Uint32Array(28)\n window.crypto.getRandomValues(array)\n return Array.from(array, (dec) => `0${dec.toString(16)}`.substr(-2)).join('')\n}\n\n/**\n * Replaces `-` or `_` with camel case.\n * @param {string} name The string to process\n * @return {String|undefined} Camel cased string or `undefined` if not transformed.\n */\nexport function camel(name: string): string | undefined {\n let i = 0\n let l\n let changed = false\n\n while ((l = name[i])) {\n if ((l === '_' || l === '-') && i + 1 < name.length) {\n name = name.substring(0, i) + name[i + 1].toUpperCase() + name.substring(i + 2)\n changed = true\n }\n\n i++\n }\n return changed ? name : undefined\n}\n\n/**\n * Computes the SHA256 hash ogf the given input.\n * @param value The value to encode.\n */\nexport async function sha256(value: string): Promise<ArrayBuffer> {\n const encoder = new TextEncoder()\n const data = encoder.encode(value)\n return window.crypto.subtle.digest('SHA-256', data)\n}\n\n/**\n * Encoded the array buffer to a base64 string value.\n */\nexport function base64Buffer(buffer: ArrayBuffer): string {\n const view = new Uint8Array(buffer)\n const len = view.byteLength\n let binary = ''\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(view[i])\n }\n // const str = String.fromCharCode.apply(null, view as number[]);\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n/**\n * Generates code challenge for the PKCE extension to the OAuth2 specification.\n * @param verifier The generated code verifier.\n * @returns The code challenge string\n */\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const hashed = await sha256(verifier)\n return base64Buffer(hashed)\n}\n\n/**\n * Generates cryptographically significant random string.\n * @param size The size of the generated nonce.\n * @returns A nonce (number used once).\n */\nexport function nonceGenerator(size = 20): string {\n const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n let array = new Uint8Array(size)\n window.crypto.getRandomValues(array)\n array = array.map((x) => validChars.charCodeAt(x % validChars.length))\n const len = array.byteLength\n let binary = ''\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(array[i])\n }\n return binary\n // return String.fromCharCode.apply(null, array as any);\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ApiModelKind } from '../models/kinds.js';
|
|
2
2
|
import { type ThingSchema, Thing } from '../models/Thing.js';
|
|
3
|
-
import type { AssociationTarget,
|
|
3
|
+
import type { AssociationTarget, AuthenticationStrategy, AuthorizationStrategy, ExposedEntitySchema, SessionConfiguration, ExposeOptions, OffsetPaginationStrategy, CursorPaginationStrategy } from './types.js';
|
|
4
4
|
import { DataDomain } from './DataDomain.js';
|
|
5
5
|
import { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js';
|
|
6
6
|
import { ExposedEntity } from './ExposedEntity.js';
|
|
@@ -61,12 +61,12 @@ export interface ApiModelSchema extends DependentModelSchema {
|
|
|
61
61
|
* Configuration for how users prove their identity.
|
|
62
62
|
* The API model is invalid if this is not set.
|
|
63
63
|
*/
|
|
64
|
-
authentication?:
|
|
64
|
+
authentication?: AuthenticationStrategy;
|
|
65
65
|
/**
|
|
66
66
|
* Configuration for what authenticated users are allowed to do.
|
|
67
67
|
* The API model is invalid if this is not set.
|
|
68
68
|
*/
|
|
69
|
-
authorization?:
|
|
69
|
+
authorization?: AuthorizationStrategy;
|
|
70
70
|
/**
|
|
71
71
|
* Configuration for the transport and payload of the user session.
|
|
72
72
|
* The API model is invalid if this is not set.
|
|
@@ -103,6 +103,12 @@ export interface ApiModelSchema extends DependentModelSchema {
|
|
|
103
103
|
* The license information for the API.
|
|
104
104
|
*/
|
|
105
105
|
license?: ApiLicense;
|
|
106
|
+
/**
|
|
107
|
+
* The pagination strategy used by all endpoints in this API. The configuration
|
|
108
|
+
* is shared across all endpoints to ensure consistency and security.
|
|
109
|
+
* This defines how the results are paginated when retrieving a collection of resources.
|
|
110
|
+
*/
|
|
111
|
+
pagination: CursorPaginationStrategy | OffsetPaginationStrategy;
|
|
106
112
|
}
|
|
107
113
|
export declare class ApiModel extends DependentModel {
|
|
108
114
|
#private;
|
|
@@ -130,12 +136,12 @@ export declare class ApiModel extends DependentModel {
|
|
|
130
136
|
* Configuration for how users prove their identity.
|
|
131
137
|
* The API model is invalid if this is not set.
|
|
132
138
|
*/
|
|
133
|
-
authentication?:
|
|
139
|
+
authentication?: AuthenticationStrategy;
|
|
134
140
|
/**
|
|
135
141
|
* Configuration for what authenticated users are allowed to do.
|
|
136
142
|
* The API model is invalid if this is not set.
|
|
137
143
|
*/
|
|
138
|
-
authorization?:
|
|
144
|
+
authorization?: AuthorizationStrategy;
|
|
139
145
|
/**
|
|
140
146
|
* Configuration for the transport and payload of the user session.
|
|
141
147
|
* The API model is invalid if this is not set.
|
|
@@ -174,6 +180,11 @@ export declare class ApiModel extends DependentModel {
|
|
|
174
180
|
* The license information for the API.
|
|
175
181
|
*/
|
|
176
182
|
accessor license: ApiLicense | undefined;
|
|
183
|
+
/**
|
|
184
|
+
* The pagination strategy used by all endpoints in this API.
|
|
185
|
+
* This defines how the results are paginated when retrieving a collection of resources.
|
|
186
|
+
*/
|
|
187
|
+
accessor pagination: CursorPaginationStrategy | OffsetPaginationStrategy;
|
|
177
188
|
/**
|
|
178
189
|
* A convenience getter that returns the DataDomain associated with this API model.
|
|
179
190
|
* Since the API model can have only one DataDomain,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAqC,MAAM,oBAAoB,CAAA;AACpF,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,KAAK,EACV,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"ApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,9 @@ let ApiModel = (() => {
|
|
|
30
30
|
let _license_decorators;
|
|
31
31
|
let _license_initializers = [];
|
|
32
32
|
let _license_extraInitializers = [];
|
|
33
|
+
let _pagination_decorators;
|
|
34
|
+
let _pagination_initializers = [];
|
|
35
|
+
let _pagination_extraInitializers = [];
|
|
33
36
|
return class ApiModel extends _classSuper {
|
|
34
37
|
static {
|
|
35
38
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
@@ -39,12 +42,14 @@ let ApiModel = (() => {
|
|
|
39
42
|
_termsOfService_decorators = [observed()];
|
|
40
43
|
_contact_decorators = [observed({ deep: true })];
|
|
41
44
|
_license_decorators = [observed({ deep: true })];
|
|
45
|
+
_pagination_decorators = [observed({ deep: true })];
|
|
42
46
|
__esDecorate(this, null, _exposes_decorators, { kind: "accessor", name: "exposes", static: false, private: false, access: { has: obj => "exposes" in obj, get: obj => obj.exposes, set: (obj, value) => { obj.exposes = value; } }, metadata: _metadata }, _exposes_initializers, _exposes_extraInitializers);
|
|
43
47
|
__esDecorate(this, null, _accessRule_decorators, { kind: "accessor", name: "accessRule", static: false, private: false, access: { has: obj => "accessRule" in obj, get: obj => obj.accessRule, set: (obj, value) => { obj.accessRule = value; } }, metadata: _metadata }, _accessRule_initializers, _accessRule_extraInitializers);
|
|
44
48
|
__esDecorate(this, null, _rateLimiting_decorators, { kind: "accessor", name: "rateLimiting", static: false, private: false, access: { has: obj => "rateLimiting" in obj, get: obj => obj.rateLimiting, set: (obj, value) => { obj.rateLimiting = value; } }, metadata: _metadata }, _rateLimiting_initializers, _rateLimiting_extraInitializers);
|
|
45
49
|
__esDecorate(this, null, _termsOfService_decorators, { kind: "accessor", name: "termsOfService", static: false, private: false, access: { has: obj => "termsOfService" in obj, get: obj => obj.termsOfService, set: (obj, value) => { obj.termsOfService = value; } }, metadata: _metadata }, _termsOfService_initializers, _termsOfService_extraInitializers);
|
|
46
50
|
__esDecorate(this, null, _contact_decorators, { kind: "accessor", name: "contact", static: false, private: false, access: { has: obj => "contact" in obj, get: obj => obj.contact, set: (obj, value) => { obj.contact = value; } }, metadata: _metadata }, _contact_initializers, _contact_extraInitializers);
|
|
47
51
|
__esDecorate(this, null, _license_decorators, { kind: "accessor", name: "license", static: false, private: false, access: { has: obj => "license" in obj, get: obj => obj.license, set: (obj, value) => { obj.license = value; } }, metadata: _metadata }, _license_initializers, _license_extraInitializers);
|
|
52
|
+
__esDecorate(this, null, _pagination_decorators, { kind: "accessor", name: "pagination", static: false, private: false, access: { has: obj => "pagination" in obj, get: obj => obj.pagination, set: (obj, value) => { obj.pagination = value; } }, metadata: _metadata }, _pagination_initializers, _pagination_extraInitializers);
|
|
48
53
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
49
54
|
}
|
|
50
55
|
/**
|
|
@@ -127,11 +132,18 @@ let ApiModel = (() => {
|
|
|
127
132
|
*/
|
|
128
133
|
get license() { return this.#license_accessor_storage; }
|
|
129
134
|
set license(value) { this.#license_accessor_storage = value; }
|
|
135
|
+
#pagination_accessor_storage = (__runInitializers(this, _license_extraInitializers), __runInitializers(this, _pagination_initializers, void 0));
|
|
136
|
+
/**
|
|
137
|
+
* The pagination strategy used by all endpoints in this API.
|
|
138
|
+
* This defines how the results are paginated when retrieving a collection of resources.
|
|
139
|
+
*/
|
|
140
|
+
get pagination() { return this.#pagination_accessor_storage; }
|
|
141
|
+
set pagination(value) { this.#pagination_accessor_storage = value; }
|
|
130
142
|
/**
|
|
131
143
|
* When the initializing flag is set to true,
|
|
132
144
|
* the domain is not notified of changes.
|
|
133
145
|
*/
|
|
134
|
-
#initializing = (__runInitializers(this,
|
|
146
|
+
#initializing = (__runInitializers(this, _pagination_extraInitializers), true);
|
|
135
147
|
/**
|
|
136
148
|
* When the notifying flag is set to true,
|
|
137
149
|
* the domain is pending a notification.
|
|
@@ -155,13 +167,14 @@ let ApiModel = (() => {
|
|
|
155
167
|
return this.dependencies.get(domain.key);
|
|
156
168
|
}
|
|
157
169
|
static createSchema(input = {}) {
|
|
158
|
-
const { key = nanoid(), exposes = [] } = input;
|
|
170
|
+
const { key = nanoid(), exposes = [], pagination } = input;
|
|
159
171
|
const info = Thing.fromJSON(input.info, { name: 'Unnamed API' }).toJSON();
|
|
160
172
|
const result = {
|
|
161
173
|
kind: ApiModelKind,
|
|
162
174
|
key,
|
|
163
175
|
info,
|
|
164
176
|
exposes,
|
|
177
|
+
pagination: pagination ? structuredClone(pagination) : { kind: 'cursor' },
|
|
165
178
|
};
|
|
166
179
|
if (input.user) {
|
|
167
180
|
result.user = structuredClone(input.user);
|
|
@@ -222,6 +235,7 @@ let ApiModel = (() => {
|
|
|
222
235
|
this.key = init.key;
|
|
223
236
|
this.info = new Thing(init.info);
|
|
224
237
|
this.user = init.user;
|
|
238
|
+
this.pagination = init.pagination ? structuredClone(init.pagination) : { kind: 'cursor' };
|
|
225
239
|
if (init.authentication) {
|
|
226
240
|
this.authentication = structuredClone(init.authentication);
|
|
227
241
|
}
|
|
@@ -266,6 +280,7 @@ let ApiModel = (() => {
|
|
|
266
280
|
key: this.key,
|
|
267
281
|
info: this.info.toJSON(),
|
|
268
282
|
exposes: Array.from(this.exposes.values()).map((e) => e.toJSON()),
|
|
283
|
+
pagination: structuredClone(toRaw(this, this.pagination)),
|
|
269
284
|
};
|
|
270
285
|
if (this.user) {
|
|
271
286
|
result.user = { ...this.user };
|
|
@@ -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 AuthenticationConfiguration,\n AuthorizationConfiguration,\n ExposedEntitySchema,\n RolesBasedAccessControl,\n SessionConfiguration,\n UsernamePasswordConfiguration,\n ExposeOptions,\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'\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 /**\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?: AuthenticationConfiguration\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?: AuthorizationConfiguration\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\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?: AuthenticationConfiguration\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?: AuthorizationConfiguration\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({ deep: true }) 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({ deep: true }) 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 /**\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 = [] } = 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 }\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 instances.push(domain)\n } else if (typeof domain === 'object' && domain.kind === DataDomainKind) {\n instances.push(new DataDomain(domain))\n } else if (domain) {\n throw new Error(`Invalid domain provided. Expected a DataDomain instance or schema.`)\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 Error(`Domain ${domain.key} must have a version.`)\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 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(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 }\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 Error(`No domain attached to API model`)\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 // quietly return the existing exposure\n // TBD: should we throw an error here?\n return existing\n }\n const domainEntity = domain.findEntity(entity.key, entity.domain)\n if (!domainEntity) {\n throw new Error(`Entity not found in domain: ${entity.key}`)\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 return\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 Error(`Exposed entity with key \"${key}\" not found.`)\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 if (this.authentication && this.authentication.strategy === 'UsernamePassword') {\n const typed = this.authentication as UsernamePasswordConfiguration\n typed.passwordKey = undefined\n }\n if (this.authorization && this.authorization.strategy == 'RBAC') {\n const typed = this.authorization as RolesBasedAccessControl\n typed.roleKey = ''\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 Error(`Cannot attach DataDomain without a version. Please set the version in the domain info.`)\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":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACpF,OAAO,EAAoB,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAa5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAoD,MAAM,qBAAqB,CAAA;AACtG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,SAAS,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,yBAAyB,EAAmC,MAAM,sCAAsC,CAAA;AACjH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;IAiHvC,QAAQ;sBAAS,cAAc;;;;;;;;;;;;;;;;;;;;;;iBAA/B,QAAS,SAAQ,WAAc;;;mCA8CzC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;sCASxB,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;wCAKxB,QAAQ,EAAE;0CAIV,QAAQ,EAAE;mCAIV,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;mCAIxB,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;sCAKxB,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YA/BC,0KAAS,OAAO,6BAAP,OAAO,yFAA4B;YAS5C,mLAAS,UAAU,6BAAV,UAAU,+FAAc;YAK/C,yLAAS,YAAY,6BAAZ,YAAY,mGAAuC;YAI5D,+LAAS,cAAc,6BAAd,cAAc,uGAAoB;YAI7B,0KAAS,OAAO,6BAAP,OAAO,yFAAwB;YAIxC,0KAAS,OAAO,6BAAP,OAAO,yFAAwB;YAKxC,mLAAS,UAAU,6BAAV,UAAU,+FAAqD;;;QA5ElG;;WAEG;QACH,IAAI,CAAqB;QACzB;;;WAGG;QACH,GAAG,CAAQ;QAEX;;WAEG;QACH,IAAI,CAAO;QACX;;;;;WAKG;QACH,IAAI,CAAoB;QAExB;;;WAGG;QACH,cAAc,CAAyB;QAEvC;;;WAGG;QACH,aAAa,CAAwB;QAErC;;;WAGG;QACH,OAAO,CAAuB;QAOJ,mFAA4C;QANtE;;;;;WAKG;QACuB,IAAS,OAAO,6CAA4B;QAA5C,IAAS,OAAO,mDAA4B;QAS5C,gJAAiC;QAR3D;;;;;;;WAOG;QACuB,IAAS,UAAU,gDAAc;QAAjC,IAAS,UAAU,sDAAc;QAK/C,uJAA4D;QAJxE;;;WAGG;QACS,IAAS,YAAY,kDAAuC;QAA5D,IAAS,YAAY,wDAAuC;QAI5D,6JAA2C;QAHvD;;WAEG;QACS,IAAS,cAAc,oDAAoB;QAA3C,IAAS,cAAc,0DAAoB;QAI7B,iJAAwC;QAHlE;;WAEG;QACuB,IAAS,OAAO,6CAAwB;QAAxC,IAAS,OAAO,mDAAwB;QAIxC,0IAAwC;QAHlE;;WAEG;QACuB,IAAS,OAAO,6CAAwB;QAAxC,IAAS,OAAO,mDAAwB;QAKxC,gJAAwE;QAJlG;;;WAGG;QACuB,IAAS,UAAU,gDAAqD;QAAxE,IAAS,UAAU,sDAAqD;QAElG;;;WAGG;QACH,aAAa,4DAAG,IAAI,EAAA;QAEpB;;;;;WAKG;QACH,UAAU,GAAG,KAAK,CAAA;QAElB;;;;;;;WAOG;QACH,IAAI,MAAM;YACR,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrC,OAAO,SAAS,CAAA;YAClB,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;YACrC,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC1C,CAAC;QAED,MAAM,CAAC,YAAY,CAAC,QAAiC,EAAE;YACrD,MAAM,EAAE,GAAG,GAAG,MAAM,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;YAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAA;YACzE,MAAM,MAAM,GAAmB;gBAC7B,IAAI,EAAE,YAAY;gBAClB,GAAG;gBACH,IAAI;gBACJ,OAAO;gBACP,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC1E,CAAA;YACD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC3C,CAAC;YACD,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,CAAC,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;YAC/D,CAAC;YACD,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,CAAC,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;YAC/D,CAAC;YACD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACxB,MAAM,CAAC,aAAa,GAAG,eAAe,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YAC7D,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjD,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpC,MAAM,CAAC,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YACvD,CAAC;YACD,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,CAAC,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;YAC3D,CAAC;YACD,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAA;YAC9C,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjD,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjD,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QAED,YAAY,KAA+B,EAAE,MAAyB;YACpE,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;YACzC,MAAM,SAAS,GAAiB,EAAE,CAAA;YAClC,IAAI,MAAM,YAAY,UAAU,EAAE,CAAC;gBACjC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACxB,CAAC;iBAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACxE,SAAS,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;YACxC,CAAC;iBAAM,IAAI,MAAM,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;YACvF,CAAC;YACD,0GAA0G;YAC1G,gFAAgF;YAChF,mHAAmH;YACnH,qDAAqD;YACrD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,GAAG,uBAAuB,CAAC,CAAA;gBAC9D,CAAC;gBACD,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;YAC3E,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;YACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;YACrB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;YACnB,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;YACzF,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,CAAC,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAC5D,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC1D,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC9C,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChC,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACtF,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAA;YAC1B,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAA;YAC1E,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;YACtB,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,IAAI,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YACtE,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;YAC3C,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;YAC7B,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;YAC7B,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;YAC1B,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACxC,IAAI,CAAC,YAAY,EAAE,CAAA;YACrB,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,MAAM;YACJ,MAAM,MAAM,GAAmB;gBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBACxB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBACjE,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAwD;aACjH,CAAA;YACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;YAChC,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,MAAM,CAAC,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAC9D,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,MAAM,CAAC,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAC9D,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,CAAC,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC5D,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAChD,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;YAClE,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;YAClD,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;YAC7C,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;YAC7D,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;YAC7D,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QAED;;;;WAIG;QACH,YAAY;YACV,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC1C,OAAM;YACR,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;YACtB,cAAc,CAAC,GAAG,EAAE;gBAClB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;gBACvB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAA;gBACjC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YAC3B,CAAC,CAAC,CAAA;QACJ,CAAC;QAED;;;;;;;;;;;WAWG;QACH,YAAY,CAAC,MAAyB,EAAE,OAAuB;YAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;YACpD,CAAC;YACD,mEAAmE;YACnE,IAAI,QAAmC,CAAA;YACvC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACxC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC;oBAChD,QAAQ,GAAG,GAAG,CAAA;oBACd,MAAK;gBACP,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,uCAAuC;gBACvC,sCAAsC;gBACtC,OAAO,QAAQ,CAAA;YACjB,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACjE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;YAC9D,CAAC;YACD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;YACzC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAA;YACnD,IAAI,sBAAsB,GAAG,IAAI,OAAO,EAAE,CAAA;YAC1C,IAAI,oBAAoB,GAAG,IAAI,OAAO,OAAO,CAAA;YAE7C,kEAAkE;YAClE,IAAI,OAAO,GAAG,CAAC,CAAA;YACf,MAAM,sBAAsB,GAAG,sBAAsB,CAAA;YACrD,OAAO,IAAI,CAAC,2BAA2B,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBAChE,sBAAsB,GAAG,GAAG,sBAAsB,IAAI,OAAO,EAAE,CAAA;gBAC/D,oBAAoB,GAAG,GAAG,sBAAsB,OAAO,CAAA;gBACvD,OAAO,EAAE,CAAA;YACX,CAAC;YAED,MAAM,SAAS,GAAwB;gBACrC,IAAI,EAAE,iBAAiB;gBACvB,GAAG,EAAE,MAAM,EAAE;gBACb,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE;gBACrB,OAAO,EAAE,EAAE;gBACX,MAAM,EAAE,IAAI;gBACZ,cAAc,EAAE,sBAAsB;gBACtC,YAAY,EAAE,oBAAoB;gBAClC,aAAa,EAAE,IAAI;aACpB,CAAA;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,CAAC,aAAa,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;YAC1C,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAEtC,mCAAmC;YACnC,IAAI,OAAO,EAAE,kBAAkB,EAAE,CAAC;gBAChC,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;oBAC5D,IAAI,CAAC,wBAAwB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC;YACD,IAAI,CAAC,YAAY,EAAE,CAAA;YACnB,OAAO,OAAO,CAAA;QAChB,CAAC;QAED;;;;;;WAMG;QACK,wBAAwB,CAAC,cAAmC,EAAE,OAAsB;YAC1F,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAM;YACR,CAAC;YACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAA;YACtC,MAAM,MAAM,GAAG,CAAC,aAAgC,EAAE,SAAiB,EAAE,KAAa,EAAE,WAAqB,EAAE,EAAE;gBAC3G,yBAAyB;gBACzB,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;gBAC/E,IAAI,CAAC,YAAY;oBAAE,OAAM;gBAEzB,+BAA+B;gBAC/B,KAAK,MAAM,WAAW,IAAI,YAAY,CAAC,gBAAgB,EAAE,EAAE,CAAC;oBAC1D,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;wBACzC,qCAAqC;wBACrC,IAAI,MAAM,CAAC,GAAG,KAAK,aAAa,CAAC,GAAG,IAAI,MAAM,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;4BAC/E,SAAQ;wBACV,CAAC;wBAED,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;wBAC1C,uFAAuF;wBACvF,IAAI,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;4BACrC,SAAQ;wBACV,CAAC;wBAED,gEAAgE;wBAChE,IAAI,gBAA2C,CAAA;wBAC/C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;4BACxC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC;gCAClC,gBAAgB,GAAG,GAAG,CAAA;gCACtB,MAAK;4BACP,CAAC;wBACH,CAAC;wBAED,IAAI,gBAAgB,EAAE,CAAC;4BACrB,8FAA8F;4BAC9F,sFAAsF;4BACtF,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;gCAC7B,oDAAoD;gCACpD,MAAM,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;gCACpE,IAAI,eAAe,EAAE,CAAC;oCACpB,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;oCAC5C,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAA;oCACnD,IAAI,sBAAsB,GAAG,IAAI,OAAO,EAAE,CAAA;oCAC1C,IAAI,oBAAoB,GAAG,IAAI,OAAO,OAAO,CAAA;oCAE7C,IAAI,OAAO,GAAG,CAAC,CAAA;oCACf,MAAM,sBAAsB,GAAG,sBAAsB,CAAA;oCACrD,OAAO,IAAI,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,EAAE,CAAC;wCAC9D,sBAAsB,GAAG,GAAG,sBAAsB,IAAI,OAAO,EAAE,CAAA;wCAC/D,oBAAoB,GAAG,GAAG,sBAAsB,OAAO,CAAA;wCACvD,OAAO,EAAE,CAAA;oCACX,CAAC;oCAED,uCAAuC;oCACvC,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAA;oCAC9B,gBAAgB,CAAC,MAAM,GAAG,SAAS,CAAA;oCACnC,gBAAgB,CAAC,cAAc,GAAG,sBAAsB,CAAA;oCACxD,gBAAgB,CAAC,YAAY,GAAG,oBAAoB,CAAA;oCACpD,gBAAgB,CAAC,aAAa,GAAG,IAAI,CAAA;gCACvC,CAAC;4BACH,CAAC;4BACD,8EAA8E;4BAC9E,SAAQ;wBACV,CAAC;wBAED,oDAAoD;wBACpD,MAAM,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;wBACvE,IAAI,CAAC,kBAAkB;4BAAE,SAAQ;wBAEjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;wBACxC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAA;wBACnD,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,KAAK,KAAK,CAAA;wBACnD,MAAM,sBAAsB,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;wBACvE,MAAM,oBAAoB,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAA;wBAC9E,yBAAyB;wBACzB,MAAM,cAAc,GAAwB;4BAC1C,IAAI,EAAE,iBAAiB;4BACvB,GAAG,EAAE,MAAM,EAAE;4BACb,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE;4BACrB,OAAO,EAAE,EAAE;4BACX,MAAM,EAAE,KAAK;4BACb,cAAc,EAAE,sBAAsB;4BACtC,YAAY,EAAE,oBAAoB;4BAClC,aAAa,EAAE,YAAY;4BAC3B,MAAM,EAAE;gCACN,GAAG,EAAE,SAAS;gCACd,WAAW,EAAE;oCACX,GAAG,EAAE,WAAW,CAAC,GAAG;oCACpB,MAAM,EAAE,aAAa,CAAC,MAAM;iCAC7B;gCACD,KAAK,EAAE,KAAK,GAAG,CAAC;6BACjB;yBACF,CAAA;wBAED,MAAM,IAAI,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;wBACpD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;wBAChC,IAAI,KAAK,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;4BAC1B,cAAc,CAAC,SAAS,GAAG,IAAI,CAAA;wBACjC,CAAC;6BAAM,CAAC;4BACN,kCAAkC;4BAClC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,UAAU,CAAC,CAAC,CAAA;wBAC7E,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAA;YAED,yCAAyC;YACzC,+CAA+C;YAC/C,MAAM,OAAO,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;YACtD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;QACjE,CAAC;QAED;;;;;WAKG;QACH,mBAAmB,CAAC,GAAW;YAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,cAAc,CAAC,CAAA;YAChE,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAC9B,CAAC;QAEO,kBAAkB,CAAC,GAAW;YACpC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,OAAM;YACR,CAAC;YACD,2BAA2B;YAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACxB,kCAAkC;YAClC,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAE,EAAE;gBAC3C,wDAAwD;gBACxD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC1C,IAAI,KAAK,CAAC,MAAM,EAAE,GAAG,KAAK,SAAS,EAAE,CAAC;wBACpC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;wBACzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;oBAChC,CAAC;gBACH,CAAC;YACH,CAAC,CAAA;YACD,4BAA4B;YAC5B,cAAc,CAAC,GAAG,CAAC,CAAA;YACnB,IAAI,CAAC,YAAY,EAAE,CAAA;QACrB,CAAC;QAED;;;;WAIG;QACH,oBAAoB;YAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;YACzB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;YACxB,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAA;YACxB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAA;YACrB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAA;YAC9B,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,KAAK,kBAAkB,EAAE,CAAC;gBAC/E,MAAM,KAAK,GAAG,IAAI,CAAC,cAA+C,CAAA;gBAClE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAA;YAC/B,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,MAAM,EAAE,CAAC;gBAChE,MAAM,KAAK,GAAG,IAAI,CAAC,aAAwC,CAAA;gBAC3D,KAAK,CAAC,OAAO,GAAG,EAAE,CAAA;YACpB,CAAC;QACH,CAAC;QAED;;;;;;WAMG;QACH,gBAAgB,CAAC,MAAkB;YACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,wFAAwF,CAAC,CAAA;YAC3G,CAAC;YACD,IAAI,CAAC,oBAAoB,EAAE,CAAA;YAC3B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;YACzC,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;YACzE,IAAI,CAAC,YAAY,EAAE,CAAA;QACrB,CAAC;QAED;;;;;;;WAOG;QACH,yBAAyB,CAAC,IAAY,EAAE,MAAe;YACrD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACtC,IAAI,MAAM,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;oBAC/B,SAAQ;gBACV,CAAC;gBACD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;oBACxC,OAAO,CAAC,CAAA;gBACV,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAA;QAClB,CAAC;QAED;;;;;;;WAOG;QACH,2BAA2B,CAAC,IAAY,EAAE,MAAe;YACvD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACtC,IAAI,MAAM,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;oBAC/B,SAAQ;gBACV,CAAC;gBACD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;oBAC7D,OAAO,CAAC,CAAA;gBACV,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAA;QAClB,CAAC;;;SAnkBU,QAAQ","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 RolesBasedAccessControl,\n SessionConfiguration,\n UsernamePasswordConfiguration,\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'\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({ deep: true }) 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({ deep: true }) 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 instances.push(domain)\n } else if (typeof domain === 'object' && domain.kind === DataDomainKind) {\n instances.push(new DataDomain(domain))\n } else if (domain) {\n throw new Error(`Invalid domain provided. Expected a DataDomain instance or schema.`)\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 Error(`Domain ${domain.key} must have a version.`)\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(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 Error(`No domain attached to API model`)\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 // quietly return the existing exposure\n // TBD: should we throw an error here?\n return existing\n }\n const domainEntity = domain.findEntity(entity.key, entity.domain)\n if (!domainEntity) {\n throw new Error(`Entity not found in domain: ${entity.key}`)\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 return\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 Error(`Exposed entity with key \"${key}\" not found.`)\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 if (this.authentication && this.authentication.strategy === 'UsernamePassword') {\n const typed = this.authentication as UsernamePasswordConfiguration\n typed.passwordKey = undefined\n }\n if (this.authorization && this.authorization.strategy == 'RBAC') {\n const typed = this.authorization as RolesBasedAccessControl\n typed.roleKey = ''\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 Error(`Cannot attach DataDomain without a version. Please set the version in the domain info.`)\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":"ApiValidation.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"ApiValidation.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAWnD;;;;;;GAMG;AACH,qBAAa,aAAa;;IA4BZ,SAAS,CAAC,KAAK,EAAE,QAAQ;IA3BrC,MAAM,EAAE,sBAAsB,EAAE,CAAK;IAMrC,IAAI,SAAS,IAAI,MAAM,CAKtB;IAED,IAAI,YAAY,IAAI,MAAM,CAKzB;IAED,IAAI,UAAU,IAAI,MAAM,CAKvB;gBAEqB,KAAK,EAAE,QAAQ;IAErC;;;;OAIG;IACH,QAAQ,IAAI,sBAAsB,EAAE;IA2BpC,oBAAoB,IAAI,IAAI;CAM7B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApiModelKind } from '../models/kinds.js';
|
|
2
|
-
import { validateApiModelInfo, validateApiModelDependency, validateApiModelSecurity, validateApiModelMetadata, validateExposedEntity, } from './validation/api_model_rules.js';
|
|
2
|
+
import { validateApiModelInfo, validateApiModelDependency, validateApiModelSecurity, validateApiModelMetadata, validateExposedEntity, validateApiPagination, } from './validation/api_model_rules.js';
|
|
3
3
|
/**
|
|
4
4
|
* ApiValidation performs comprehensive validation on an API model.
|
|
5
5
|
*
|
|
@@ -46,6 +46,7 @@ export class ApiValidation {
|
|
|
46
46
|
this.report.push(...validateApiModelInfo(this.model));
|
|
47
47
|
this.report.push(...validateApiModelDependency(this.model));
|
|
48
48
|
this.report.push(...validateApiModelSecurity(this.model));
|
|
49
|
+
this.report.push(...validateApiPagination(this.model));
|
|
49
50
|
this.report.push(...validateApiModelMetadata(this.model));
|
|
50
51
|
if (!this.model.exposes || this.model.exposes.size === 0) {
|
|
51
52
|
this.report.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiValidation.js","sourceRoot":"","sources":["../../../src/modeling/ApiValidation.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiModel } from './ApiModel.js'\nimport { ApiModelValidationItem } from './types.js'\nimport { ApiModelKind } from '../models/kinds.js'\nimport {\n validateApiModelInfo,\n validateApiModelDependency,\n validateApiModelSecurity,\n validateApiModelMetadata,\n validateExposedEntity,\n} from './validation/api_model_rules.js'\n\n/**\n * ApiValidation performs comprehensive validation on an API model.\n *\n * This class orchestrates validation across all API model elements including\n * info, security, exposures, and actions. It ensures that the API model is\n * well-formed and follows established conventions before it can be published.\n */\nexport class ApiValidation {\n report: ApiModelValidationItem[] = []\n #infoCount = 0\n #warningCount = 0\n #errorCount = 0\n #counted = false\n\n get infoCount(): number {\n if (!this.#counted) {\n this.computeIssueCounters()\n }\n return this.#infoCount\n }\n\n get warningCount(): number {\n if (!this.#counted) {\n this.computeIssueCounters()\n }\n return this.#warningCount\n }\n\n get errorCount(): number {\n if (!this.#counted) {\n this.computeIssueCounters()\n }\n return this.#errorCount\n }\n\n constructor(protected model: ApiModel) {}\n\n /**\n * Performs comprehensive validation on the entire API model.\n *\n * @returns A comprehensive validation report with all issues found\n */\n validate(): ApiModelValidationItem[] {\n this.#counted = false\n this.report = []\n\n this.report.push(...validateApiModelInfo(this.model))\n this.report.push(...validateApiModelDependency(this.model))\n this.report.push(...validateApiModelSecurity(this.model))\n this.report.push(...validateApiModelMetadata(this.model))\n\n if (!this.model.exposes || this.model.exposes.size === 0) {\n this.report.push({\n code: 'API_NO_EXPOSURES',\n message: 'Your API currently has no exposed data for external clients to request.',\n suggestion: 'Expose a data model so apps can communicate with it.',\n severity: 'warning',\n context: { apiModelKey: this.model.key, kind: ApiModelKind, key: this.model.key, property: 'exposes' },\n })\n } else {\n for (const exposure of this.model.exposes.values()) {\n this.report.push(...validateExposedEntity(exposure, this.model))\n }\n }\n\n return this.report\n }\n\n computeIssueCounters(): void {\n this.#infoCount = this.report.filter((validation) => validation.severity === 'info').length\n this.#warningCount = this.report.filter((validation) => validation.severity === 'warning').length\n this.#errorCount = this.report.filter((validation) => validation.severity === 'error').length\n this.#counted = true\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ApiValidation.js","sourceRoot":"","sources":["../../../src/modeling/ApiValidation.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiModel } from './ApiModel.js'\nimport { ApiModelValidationItem } from './types.js'\nimport { ApiModelKind } from '../models/kinds.js'\nimport {\n validateApiModelInfo,\n validateApiModelDependency,\n validateApiModelSecurity,\n validateApiModelMetadata,\n validateExposedEntity,\n validateApiPagination,\n} from './validation/api_model_rules.js'\n\n/**\n * ApiValidation performs comprehensive validation on an API model.\n *\n * This class orchestrates validation across all API model elements including\n * info, security, exposures, and actions. It ensures that the API model is\n * well-formed and follows established conventions before it can be published.\n */\nexport class ApiValidation {\n report: ApiModelValidationItem[] = []\n #infoCount = 0\n #warningCount = 0\n #errorCount = 0\n #counted = false\n\n get infoCount(): number {\n if (!this.#counted) {\n this.computeIssueCounters()\n }\n return this.#infoCount\n }\n\n get warningCount(): number {\n if (!this.#counted) {\n this.computeIssueCounters()\n }\n return this.#warningCount\n }\n\n get errorCount(): number {\n if (!this.#counted) {\n this.computeIssueCounters()\n }\n return this.#errorCount\n }\n\n constructor(protected model: ApiModel) {}\n\n /**\n * Performs comprehensive validation on the entire API model.\n *\n * @returns A comprehensive validation report with all issues found\n */\n validate(): ApiModelValidationItem[] {\n this.#counted = false\n this.report = []\n\n this.report.push(...validateApiModelInfo(this.model))\n this.report.push(...validateApiModelDependency(this.model))\n this.report.push(...validateApiModelSecurity(this.model))\n this.report.push(...validateApiPagination(this.model))\n this.report.push(...validateApiModelMetadata(this.model))\n\n if (!this.model.exposes || this.model.exposes.size === 0) {\n this.report.push({\n code: 'API_NO_EXPOSURES',\n message: 'Your API currently has no exposed data for external clients to request.',\n suggestion: 'Expose a data model so apps can communicate with it.',\n severity: 'warning',\n context: { apiModelKey: this.model.key, kind: ApiModelKind, key: this.model.key, property: 'exposes' },\n })\n } else {\n for (const exposure of this.model.exposes.values()) {\n this.report.push(...validateExposedEntity(exposure, this.model))\n }\n }\n\n return this.report\n }\n\n computeIssueCounters(): void {\n this.#infoCount = this.report.filter((validation) => validation.severity === 'info').length\n this.#warningCount = this.report.filter((validation) => validation.severity === 'warning').length\n this.#errorCount = this.report.filter((validation) => validation.severity === 'error').length\n this.#counted = true\n }\n}\n"]}
|
|
@@ -34,8 +34,14 @@ export interface DomainPropertySchema extends DomainElementSchema {
|
|
|
34
34
|
unique?: boolean;
|
|
35
35
|
/**
|
|
36
36
|
* Whether this property describes an indexed property of the entity.
|
|
37
|
+
* This enables a standard B-Tree index.
|
|
37
38
|
*/
|
|
38
39
|
index?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether this property describes a search index of the entity.
|
|
42
|
+
* This enables a specialized Inverted Index (e.g., a GIN or `pg_trgm` index in PostgreSQL).
|
|
43
|
+
*/
|
|
44
|
+
search?: boolean;
|
|
39
45
|
/**
|
|
40
46
|
* Whether the property is read only in the schema.
|
|
41
47
|
*/
|
|
@@ -147,8 +153,14 @@ export declare class DomainProperty extends DomainElement {
|
|
|
147
153
|
accessor unique: boolean | undefined;
|
|
148
154
|
/**
|
|
149
155
|
* Whether this property describes an indexed property of the entity.
|
|
156
|
+
* This enables a standard B-Tree index.
|
|
150
157
|
*/
|
|
151
158
|
accessor index: boolean | undefined;
|
|
159
|
+
/**
|
|
160
|
+
* Whether this property describes a search index of the entity.
|
|
161
|
+
* This enables a specialized Inverted Index (e.g., a GIN or `pg_trgm` index in PostgreSQL).
|
|
162
|
+
*/
|
|
163
|
+
accessor search: boolean | undefined;
|
|
152
164
|
/**
|
|
153
165
|
* Whether the property is read only in the schema.
|
|
154
166
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DomainProperty.d.ts","sourceRoot":"","sources":["../../../src/modeling/DomainProperty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAE5E,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE5D,OAAO,EAGL,KAAK,uBAAuB,EAE5B,KAAK,oBAAoB,EAEzB,KAAK,kBAAkB,EAIxB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAC3F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAqC,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAE/G,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,IAAI,EAAE,OAAO,kBAAkB,CAAA;IAC/B;;OAEG;IACH,IAAI,EAAE,WAAW,CAAA;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB
|
|
1
|
+
{"version":3,"file":"DomainProperty.d.ts","sourceRoot":"","sources":["../../../src/modeling/DomainProperty.ts"],"names":[],"mappings":"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"}
|