@api-client/core 0.18.2 → 0.18.4
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/modeling/ApiModel.d.ts +5 -5
- package/build/src/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +8 -8
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/helpers/database.d.ts +24 -0
- package/build/src/modeling/helpers/database.d.ts.map +1 -0
- package/build/src/modeling/helpers/database.js +42 -0
- package/build/src/modeling/helpers/database.js.map +1 -0
- package/build/src/modeling/importers/CsvImporter.d.ts +36 -0
- package/build/src/modeling/importers/CsvImporter.d.ts.map +1 -0
- package/build/src/modeling/importers/CsvImporter.js +81 -0
- package/build/src/modeling/importers/CsvImporter.js.map +1 -0
- package/build/src/modeling/importers/ImporterException.d.ts +10 -0
- package/build/src/modeling/importers/ImporterException.d.ts.map +1 -0
- package/build/src/modeling/importers/ImporterException.js +10 -0
- package/build/src/modeling/importers/ImporterException.js.map +1 -0
- package/build/src/modeling/importers/JsonSchemaImporter.d.ts +99 -0
- package/build/src/modeling/importers/JsonSchemaImporter.d.ts.map +1 -0
- package/build/src/modeling/importers/JsonSchemaImporter.js +525 -0
- package/build/src/modeling/importers/JsonSchemaImporter.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +13 -13
- package/package.json +5 -2
- package/src/modeling/ApiModel.ts +11 -10
- package/src/modeling/helpers/database.ts +48 -0
- package/src/modeling/importers/CsvImporter.ts +88 -0
- package/src/modeling/importers/ImporterException.ts +10 -0
- package/src/modeling/importers/JsonSchemaImporter.ts +642 -0
- package/tests/unit/modeling/api_model.spec.ts +9 -9
- package/tests/unit/modeling/importers/csv_importer.spec.ts +189 -0
- package/tests/unit/modeling/importers/json_schema_importer.spec.ts +451 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ApiModelKind } from '../models/kinds.js';
|
|
2
2
|
import { type IThing, Thing } from '../models/Thing.js';
|
|
3
|
-
import type { AccessRule, AuthenticationConfiguration, AuthorizationConfiguration, ExposedEntity, RateLimitingConfiguration, SessionConfiguration } from './types.js';
|
|
3
|
+
import type { AccessRule, AssociationTarget, AuthenticationConfiguration, AuthorizationConfiguration, ExposedEntity, RateLimitingConfiguration, SessionConfiguration } from './types.js';
|
|
4
4
|
import { DataDomain } from './DataDomain.js';
|
|
5
5
|
import { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js';
|
|
6
6
|
/**
|
|
@@ -49,11 +49,11 @@ export interface ApiModelSchema extends DependentModelSchema {
|
|
|
49
49
|
info: IThing;
|
|
50
50
|
/**
|
|
51
51
|
* The designated Data Entity that represents a "User".
|
|
52
|
-
* This entity
|
|
52
|
+
* This entity should be marked with the "User" semantic in the Data Modeler.
|
|
53
53
|
*
|
|
54
54
|
* This property is required to publish the API.
|
|
55
55
|
*/
|
|
56
|
-
|
|
56
|
+
user?: AssociationTarget;
|
|
57
57
|
/**
|
|
58
58
|
* Configuration for how users prove their identity.
|
|
59
59
|
* The API model is invalid if this is not set.
|
|
@@ -122,7 +122,7 @@ export declare class ApiModel extends DependentModel {
|
|
|
122
122
|
*
|
|
123
123
|
* This property is required to publish the API.
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
user?: AssociationTarget;
|
|
126
126
|
/**
|
|
127
127
|
* Configuration for how users prove their identity.
|
|
128
128
|
* The API model is invalid if this is not set.
|
|
@@ -207,7 +207,7 @@ export declare class ApiModel extends DependentModel {
|
|
|
207
207
|
getExposedEntity(entityKey: string): ExposedEntity | undefined;
|
|
208
208
|
/**
|
|
209
209
|
* Clears the API model for a new entity change.
|
|
210
|
-
* This method resets the dependencies, exposes,
|
|
210
|
+
* This method resets the dependencies, exposes, user,
|
|
211
211
|
* authentication, authorization, and session properties.
|
|
212
212
|
*/
|
|
213
213
|
cleanForEntityChange(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAkB,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EACV,UAAU,EACV,2BAA2B,EAC3B,0BAA0B,EAC1B,aAAa,EACb,yBAAyB,EAEzB,oBAAoB,EAErB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAGtG;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAC1D;;OAEG;IACH,IAAI,EAAE,OAAO,YAAY,CAAA;IACzB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;;OAKG;IACH,
|
|
1
|
+
{"version":3,"file":"ApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAkB,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,EAC1B,aAAa,EACb,yBAAyB,EAEzB,oBAAoB,EAErB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAGtG;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAC1D;;OAEG;IACH,IAAI,EAAE,OAAO,YAAY,CAAA;IACzB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;;OAKG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAA;IAExB;;;OAGG;IACH,cAAc,CAAC,EAAE,2BAA2B,CAAA;IAE5C;;;OAGG;IACH,aAAa,CAAC,EAAE,0BAA0B,CAAA;IAE1C;;;OAGG;IACH,OAAO,CAAC,EAAE,oBAAoB,CAAA;IAC9B;;;OAGG;IACH,OAAO,EAAE,aAAa,EAAE,CAAA;IAExB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAA;IACxC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AAED,qBAAa,QAAS,SAAQ,cAAc;;IAC1C;;OAEG;IACH,IAAI,EAAE,OAAO,YAAY,CAAA;IACzB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;OAEG;IACH,IAAI,EAAE,KAAK,CAAA;IACX;;;;;OAKG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAA;IAExB;;;OAGG;IACH,cAAc,CAAC,EAAE,2BAA2B,CAAA;IAE5C;;;OAGG;IACH,aAAa,CAAC,EAAE,0BAA0B,CAAA;IAE1C;;;OAGG;IACH,OAAO,CAAC,EAAE,oBAAoB,CAAA;IAC9B;;;OAGG;IACH,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAA;IACxC;;OAEG;IACS,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IACvD;;OAEG;IACuB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CAAA;IAClE;;OAEG;IACuB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CAAA;IAgBlE;;;;;;;OAOG;IACH,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS,CAMnC;IAED,MAAM,CAAC,YAAY,CAAC,KAAK,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,cAAc;gBA0C5D,KAAK,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAkDtE,MAAM,IAAI,cAAc;IAwCxB;;;;OAIG;IACH,YAAY;IAYZ;;;;;OAKG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa;IAc9C;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOrC;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI9D;;;;OAIG;IACH,oBAAoB,IAAI,IAAI;IAkB5B;;;;;;OAMG;IACH,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;CAS3C"}
|
|
@@ -46,7 +46,7 @@ let ApiModel = (() => {
|
|
|
46
46
|
*
|
|
47
47
|
* This property is required to publish the API.
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
user;
|
|
50
50
|
/**
|
|
51
51
|
* Configuration for how users prove their identity.
|
|
52
52
|
* The API model is invalid if this is not set.
|
|
@@ -135,8 +135,8 @@ let ApiModel = (() => {
|
|
|
135
135
|
info,
|
|
136
136
|
exposes,
|
|
137
137
|
};
|
|
138
|
-
if (input.
|
|
139
|
-
result.
|
|
138
|
+
if (input.user) {
|
|
139
|
+
result.user = { ...input.user };
|
|
140
140
|
}
|
|
141
141
|
if (input.dependencyList) {
|
|
142
142
|
result.dependencyList = structuredClone(input.dependencyList);
|
|
@@ -183,7 +183,7 @@ let ApiModel = (() => {
|
|
|
183
183
|
this.kind = init.kind;
|
|
184
184
|
this.key = init.key;
|
|
185
185
|
this.info = new Thing(init.info);
|
|
186
|
-
this.
|
|
186
|
+
this.user = init.user;
|
|
187
187
|
if (init.authentication) {
|
|
188
188
|
this.authentication = structuredClone(init.authentication);
|
|
189
189
|
}
|
|
@@ -226,8 +226,8 @@ let ApiModel = (() => {
|
|
|
226
226
|
info: this.info.toJSON(),
|
|
227
227
|
exposes: structuredClone(this.exposes),
|
|
228
228
|
};
|
|
229
|
-
if (this.
|
|
230
|
-
result.
|
|
229
|
+
if (this.user) {
|
|
230
|
+
result.user = { ...this.user };
|
|
231
231
|
}
|
|
232
232
|
if (this.dependencyList.length > 0) {
|
|
233
233
|
result.dependencyList = structuredClone(this.dependencyList);
|
|
@@ -314,14 +314,14 @@ let ApiModel = (() => {
|
|
|
314
314
|
}
|
|
315
315
|
/**
|
|
316
316
|
* Clears the API model for a new entity change.
|
|
317
|
-
* This method resets the dependencies, exposes,
|
|
317
|
+
* This method resets the dependencies, exposes, user,
|
|
318
318
|
* authentication, authorization, and session properties.
|
|
319
319
|
*/
|
|
320
320
|
cleanForEntityChange() {
|
|
321
321
|
this.dependencies.clear();
|
|
322
322
|
this.dependencyList = [];
|
|
323
323
|
this.exposes = [];
|
|
324
|
-
this.
|
|
324
|
+
this.user = undefined;
|
|
325
325
|
if (this.session) {
|
|
326
326
|
this.session.properties = [];
|
|
327
327
|
}
|
|
@@ -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 } from '../models/kinds.js'\nimport { type IThing, Thing } from '../models/Thing.js'\nimport type {\n AccessRule,\n AuthenticationConfiguration,\n AuthorizationConfiguration,\n ExposedEntity,\n RateLimitingConfiguration,\n RolesBasedAccessControl,\n SessionConfiguration,\n UsernamePasswordConfiguration,\n} from './types.js'\nimport { DataDomain } from './DataDomain.js'\nimport { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js'\nimport { observed, toRaw } from './observed.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 data domain 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 data domain schema.\n */\n info: IThing\n\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 userKey?: string\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: ExposedEntity[]\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?: AccessRule[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n rateLimiting?: RateLimitingConfiguration\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 userKey?: string\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: 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 accessRule?: AccessRule[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n rateLimiting?: RateLimitingConfiguration\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.userKey) {\n result.userKey = input.userKey\n }\n if (input.dependencyList) {\n result.dependencyList = structuredClone(input.dependencyList)\n }\n if (input.authentication) {\n result.authentication = input.authentication\n }\n if (input.authorization) {\n result.authorization = input.authorization\n }\n if (input.session) {\n result.session = input.session\n }\n if (input.accessRule) {\n result.accessRule = input.accessRule\n }\n if (input.rateLimiting) {\n result.rateLimiting = 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 super(init.dependencyList, instances)\n this.kind = init.kind\n this.key = init.key\n this.info = new Thing(init.info)\n this.userKey = init.userKey\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 = structuredClone(init.exposes)\n } else {\n this.exposes = []\n }\n if (init.accessRule) {\n this.accessRule = structuredClone(init.accessRule)\n }\n if (init.rateLimiting) {\n this.rateLimiting = structuredClone(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: structuredClone(this.exposes),\n }\n if (this.userKey) {\n result.userKey = this.userKey\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 (this.accessRule) {\n result.accessRule = structuredClone(this.accessRule)\n }\n if (this.rateLimiting) {\n result.rateLimiting = structuredClone(this.rateLimiting)\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 * @param entityKey The key of the entity to expose.\n * @returns The exposed entity.\n */\n exposeEntity(entityKey: string): ExposedEntity {\n const existing = this.exposes.find((e) => e.key === entityKey)\n if (existing) {\n return existing\n }\n const newEntity: ExposedEntity = {\n key: entityKey,\n actions: [],\n }\n this.exposes.push(newEntity)\n this.notifyChange()\n return newEntity\n }\n\n /**\n * Removes an entity from the API model.\n * @param entityKey The key of the entity to remove.\n */\n removeEntity(entityKey: string): void {\n const index = this.exposes.findIndex((e) => e.key === entityKey)\n if (index !== -1) {\n this.exposes.splice(index, 1)\n this.notifyChange()\n }\n }\n /**\n * Returns the exposed entity by its key.\n * @param entityKey The key of the entity to find.\n * @returns The exposed entity or undefined if not found.\n */\n getExposedEntity(entityKey: string): ExposedEntity | undefined {\n return this.exposes.find((e) => e.key === entityKey)\n }\n\n /**\n * Clears the API model for a new entity change.\n * This method resets the dependencies, exposes, userKey,\n * authentication, authorization, and session properties.\n */\n cleanForEntityChange(): void {\n this.dependencies.clear()\n this.dependencyList = []\n this.exposes = []\n this.userKey = 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.cleanForEntityChange()\n this.dependencies.set(domain.key, domain)\n this.dependencyList = [{ key: domain.key, version: domain.info.version }]\n this.notifyChange()\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ApiModel.js","sourceRoot":"","sources":["../../../src/modeling/ApiModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { nanoid } from '../nanoid.js'\nimport { ApiModelKind, DataDomainKind } from '../models/kinds.js'\nimport { type IThing, Thing } from '../models/Thing.js'\nimport type {\n AccessRule,\n AssociationTarget,\n AuthenticationConfiguration,\n AuthorizationConfiguration,\n ExposedEntity,\n RateLimitingConfiguration,\n RolesBasedAccessControl,\n SessionConfiguration,\n UsernamePasswordConfiguration,\n} from './types.js'\nimport { DataDomain } from './DataDomain.js'\nimport { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js'\nimport { observed, toRaw } from './observed.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 data domain 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 data domain schema.\n */\n info: IThing\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: ExposedEntity[]\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?: AccessRule[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n rateLimiting?: RateLimitingConfiguration\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 exposes: 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 accessRule?: AccessRule[]\n /**\n * Optional configuration for API-wide rate limiting and throttling.\n * Defines rules to protect the API from overuse.\n */\n rateLimiting?: RateLimitingConfiguration\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 = { ...input.user }\n }\n if (input.dependencyList) {\n result.dependencyList = structuredClone(input.dependencyList)\n }\n if (input.authentication) {\n result.authentication = input.authentication\n }\n if (input.authorization) {\n result.authorization = input.authorization\n }\n if (input.session) {\n result.session = input.session\n }\n if (input.accessRule) {\n result.accessRule = input.accessRule\n }\n if (input.rateLimiting) {\n result.rateLimiting = 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 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 = structuredClone(init.exposes)\n } else {\n this.exposes = []\n }\n if (init.accessRule) {\n this.accessRule = structuredClone(init.accessRule)\n }\n if (init.rateLimiting) {\n this.rateLimiting = structuredClone(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: structuredClone(this.exposes),\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 (this.accessRule) {\n result.accessRule = structuredClone(this.accessRule)\n }\n if (this.rateLimiting) {\n result.rateLimiting = structuredClone(this.rateLimiting)\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 * @param entityKey The key of the entity to expose.\n * @returns The exposed entity.\n */\n exposeEntity(entityKey: string): ExposedEntity {\n const existing = this.exposes.find((e) => e.key === entityKey)\n if (existing) {\n return existing\n }\n const newEntity: ExposedEntity = {\n key: entityKey,\n actions: [],\n }\n this.exposes.push(newEntity)\n this.notifyChange()\n return newEntity\n }\n\n /**\n * Removes an entity from the API model.\n * @param entityKey The key of the entity to remove.\n */\n removeEntity(entityKey: string): void {\n const index = this.exposes.findIndex((e) => e.key === entityKey)\n if (index !== -1) {\n this.exposes.splice(index, 1)\n this.notifyChange()\n }\n }\n /**\n * Returns the exposed entity by its key.\n * @param entityKey The key of the entity to find.\n * @returns The exposed entity or undefined if not found.\n */\n getExposedEntity(entityKey: string): ExposedEntity | undefined {\n return this.exposes.find((e) => e.key === entityKey)\n }\n\n /**\n * Clears the API model for a new entity change.\n * This method resets the dependencies, exposes, user,\n * authentication, authorization, and session properties.\n */\n cleanForEntityChange(): void {\n this.dependencies.clear()\n this.dependencyList = []\n this.exposes = []\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.cleanForEntityChange()\n this.dependencies.set(domain.key, domain)\n this.dependencyList = [{ key: domain.key, version: domain.info.version }]\n this.notifyChange()\n }\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare function sanitizeInput(input: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Converts a string into a sanitized, database column friendly name.
|
|
4
|
+
* - Sanitizes the input using DOMPurify.
|
|
5
|
+
* - Converts to lowercase.
|
|
6
|
+
* - Replaces spaces and multiple underscores with a single underscore.
|
|
7
|
+
* - Removes any characters that are not alphanumeric or underscore.
|
|
8
|
+
*
|
|
9
|
+
* @param inputName The string to format.
|
|
10
|
+
* @returns A database column friendly name.
|
|
11
|
+
*/
|
|
12
|
+
export declare function toDatabaseColumnName(inputName: string, defaultName?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Converts a string into a sanitized, database table friendly name.
|
|
15
|
+
* - Sanitizes the input using DOMPurify.
|
|
16
|
+
* - Converts to lowercase.
|
|
17
|
+
* - Replaces spaces and multiple underscores with a single underscore.
|
|
18
|
+
* - Removes any characters that are not alphanumeric or underscore.
|
|
19
|
+
*
|
|
20
|
+
* @param inputName The string to format.
|
|
21
|
+
* @returns A database table friendly name.
|
|
22
|
+
*/
|
|
23
|
+
export declare function toDatabaseTableName(inputName: string, defaultName?: string): string;
|
|
24
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/modeling/helpers/database.ts"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAoB,GAAG,MAAM,CAiB/F;AACD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAmB,GAAG,MAAM,CAE7F"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import DOMPurify from 'isomorphic-dompurify';
|
|
2
|
+
import { snakeCase } from '@pawel-up/jexl/string.js';
|
|
3
|
+
export function sanitizeInput(input) {
|
|
4
|
+
return DOMPurify.isSupported ? DOMPurify.sanitize(input) : input;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Converts a string into a sanitized, database column friendly name.
|
|
8
|
+
* - Sanitizes the input using DOMPurify.
|
|
9
|
+
* - Converts to lowercase.
|
|
10
|
+
* - Replaces spaces and multiple underscores with a single underscore.
|
|
11
|
+
* - Removes any characters that are not alphanumeric or underscore.
|
|
12
|
+
*
|
|
13
|
+
* @param inputName The string to format.
|
|
14
|
+
* @returns A database column friendly name.
|
|
15
|
+
*/
|
|
16
|
+
export function toDatabaseColumnName(inputName, defaultName = 'untitled_column') {
|
|
17
|
+
// 1. Sanitize
|
|
18
|
+
let name = sanitizeInput(inputName);
|
|
19
|
+
// 2. Convert to lowercase
|
|
20
|
+
name = snakeCase(name);
|
|
21
|
+
// 3. Replace spaces and multiple hyphens/underscores with a single underscore
|
|
22
|
+
name = name.replace(/[\s-]+/g, '_');
|
|
23
|
+
// 4. Remove any characters that are not alphanumeric or underscore
|
|
24
|
+
name = name.replace(/[^a-z0-9_]/g, '');
|
|
25
|
+
// 5. Ensure it doesn't start or end with an underscore (optional, but good practice)
|
|
26
|
+
name = name.replace(/^_+|_+$/g, '');
|
|
27
|
+
return name || defaultName;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Converts a string into a sanitized, database table friendly name.
|
|
31
|
+
* - Sanitizes the input using DOMPurify.
|
|
32
|
+
* - Converts to lowercase.
|
|
33
|
+
* - Replaces spaces and multiple underscores with a single underscore.
|
|
34
|
+
* - Removes any characters that are not alphanumeric or underscore.
|
|
35
|
+
*
|
|
36
|
+
* @param inputName The string to format.
|
|
37
|
+
* @returns A database table friendly name.
|
|
38
|
+
*/
|
|
39
|
+
export function toDatabaseTableName(inputName, defaultName = 'untitled_table') {
|
|
40
|
+
return toDatabaseColumnName(inputName, defaultName);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../../src/modeling/helpers/database.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEpD,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAClE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,WAAW,GAAG,iBAAiB;IACrF,cAAc;IACd,IAAI,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;IAEnC,0BAA0B;IAC1B,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAEtB,8EAA8E;IAC9E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;IAEnC,mEAAmE;IACnE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IAEtC,qFAAqF;IACrF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAEnC,OAAO,IAAI,IAAI,WAAW,CAAA;AAC5B,CAAC;AACD;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,WAAW,GAAG,gBAAgB;IACnF,OAAO,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;AACrD,CAAC","sourcesContent":["import DOMPurify from 'isomorphic-dompurify'\nimport { snakeCase } from '@pawel-up/jexl/string.js'\n\nexport function sanitizeInput(input: string): string {\n return DOMPurify.isSupported ? DOMPurify.sanitize(input) : input\n}\n\n/**\n * Converts a string into a sanitized, database column friendly name.\n * - Sanitizes the input using DOMPurify.\n * - Converts to lowercase.\n * - Replaces spaces and multiple underscores with a single underscore.\n * - Removes any characters that are not alphanumeric or underscore.\n *\n * @param inputName The string to format.\n * @returns A database column friendly name.\n */\nexport function toDatabaseColumnName(inputName: string, defaultName = 'untitled_column'): string {\n // 1. Sanitize\n let name = sanitizeInput(inputName)\n\n // 2. Convert to lowercase\n name = snakeCase(name)\n\n // 3. Replace spaces and multiple hyphens/underscores with a single underscore\n name = name.replace(/[\\s-]+/g, '_')\n\n // 4. Remove any characters that are not alphanumeric or underscore\n name = name.replace(/[^a-z0-9_]/g, '')\n\n // 5. Ensure it doesn't start or end with an underscore (optional, but good practice)\n name = name.replace(/^_+|_+$/g, '')\n\n return name || defaultName\n}\n/**\n * Converts a string into a sanitized, database table friendly name.\n * - Sanitizes the input using DOMPurify.\n * - Converts to lowercase.\n * - Replaces spaces and multiple underscores with a single underscore.\n * - Removes any characters that are not alphanumeric or underscore.\n *\n * @param inputName The string to format.\n * @returns A database table friendly name.\n */\nexport function toDatabaseTableName(inputName: string, defaultName = 'untitled_table'): string {\n return toDatabaseColumnName(inputName, defaultName)\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type CSVOptions, type ParseResult } from '@pawel-up/csv';
|
|
2
|
+
import type { DataDomain } from '../DataDomain.js';
|
|
3
|
+
export type { CSVOptions, ParseResult };
|
|
4
|
+
/**
|
|
5
|
+
* Imports CSV data into a DataDomain.
|
|
6
|
+
*
|
|
7
|
+
* This class parses CSV files and translates the column definitions into DomainProperty instances
|
|
8
|
+
* within a specified DomainModel and DomainEntity.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CsvImporter {
|
|
11
|
+
private parser;
|
|
12
|
+
private domain;
|
|
13
|
+
/**
|
|
14
|
+
* Creates an instance of CsvImporter.
|
|
15
|
+
* @param domain The DataDomain to which the imported data will be added.
|
|
16
|
+
* @param options Optional CSV parsing options.
|
|
17
|
+
*/
|
|
18
|
+
constructor(domain: DataDomain, options?: CSVOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Parses a CSV file or string to extract its structure and data.
|
|
21
|
+
* This is a wrapper around the underlying CSV parser.
|
|
22
|
+
* @param csv The CSV content to parse, as a File object or a string.
|
|
23
|
+
* @returns A promise that resolves with the parsed result.
|
|
24
|
+
*/
|
|
25
|
+
parse(csv: File | string): Promise<ParseResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Imports the parsed CSV data structure into the domain as a new model and entity.
|
|
28
|
+
* It creates a `DomainEntity` where each column from the CSV is represented as a `DomainProperty`.
|
|
29
|
+
* The first row of data is used to provide an example value for each property.
|
|
30
|
+
* @param data The result from the `parse` method, containing the CSV structure and values.
|
|
31
|
+
* @param modelName The name to be used for the created `DomainModel` and `DomainEntity`.
|
|
32
|
+
* @returns A promise that resolves when the import is complete.
|
|
33
|
+
*/
|
|
34
|
+
import(data: ParseResult, modelName: string): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=CsvImporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CsvImporter.d.ts","sourceRoot":"","sources":["../../../../src/modeling/importers/CsvImporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAa,KAAK,WAAW,EAAE,MAAM,eAAe,CAAA;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAIlD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,CAAA;AAEvC;;;;;GAKG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,MAAM,CAAY;IAE1B;;;;OAIG;gBACS,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU;IAKpD;;;;;OAKG;IACI,KAAK,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAItD;;;;;;;OAOG;IACU,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA0CzE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { CSVParser } from '@pawel-up/csv';
|
|
2
|
+
import { sanitizeInput, toDatabaseColumnName, toDatabaseTableName } from '../helpers/database.js';
|
|
3
|
+
/**
|
|
4
|
+
* Imports CSV data into a DataDomain.
|
|
5
|
+
*
|
|
6
|
+
* This class parses CSV files and translates the column definitions into DomainProperty instances
|
|
7
|
+
* within a specified DomainModel and DomainEntity.
|
|
8
|
+
*/
|
|
9
|
+
export class CsvImporter {
|
|
10
|
+
parser;
|
|
11
|
+
domain;
|
|
12
|
+
/**
|
|
13
|
+
* Creates an instance of CsvImporter.
|
|
14
|
+
* @param domain The DataDomain to which the imported data will be added.
|
|
15
|
+
* @param options Optional CSV parsing options.
|
|
16
|
+
*/
|
|
17
|
+
constructor(domain, options) {
|
|
18
|
+
this.parser = new CSVParser(options);
|
|
19
|
+
this.domain = domain;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parses a CSV file or string to extract its structure and data.
|
|
23
|
+
* This is a wrapper around the underlying CSV parser.
|
|
24
|
+
* @param csv The CSV content to parse, as a File object or a string.
|
|
25
|
+
* @returns A promise that resolves with the parsed result.
|
|
26
|
+
*/
|
|
27
|
+
parse(csv) {
|
|
28
|
+
return this.parser.parse(csv);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Imports the parsed CSV data structure into the domain as a new model and entity.
|
|
32
|
+
* It creates a `DomainEntity` where each column from the CSV is represented as a `DomainProperty`.
|
|
33
|
+
* The first row of data is used to provide an example value for each property.
|
|
34
|
+
* @param data The result from the `parse` method, containing the CSV structure and values.
|
|
35
|
+
* @param modelName The name to be used for the created `DomainModel` and `DomainEntity`.
|
|
36
|
+
* @returns A promise that resolves when the import is complete.
|
|
37
|
+
*/
|
|
38
|
+
async import(data, modelName) {
|
|
39
|
+
const name = toDatabaseTableName(modelName, 'imported_cvs_data');
|
|
40
|
+
const model = this.domain.addModel({ info: { name } });
|
|
41
|
+
const entity = model.addEntity({ info: { name } });
|
|
42
|
+
const sanitizedInputName = sanitizeInput(modelName);
|
|
43
|
+
if (name !== sanitizedInputName) {
|
|
44
|
+
model.info.displayName = sanitizedInputName;
|
|
45
|
+
entity.info.displayName = sanitizedInputName;
|
|
46
|
+
}
|
|
47
|
+
for (const row of data.format) {
|
|
48
|
+
const { index, name, type, format } = row;
|
|
49
|
+
const columnName = toDatabaseColumnName(name, `column_${index}`);
|
|
50
|
+
const schema = {
|
|
51
|
+
info: { name: columnName },
|
|
52
|
+
type,
|
|
53
|
+
};
|
|
54
|
+
if (format) {
|
|
55
|
+
schema.bindings = [
|
|
56
|
+
{
|
|
57
|
+
type: 'web',
|
|
58
|
+
schema: {
|
|
59
|
+
format: format === 'integer' ? 'int64' : 'double',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
const exampleRow = data.values[0];
|
|
65
|
+
if (Array.isArray(exampleRow) && exampleRow[index]) {
|
|
66
|
+
const value = exampleRow[index];
|
|
67
|
+
if (value !== undefined && value !== null) {
|
|
68
|
+
schema.schema = {
|
|
69
|
+
examples: [sanitizeInput(String(value))],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const prop = entity.addProperty(schema);
|
|
74
|
+
const sn = sanitizeInput(name);
|
|
75
|
+
if (sn !== columnName) {
|
|
76
|
+
prop.info.displayName = sn;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=CsvImporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CsvImporter.js","sourceRoot":"","sources":["../../../../src/modeling/importers/CsvImporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,SAAS,EAAoB,MAAM,eAAe,CAAA;AAE5E,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAKjG;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IACd,MAAM,CAAW;IACjB,MAAM,CAAY;IAE1B;;;;OAIG;IACH,YAAY,MAAkB,EAAE,OAAoB;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAA;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,GAAkB;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC/B,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,MAAM,CAAC,IAAiB,EAAE,SAAiB;QACtD,MAAM,IAAI,GAAG,mBAAmB,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;QAClD,MAAM,kBAAkB,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;QACnD,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,kBAAkB,CAAA;YAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,kBAAkB,CAAA;QAC9C,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;YACzC,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,EAAE,UAAU,KAAK,EAAE,CAAC,CAAA;YAChE,MAAM,MAAM,GAAkC;gBAC5C,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;gBAC1B,IAAI;aACL,CAAA;YACD,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,QAAQ,GAAG;oBAChB;wBACE,IAAI,EAAE,KAAK;wBACX,MAAM,EAAE;4BACN,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;yBAClD;qBACF;iBACF,CAAA;YACH,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YACjC,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;gBAC/B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBAC1C,MAAM,CAAC,MAAM,GAAG;wBACd,QAAQ,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;qBACzC,CAAA;gBACH,CAAC;YACH,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YACvC,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;YAC9B,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;gBACtB,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAA;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;CACF","sourcesContent":["import { type CSVOptions, CSVParser, type ParseResult } from '@pawel-up/csv'\nimport type { DataDomain } from '../DataDomain.js'\nimport { sanitizeInput, toDatabaseColumnName, toDatabaseTableName } from '../helpers/database.js'\nimport type { DomainPropertySchema } from '../DomainProperty.js'\n\nexport type { CSVOptions, ParseResult }\n\n/**\n * Imports CSV data into a DataDomain.\n *\n * This class parses CSV files and translates the column definitions into DomainProperty instances\n * within a specified DomainModel and DomainEntity.\n */\nexport class CsvImporter {\n private parser: CSVParser\n private domain: DataDomain\n\n /**\n * Creates an instance of CsvImporter.\n * @param domain The DataDomain to which the imported data will be added.\n * @param options Optional CSV parsing options.\n */\n constructor(domain: DataDomain, options?: CSVOptions) {\n this.parser = new CSVParser(options)\n this.domain = domain\n }\n\n /**\n * Parses a CSV file or string to extract its structure and data.\n * This is a wrapper around the underlying CSV parser.\n * @param csv The CSV content to parse, as a File object or a string.\n * @returns A promise that resolves with the parsed result.\n */\n public parse(csv: File | string): Promise<ParseResult> {\n return this.parser.parse(csv)\n }\n\n /**\n * Imports the parsed CSV data structure into the domain as a new model and entity.\n * It creates a `DomainEntity` where each column from the CSV is represented as a `DomainProperty`.\n * The first row of data is used to provide an example value for each property.\n * @param data The result from the `parse` method, containing the CSV structure and values.\n * @param modelName The name to be used for the created `DomainModel` and `DomainEntity`.\n * @returns A promise that resolves when the import is complete.\n */\n public async import(data: ParseResult, modelName: string): Promise<void> {\n const name = toDatabaseTableName(modelName, 'imported_cvs_data')\n const model = this.domain.addModel({ info: { name } })\n const entity = model.addEntity({ info: { name } })\n const sanitizedInputName = sanitizeInput(modelName)\n if (name !== sanitizedInputName) {\n model.info.displayName = sanitizedInputName\n entity.info.displayName = sanitizedInputName\n }\n for (const row of data.format) {\n const { index, name, type, format } = row\n const columnName = toDatabaseColumnName(name, `column_${index}`)\n const schema: Partial<DomainPropertySchema> = {\n info: { name: columnName },\n type,\n }\n if (format) {\n schema.bindings = [\n {\n type: 'web',\n schema: {\n format: format === 'integer' ? 'int64' : 'double',\n },\n },\n ]\n }\n const exampleRow = data.values[0]\n if (Array.isArray(exampleRow) && exampleRow[index]) {\n const value = exampleRow[index]\n if (value !== undefined && value !== null) {\n schema.schema = {\n examples: [sanitizeInput(String(value))],\n }\n }\n }\n const prop = entity.addProperty(schema)\n const sn = sanitizeInput(name)\n if (sn !== columnName) {\n prop.info.displayName = sn\n }\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Exception } from '../../exceptions/exception.js';
|
|
2
|
+
/**
|
|
3
|
+
* An exception thrown during the JSON Schema import process when an
|
|
4
|
+
* unrecoverable error occurs.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ImporterException extends Exception {
|
|
7
|
+
static code: string;
|
|
8
|
+
static status: number;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ImporterException.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImporterException.d.ts","sourceRoot":"","sources":["../../../../src/modeling/importers/ImporterException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAEzD;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC9C,OAAgB,IAAI,SAAuB;IAC3C,OAAgB,MAAM,SAAM;CAC7B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Exception } from '../../exceptions/exception.js';
|
|
2
|
+
/**
|
|
3
|
+
* An exception thrown during the JSON Schema import process when an
|
|
4
|
+
* unrecoverable error occurs.
|
|
5
|
+
*/
|
|
6
|
+
export class ImporterException extends Exception {
|
|
7
|
+
static code = 'E_IMPORTER_FAILURE';
|
|
8
|
+
static status = 400; // Bad Request, as it's likely due to invalid input schemas
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ImporterException.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImporterException.js","sourceRoot":"","sources":["../../../../src/modeling/importers/ImporterException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAEzD;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IAC9C,MAAM,CAAU,IAAI,GAAG,oBAAoB,CAAA;IAC3C,MAAM,CAAU,MAAM,GAAG,GAAG,CAAA,CAAC,2DAA2D","sourcesContent":["import { Exception } from '../../exceptions/exception.js'\n\n/**\n * An exception thrown during the JSON Schema import process when an\n * unrecoverable error occurs.\n */\nexport class ImporterException extends Exception {\n static override code = 'E_IMPORTER_FAILURE'\n static override status = 400 // Bad Request, as it's likely due to invalid input schemas\n}\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { JSONSchema7 } from 'json-schema';
|
|
2
|
+
import { DataDomain } from '../DataDomain.js';
|
|
3
|
+
import { DomainModel } from '../DomainModel.js';
|
|
4
|
+
/**
|
|
5
|
+
* Represents a single message (info, warning, or error) generated during the import process.
|
|
6
|
+
*/
|
|
7
|
+
export interface ImportMessage {
|
|
8
|
+
level: 'warning' | 'info';
|
|
9
|
+
message: string;
|
|
10
|
+
location?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A report containing the result of the import process, including the created model
|
|
14
|
+
* and any non-blocking messages.
|
|
15
|
+
*/
|
|
16
|
+
export interface JsonImportReport {
|
|
17
|
+
/**
|
|
18
|
+
* An array of messages generated during the import process.
|
|
19
|
+
* These can include warnings, info messages, or other non-blocking notifications.
|
|
20
|
+
*/
|
|
21
|
+
messages: ImportMessage[];
|
|
22
|
+
/**
|
|
23
|
+
* The model that was created during the import.
|
|
24
|
+
*/
|
|
25
|
+
model: DomainModel;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A structure to hold in-memory JSON schema files for browser-based import.
|
|
29
|
+
*/
|
|
30
|
+
export interface InMemorySchema {
|
|
31
|
+
/** A virtual path or identifier for the schema, used in `$ref` values. */
|
|
32
|
+
path: string;
|
|
33
|
+
/** The parsed content of the JSON schema file. */
|
|
34
|
+
contents: JSONSchema7;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Imports JSON Schema definitions into a DataDomain.
|
|
38
|
+
*
|
|
39
|
+
* This class parses a root JSON Schema file, bundles all its dependencies,
|
|
40
|
+
* and translates the object definitions into DomainEntity instances within a specified DomainModel.
|
|
41
|
+
*/
|
|
42
|
+
export declare class JsonSchemaImporter {
|
|
43
|
+
private domain;
|
|
44
|
+
private model;
|
|
45
|
+
private refMap;
|
|
46
|
+
private messages;
|
|
47
|
+
private enums;
|
|
48
|
+
constructor(domain: DataDomain);
|
|
49
|
+
/**
|
|
50
|
+
* Resets the internal state for a new import operation.
|
|
51
|
+
*/
|
|
52
|
+
private resetState;
|
|
53
|
+
/**
|
|
54
|
+
* Centralized reporting for warnings and info messages.
|
|
55
|
+
*/
|
|
56
|
+
private report;
|
|
57
|
+
/**
|
|
58
|
+
* Main import method: orchestrates schema bundling, entity creation, and population.
|
|
59
|
+
*/
|
|
60
|
+
import(schemas: InMemorySchema[], modelName: string): Promise<JsonImportReport>;
|
|
61
|
+
private isEnum;
|
|
62
|
+
/**
|
|
63
|
+
* Resolves a schema reference from the flat definition/id maps.
|
|
64
|
+
* Supports #/definitions/..., $id, or direct path keys.
|
|
65
|
+
*/
|
|
66
|
+
private resolveSchemaRef;
|
|
67
|
+
/**
|
|
68
|
+
* Helper for entity creation, can be extended for custom logic.
|
|
69
|
+
*/
|
|
70
|
+
private createEntity;
|
|
71
|
+
/**
|
|
72
|
+
* Populates a DomainEntity with its properties, associations, and parent relationships.
|
|
73
|
+
*/
|
|
74
|
+
private populateEntity;
|
|
75
|
+
/**
|
|
76
|
+
* Processes the `allOf` keyword, which can contain references (for inheritance)
|
|
77
|
+
* or inline schemas (for composition/mixins).
|
|
78
|
+
*/
|
|
79
|
+
private processAllOf;
|
|
80
|
+
/**
|
|
81
|
+
* Recursively analyzes a schema definition to find all contained primitive types and `$ref`s.
|
|
82
|
+
* It's used to understand the nature of a property (is it a primitive, an association, or a mix).
|
|
83
|
+
*/
|
|
84
|
+
private collectTypesAndRefs;
|
|
85
|
+
/**
|
|
86
|
+
* Determines whether to create a DomainProperty or a DomainAssociation for a given schema property.
|
|
87
|
+
*/
|
|
88
|
+
private createPropertyOrAssociation;
|
|
89
|
+
/**
|
|
90
|
+
* Creates and configures a DomainProperty based on a JSON schema property definition.
|
|
91
|
+
*/
|
|
92
|
+
private createDomainProperty;
|
|
93
|
+
/**
|
|
94
|
+
* Maps a JSON Schema type to a DomainPropertyType.
|
|
95
|
+
*/
|
|
96
|
+
private mapJsonTypeToDomainType;
|
|
97
|
+
private createEnumProperty;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=JsonSchemaImporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonSchemaImporter.d.ts","sourceRoot":"","sources":["../../../../src/modeling/importers/JsonSchemaImporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAA8C,MAAM,aAAa,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQ/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,GAAG,MAAM,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB;;OAEG;IACH,KAAK,EAAE,WAAW,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,QAAQ,EAAE,WAAW,CAAA;CACtB;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,KAAK,CAAiC;gBAElC,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACH,OAAO,CAAC,UAAU;IAOlB;;OAEG;IACH,OAAO,CAAC,MAAM;IAId;;OAEG;IACU,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqE5F,OAAO,CAAC,MAAM;IAYd;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAgDpB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiD3B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAwEnC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA0D5B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAuE/B,OAAO,CAAC,kBAAkB;CA+F3B"}
|