@api-client/core 0.18.23 → 0.18.25
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/DomainEntity.d.ts +6 -1
- package/build/src/modeling/DomainEntity.d.ts.map +1 -1
- package/build/src/modeling/DomainEntity.js +24 -5
- package/build/src/modeling/DomainEntity.js.map +1 -1
- package/build/src/modeling/Semantics.d.ts +68 -0
- package/build/src/modeling/Semantics.d.ts.map +1 -1
- package/build/src/modeling/Semantics.js +217 -0
- package/build/src/modeling/Semantics.js.map +1 -1
- package/build/src/modeling/definitions/Email.d.ts +0 -4
- package/build/src/modeling/definitions/Email.d.ts.map +1 -1
- package/build/src/modeling/definitions/Email.js +1 -2
- package/build/src/modeling/definitions/Email.js.map +1 -1
- package/build/src/modeling/definitions/Password.d.ts.map +1 -1
- package/build/src/modeling/definitions/Password.js +1 -3
- package/build/src/modeling/definitions/Password.js.map +1 -1
- package/build/src/modeling/helpers/Intelisense.d.ts.map +1 -1
- package/build/src/modeling/helpers/Intelisense.js +24 -58
- package/build/src/modeling/helpers/Intelisense.js.map +1 -1
- package/build/src/modeling/helpers/database.js +2 -2
- package/build/src/modeling/helpers/database.js.map +1 -1
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.js +3 -3
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.js.map +1 -1
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.js +5 -5
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +20 -20
- package/package.json +1 -1
- package/src/modeling/DomainEntity.ts +27 -5
- package/src/modeling/Semantics.ts +254 -0
- package/src/modeling/definitions/Email.ts +1 -6
- package/src/modeling/definitions/Password.ts +1 -3
- package/src/modeling/helpers/Intelisense.ts +26 -58
- package/src/modeling/helpers/database.ts +2 -2
- package/src/modeling/templates/verticals/business-services/ecommerce-domain.ts +3 -3
- package/src/modeling/templates/verticals/technology-media/blog-domain.ts +5 -5
- package/tests/unit/modeling/definitions/email.spec.ts +0 -1
- package/tests/unit/modeling/definitions/password.spec.ts +0 -2
- package/tests/unit/modeling/domain_entity_parents.spec.ts +243 -0
- package/tests/unit/modeling/semantic-configs.spec.ts +0 -1
- package/tests/unit/modeling/semantic_runtime.spec.ts +113 -0
- package/tests/unit/modeling/semantics.spec.ts +68 -0
|
@@ -42062,7 +42062,7 @@
|
|
|
42062
42062
|
"@id": "#209"
|
|
42063
42063
|
},
|
|
42064
42064
|
{
|
|
42065
|
-
"@id": "#
|
|
42065
|
+
"@id": "#206"
|
|
42066
42066
|
},
|
|
42067
42067
|
{
|
|
42068
42068
|
"@id": "#191"
|
|
@@ -42071,13 +42071,13 @@
|
|
|
42071
42071
|
"@id": "#194"
|
|
42072
42072
|
},
|
|
42073
42073
|
{
|
|
42074
|
-
"@id": "#
|
|
42074
|
+
"@id": "#197"
|
|
42075
42075
|
},
|
|
42076
42076
|
{
|
|
42077
|
-
"@id": "#
|
|
42077
|
+
"@id": "#203"
|
|
42078
42078
|
},
|
|
42079
42079
|
{
|
|
42080
|
-
"@id": "#
|
|
42080
|
+
"@id": "#200"
|
|
42081
42081
|
},
|
|
42082
42082
|
{
|
|
42083
42083
|
"@id": "#209"
|
|
@@ -42810,15 +42810,15 @@
|
|
|
42810
42810
|
"@id": "#219"
|
|
42811
42811
|
},
|
|
42812
42812
|
{
|
|
42813
|
-
"@id": "#216"
|
|
42814
|
-
},
|
|
42815
|
-
{
|
|
42816
42813
|
"@id": "#210"
|
|
42817
42814
|
},
|
|
42818
42815
|
{
|
|
42819
42816
|
"@id": "#213"
|
|
42820
42817
|
},
|
|
42821
42818
|
{
|
|
42819
|
+
"@id": "#216"
|
|
42820
|
+
},
|
|
42821
|
+
{
|
|
42822
42822
|
"@id": "#219"
|
|
42823
42823
|
}
|
|
42824
42824
|
],
|
|
@@ -43478,7 +43478,7 @@
|
|
|
43478
43478
|
"doc:ExternalDomainElement",
|
|
43479
43479
|
"doc:DomainElement"
|
|
43480
43480
|
],
|
|
43481
|
-
"doc:raw": "
|
|
43481
|
+
"doc:raw": "class: '3'\ndescription: '150 - 300'\nnumberOfFte: 5500\nnumberOfEmployees: 5232\n",
|
|
43482
43482
|
"core:mediaType": "application/yaml",
|
|
43483
43483
|
"sourcemaps:sources": [
|
|
43484
43484
|
{
|
|
@@ -43499,7 +43499,7 @@
|
|
|
43499
43499
|
"doc:ExternalDomainElement",
|
|
43500
43500
|
"doc:DomainElement"
|
|
43501
43501
|
],
|
|
43502
|
-
"doc:raw": "
|
|
43502
|
+
"doc:raw": "code: '7487'\ndescription: 'Financial and insurance activities'\ntype: \"PRIMARY\"\nclassificationCode: 'BE_NACEBEL2008'\nactivityGroupCode: 'ABCDE'\n",
|
|
43503
43503
|
"core:mediaType": "application/yaml",
|
|
43504
43504
|
"sourcemaps:sources": [
|
|
43505
43505
|
{
|
|
@@ -43520,7 +43520,7 @@
|
|
|
43520
43520
|
"doc:ExternalDomainElement",
|
|
43521
43521
|
"doc:DomainElement"
|
|
43522
43522
|
],
|
|
43523
|
-
"doc:raw": "code: '
|
|
43523
|
+
"doc:raw": "code: 'J'\ndescription: 'Information and communication'\n",
|
|
43524
43524
|
"core:mediaType": "application/yaml",
|
|
43525
43525
|
"sourcemaps:sources": [
|
|
43526
43526
|
{
|
|
@@ -43541,7 +43541,7 @@
|
|
|
43541
43541
|
"doc:ExternalDomainElement",
|
|
43542
43542
|
"doc:DomainElement"
|
|
43543
43543
|
],
|
|
43544
|
-
"doc:raw": "
|
|
43544
|
+
"doc:raw": "countryCode: \"BE\"\ngraydonEnterpriseId: 1057155523\nregistrationId: \"0422319093\"\nvatNumber: \"BE0422319093\"\ngraydonCompanyId: \"0422319093\"\nisBranchOffice: false\n",
|
|
43545
43545
|
"core:mediaType": "application/yaml",
|
|
43546
43546
|
"sourcemaps:sources": [
|
|
43547
43547
|
{
|
|
@@ -44232,7 +44232,7 @@
|
|
|
44232
44232
|
"doc:ExternalDomainElement",
|
|
44233
44233
|
"doc:DomainElement"
|
|
44234
44234
|
],
|
|
44235
|
-
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '
|
|
44235
|
+
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '22'\nsubscriberNumber: '12.87.00'\nformatted: '+32-(0)22 000000'\n",
|
|
44236
44236
|
"core:mediaType": "application/yaml",
|
|
44237
44237
|
"sourcemaps:sources": [
|
|
44238
44238
|
{
|
|
@@ -44253,7 +44253,7 @@
|
|
|
44253
44253
|
"doc:ExternalDomainElement",
|
|
44254
44254
|
"doc:DomainElement"
|
|
44255
44255
|
],
|
|
44256
|
-
"doc:raw": "
|
|
44256
|
+
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '21'\nsubscriberNumber: '12.87.00'\nformatted: '+32-(0)21 302099'\n",
|
|
44257
44257
|
"core:mediaType": "application/yaml",
|
|
44258
44258
|
"sourcemaps:sources": [
|
|
44259
44259
|
{
|
|
@@ -44274,7 +44274,7 @@
|
|
|
44274
44274
|
"doc:ExternalDomainElement",
|
|
44275
44275
|
"doc:DomainElement"
|
|
44276
44276
|
],
|
|
44277
|
-
"doc:raw": "type: 'GENERAL'\
|
|
44277
|
+
"doc:raw": "-\n type: 'GENERAL'\n value: 'info@company.be'\n-\n type: 'IT_DEPT'\n value: 'it-service@company.be'\n",
|
|
44278
44278
|
"core:mediaType": "application/yaml",
|
|
44279
44279
|
"sourcemaps:sources": [
|
|
44280
44280
|
{
|
|
@@ -44766,22 +44766,22 @@
|
|
|
44766
44766
|
{
|
|
44767
44767
|
"@id": "#199/source-map/lexical/element_0",
|
|
44768
44768
|
"sourcemaps:element": "amf://id#199",
|
|
44769
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44769
|
+
"sourcemaps:value": "[(1,0)-(5,0)]"
|
|
44770
44770
|
},
|
|
44771
44771
|
{
|
|
44772
44772
|
"@id": "#202/source-map/lexical/element_0",
|
|
44773
44773
|
"sourcemaps:element": "amf://id#202",
|
|
44774
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44774
|
+
"sourcemaps:value": "[(1,0)-(6,0)]"
|
|
44775
44775
|
},
|
|
44776
44776
|
{
|
|
44777
44777
|
"@id": "#205/source-map/lexical/element_0",
|
|
44778
44778
|
"sourcemaps:element": "amf://id#205",
|
|
44779
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44779
|
+
"sourcemaps:value": "[(1,0)-(3,0)]"
|
|
44780
44780
|
},
|
|
44781
44781
|
{
|
|
44782
44782
|
"@id": "#208/source-map/lexical/element_0",
|
|
44783
44783
|
"sourcemaps:element": "amf://id#208",
|
|
44784
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44784
|
+
"sourcemaps:value": "[(1,0)-(7,0)]"
|
|
44785
44785
|
},
|
|
44786
44786
|
{
|
|
44787
44787
|
"@id": "#223/source-map/lexical/element_0",
|
|
@@ -45121,12 +45121,12 @@
|
|
|
45121
45121
|
{
|
|
45122
45122
|
"@id": "#215/source-map/lexical/element_0",
|
|
45123
45123
|
"sourcemaps:element": "amf://id#215",
|
|
45124
|
-
"sourcemaps:value": "[(1,0)-(
|
|
45124
|
+
"sourcemaps:value": "[(1,0)-(6,0)]"
|
|
45125
45125
|
},
|
|
45126
45126
|
{
|
|
45127
45127
|
"@id": "#218/source-map/lexical/element_0",
|
|
45128
45128
|
"sourcemaps:element": "amf://id#218",
|
|
45129
|
-
"sourcemaps:value": "[(1,0)-(
|
|
45129
|
+
"sourcemaps:value": "[(1,0)-(7,0)]"
|
|
45130
45130
|
},
|
|
45131
45131
|
{
|
|
45132
45132
|
"@id": "#221/source-map/lexical/element_0",
|
package/package.json
CHANGED
|
@@ -412,7 +412,7 @@ export class DomainEntity extends DomainElement {
|
|
|
412
412
|
* ```
|
|
413
413
|
*/
|
|
414
414
|
addParent(key: string, domain?: string): this {
|
|
415
|
-
const effectiveKey = domain
|
|
415
|
+
const effectiveKey = this.domain.buildReferenceKey(key, domain)
|
|
416
416
|
// Prevent adding self as parent
|
|
417
417
|
if (effectiveKey === this.key) {
|
|
418
418
|
const message = 'Entity cannot be a parent of itself'
|
|
@@ -486,19 +486,41 @@ export class DomainEntity extends DomainElement {
|
|
|
486
486
|
* Removes a parent from this entity.
|
|
487
487
|
*
|
|
488
488
|
* @param key The key of the parent entity to remove.
|
|
489
|
+
* @param domain Optional domain key if the parent belongs to a foreign domain.
|
|
489
490
|
* @returns `this` for chaining.
|
|
490
491
|
* @throws Error When the parent does not exist.
|
|
491
492
|
* @example
|
|
492
493
|
* ```typescript
|
|
494
|
+
* // Remove local parent
|
|
493
495
|
* entity.removeParent('baseEntity');
|
|
496
|
+
*
|
|
497
|
+
* // Remove foreign domain parent
|
|
498
|
+
* entity.removeParent('baseEntity', 'externalDomain');
|
|
494
499
|
* ```
|
|
495
500
|
*/
|
|
496
|
-
removeParent(key: string): this {
|
|
501
|
+
removeParent(key: string, domain?: string): this {
|
|
497
502
|
const { graph } = this.root
|
|
498
|
-
|
|
499
|
-
|
|
503
|
+
const effectiveKey = this.domain.buildReferenceKey(key, domain)
|
|
504
|
+
|
|
505
|
+
if (!graph.hasEdge(this.key, effectiveKey)) {
|
|
506
|
+
let message = `Trying to remove a parent ${key} from ${this.key}, but it doesn't exist`
|
|
507
|
+
if (domain) {
|
|
508
|
+
message = `Trying to remove a foreign parent ${key} from domain "${domain}" from ${this.key}, but it doesn't exist`
|
|
509
|
+
}
|
|
510
|
+
throw new Error(message)
|
|
500
511
|
}
|
|
501
|
-
|
|
512
|
+
|
|
513
|
+
// Verify it's actually a parent edge
|
|
514
|
+
const edge = graph.edge(this.key, effectiveKey)
|
|
515
|
+
if (!edge || edge.type !== 'parent') {
|
|
516
|
+
let message = `Edge between ${this.key} and ${key} exists but is not a parent relationship`
|
|
517
|
+
if (domain) {
|
|
518
|
+
message = `Edge between ${this.key} and ${key} in domain "${domain}" exists but is not a parent relationship`
|
|
519
|
+
}
|
|
520
|
+
throw new Error(message)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
graph.removeEdge(this.key, effectiveKey)
|
|
502
524
|
this.root.notifyChange()
|
|
503
525
|
return this
|
|
504
526
|
}
|
|
@@ -270,6 +270,65 @@ export enum SemanticCategory {
|
|
|
270
270
|
Computed = 'Computed Values',
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Defines when a semantic should execute in relation to database operations.
|
|
275
|
+
*/
|
|
276
|
+
export enum SemanticTiming {
|
|
277
|
+
/**
|
|
278
|
+
* Execute before the database operation (validation, preprocessing)
|
|
279
|
+
*/
|
|
280
|
+
Before = 'Before',
|
|
281
|
+
/**
|
|
282
|
+
* Execute after the database operation (cleanup, notifications, derived values)
|
|
283
|
+
*/
|
|
284
|
+
After = 'After',
|
|
285
|
+
/**
|
|
286
|
+
* Execute both before and after the operation
|
|
287
|
+
*/
|
|
288
|
+
Both = 'Both',
|
|
289
|
+
/**
|
|
290
|
+
* No automatic execution (manual/on-demand only)
|
|
291
|
+
*/
|
|
292
|
+
None = 'None',
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Defines which database operations can trigger a semantic.
|
|
297
|
+
*/
|
|
298
|
+
export enum SemanticOperation {
|
|
299
|
+
Create = 'Create',
|
|
300
|
+
Read = 'Read',
|
|
301
|
+
Update = 'Update',
|
|
302
|
+
Delete = 'Delete',
|
|
303
|
+
/**
|
|
304
|
+
* Special operation for list/query operations
|
|
305
|
+
*/
|
|
306
|
+
List = 'List',
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Configuration for when and how a semantic should execute at runtime.
|
|
311
|
+
*/
|
|
312
|
+
export interface SemanticRuntimeConfig {
|
|
313
|
+
/**
|
|
314
|
+
* When the semantic should execute relative to the database operation.
|
|
315
|
+
*/
|
|
316
|
+
timing: SemanticTiming
|
|
317
|
+
/**
|
|
318
|
+
* Which database operations should trigger this semantic.
|
|
319
|
+
*/
|
|
320
|
+
operations: SemanticOperation[]
|
|
321
|
+
/**
|
|
322
|
+
* Priority order for execution when multiple semantics apply.
|
|
323
|
+
* Lower numbers execute first. Default is 100.
|
|
324
|
+
*/
|
|
325
|
+
priority?: number
|
|
326
|
+
/**
|
|
327
|
+
* Whether this semantic can be disabled at the entity/property level.
|
|
328
|
+
*/
|
|
329
|
+
canDisable?: boolean
|
|
330
|
+
}
|
|
331
|
+
|
|
273
332
|
/**
|
|
274
333
|
* A base interface for all Data Semantics, containing common properties.
|
|
275
334
|
* A semantic is an annotation applied to a Data Entity, Property, or Association
|
|
@@ -302,6 +361,10 @@ interface BaseDataSemantic {
|
|
|
302
361
|
* This is used to determine if the semantic requires additional setup or configuration.
|
|
303
362
|
*/
|
|
304
363
|
hasConfig: boolean
|
|
364
|
+
/**
|
|
365
|
+
* Runtime execution configuration for this semantic.
|
|
366
|
+
*/
|
|
367
|
+
runtime: SemanticRuntimeConfig
|
|
305
368
|
}
|
|
306
369
|
|
|
307
370
|
/**
|
|
@@ -369,6 +432,10 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
369
432
|
description: 'System users and accounts',
|
|
370
433
|
category: SemanticCategory.Identity,
|
|
371
434
|
hasConfig: false,
|
|
435
|
+
runtime: {
|
|
436
|
+
timing: SemanticTiming.None,
|
|
437
|
+
operations: [],
|
|
438
|
+
},
|
|
372
439
|
},
|
|
373
440
|
[SemanticType.Password]: {
|
|
374
441
|
id: SemanticType.Password,
|
|
@@ -378,6 +445,12 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
378
445
|
category: SemanticCategory.Identity,
|
|
379
446
|
applicableDataTypes: ['string'],
|
|
380
447
|
hasConfig: true,
|
|
448
|
+
runtime: {
|
|
449
|
+
timing: SemanticTiming.Before,
|
|
450
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
451
|
+
priority: 10, // High priority for security
|
|
452
|
+
canDisable: false, // Security semantics cannot be disabled
|
|
453
|
+
},
|
|
381
454
|
},
|
|
382
455
|
[SemanticType.UserRole]: {
|
|
383
456
|
id: SemanticType.UserRole,
|
|
@@ -387,6 +460,17 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
387
460
|
category: SemanticCategory.Identity,
|
|
388
461
|
applicableDataTypes: ['string'],
|
|
389
462
|
hasConfig: false,
|
|
463
|
+
runtime: {
|
|
464
|
+
timing: SemanticTiming.Before,
|
|
465
|
+
operations: [
|
|
466
|
+
SemanticOperation.Create,
|
|
467
|
+
SemanticOperation.Read,
|
|
468
|
+
SemanticOperation.Update,
|
|
469
|
+
SemanticOperation.Delete,
|
|
470
|
+
SemanticOperation.List,
|
|
471
|
+
],
|
|
472
|
+
priority: 20,
|
|
473
|
+
},
|
|
390
474
|
},
|
|
391
475
|
[SemanticType.ResourceOwnerIdentifier]: {
|
|
392
476
|
id: SemanticType.ResourceOwnerIdentifier,
|
|
@@ -395,6 +479,18 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
395
479
|
description: 'Links record to owner user',
|
|
396
480
|
category: SemanticCategory.Identity,
|
|
397
481
|
hasConfig: false,
|
|
482
|
+
runtime: {
|
|
483
|
+
timing: SemanticTiming.Before,
|
|
484
|
+
operations: [
|
|
485
|
+
SemanticOperation.Create,
|
|
486
|
+
SemanticOperation.Read,
|
|
487
|
+
SemanticOperation.Update,
|
|
488
|
+
SemanticOperation.Delete,
|
|
489
|
+
SemanticOperation.List,
|
|
490
|
+
],
|
|
491
|
+
priority: 5, // Very high priority for access control
|
|
492
|
+
canDisable: false,
|
|
493
|
+
},
|
|
398
494
|
},
|
|
399
495
|
|
|
400
496
|
//
|
|
@@ -409,6 +505,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
409
505
|
category: SemanticCategory.Lifecycle,
|
|
410
506
|
applicableDataTypes: ['datetime'],
|
|
411
507
|
hasConfig: false,
|
|
508
|
+
runtime: {
|
|
509
|
+
timing: SemanticTiming.Before,
|
|
510
|
+
operations: [SemanticOperation.Create],
|
|
511
|
+
priority: 90,
|
|
512
|
+
},
|
|
412
513
|
},
|
|
413
514
|
[SemanticType.UpdatedTimestamp]: {
|
|
414
515
|
id: SemanticType.UpdatedTimestamp,
|
|
@@ -418,6 +519,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
418
519
|
category: SemanticCategory.Lifecycle,
|
|
419
520
|
applicableDataTypes: ['datetime'],
|
|
420
521
|
hasConfig: false,
|
|
522
|
+
runtime: {
|
|
523
|
+
timing: SemanticTiming.Before,
|
|
524
|
+
operations: [SemanticOperation.Update],
|
|
525
|
+
priority: 90,
|
|
526
|
+
},
|
|
421
527
|
},
|
|
422
528
|
[SemanticType.DeletedTimestamp]: {
|
|
423
529
|
id: SemanticType.DeletedTimestamp,
|
|
@@ -427,6 +533,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
427
533
|
category: SemanticCategory.Lifecycle,
|
|
428
534
|
applicableDataTypes: ['datetime'],
|
|
429
535
|
hasConfig: false,
|
|
536
|
+
runtime: {
|
|
537
|
+
timing: SemanticTiming.Before,
|
|
538
|
+
operations: [SemanticOperation.Delete],
|
|
539
|
+
priority: 80,
|
|
540
|
+
},
|
|
430
541
|
},
|
|
431
542
|
[SemanticType.DeletedFlag]: {
|
|
432
543
|
id: SemanticType.DeletedFlag,
|
|
@@ -436,6 +547,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
436
547
|
category: SemanticCategory.Lifecycle,
|
|
437
548
|
applicableDataTypes: ['boolean'],
|
|
438
549
|
hasConfig: false,
|
|
550
|
+
runtime: {
|
|
551
|
+
timing: SemanticTiming.Before,
|
|
552
|
+
operations: [SemanticOperation.Delete, SemanticOperation.Read, SemanticOperation.List],
|
|
553
|
+
priority: 80,
|
|
554
|
+
},
|
|
439
555
|
},
|
|
440
556
|
[SemanticType.Version]: {
|
|
441
557
|
id: SemanticType.Version,
|
|
@@ -445,6 +561,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
445
561
|
category: SemanticCategory.Lifecycle,
|
|
446
562
|
applicableDataTypes: ['number'],
|
|
447
563
|
hasConfig: false,
|
|
564
|
+
runtime: {
|
|
565
|
+
timing: SemanticTiming.Before,
|
|
566
|
+
operations: [SemanticOperation.Update],
|
|
567
|
+
priority: 85,
|
|
568
|
+
},
|
|
448
569
|
},
|
|
449
570
|
|
|
450
571
|
//
|
|
@@ -459,6 +580,10 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
459
580
|
category: SemanticCategory.Content,
|
|
460
581
|
applicableDataTypes: ['string'],
|
|
461
582
|
hasConfig: false,
|
|
583
|
+
runtime: {
|
|
584
|
+
timing: SemanticTiming.None,
|
|
585
|
+
operations: [],
|
|
586
|
+
},
|
|
462
587
|
},
|
|
463
588
|
[SemanticType.Description]: {
|
|
464
589
|
id: SemanticType.Description,
|
|
@@ -468,6 +593,10 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
468
593
|
category: SemanticCategory.Content,
|
|
469
594
|
applicableDataTypes: ['string'],
|
|
470
595
|
hasConfig: false,
|
|
596
|
+
runtime: {
|
|
597
|
+
timing: SemanticTiming.None,
|
|
598
|
+
operations: [],
|
|
599
|
+
},
|
|
471
600
|
},
|
|
472
601
|
[SemanticType.Summary]: {
|
|
473
602
|
id: SemanticType.Summary,
|
|
@@ -477,6 +606,10 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
477
606
|
category: SemanticCategory.Content,
|
|
478
607
|
applicableDataTypes: ['string'],
|
|
479
608
|
hasConfig: false,
|
|
609
|
+
runtime: {
|
|
610
|
+
timing: SemanticTiming.None,
|
|
611
|
+
operations: [],
|
|
612
|
+
},
|
|
480
613
|
},
|
|
481
614
|
[SemanticType.Markdown]: {
|
|
482
615
|
id: SemanticType.Markdown,
|
|
@@ -486,6 +619,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
486
619
|
category: SemanticCategory.Content,
|
|
487
620
|
applicableDataTypes: ['string'],
|
|
488
621
|
hasConfig: true,
|
|
622
|
+
runtime: {
|
|
623
|
+
timing: SemanticTiming.Before,
|
|
624
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
625
|
+
priority: 50, // Process before storage
|
|
626
|
+
},
|
|
489
627
|
},
|
|
490
628
|
[SemanticType.HTML]: {
|
|
491
629
|
id: SemanticType.HTML,
|
|
@@ -495,6 +633,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
495
633
|
category: SemanticCategory.Content,
|
|
496
634
|
applicableDataTypes: ['string'],
|
|
497
635
|
hasConfig: true,
|
|
636
|
+
runtime: {
|
|
637
|
+
timing: SemanticTiming.Before,
|
|
638
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
639
|
+
priority: 50, // Process before storage for sanitization
|
|
640
|
+
},
|
|
498
641
|
},
|
|
499
642
|
[SemanticType.ImageURL]: {
|
|
500
643
|
id: SemanticType.ImageURL,
|
|
@@ -504,6 +647,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
504
647
|
category: SemanticCategory.Content,
|
|
505
648
|
applicableDataTypes: ['string'],
|
|
506
649
|
hasConfig: false,
|
|
650
|
+
runtime: {
|
|
651
|
+
timing: SemanticTiming.Before,
|
|
652
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
653
|
+
priority: 60, // Validate URLs before storage
|
|
654
|
+
},
|
|
507
655
|
},
|
|
508
656
|
[SemanticType.FileURL]: {
|
|
509
657
|
id: SemanticType.FileURL,
|
|
@@ -513,6 +661,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
513
661
|
category: SemanticCategory.Content,
|
|
514
662
|
applicableDataTypes: ['string'],
|
|
515
663
|
hasConfig: false,
|
|
664
|
+
runtime: {
|
|
665
|
+
timing: SemanticTiming.Before,
|
|
666
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
667
|
+
priority: 60, // Validate URLs before storage
|
|
668
|
+
},
|
|
516
669
|
},
|
|
517
670
|
|
|
518
671
|
//
|
|
@@ -527,6 +680,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
527
680
|
category: SemanticCategory.Business,
|
|
528
681
|
applicableDataTypes: ['string'],
|
|
529
682
|
hasConfig: true,
|
|
683
|
+
runtime: {
|
|
684
|
+
timing: SemanticTiming.Both,
|
|
685
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read, SemanticOperation.List],
|
|
686
|
+
priority: 30, // Validate state transitions before, filter by state after
|
|
687
|
+
},
|
|
530
688
|
},
|
|
531
689
|
[SemanticType.Currency]: {
|
|
532
690
|
id: SemanticType.Currency,
|
|
@@ -536,6 +694,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
536
694
|
category: SemanticCategory.Business,
|
|
537
695
|
applicableDataTypes: ['number', 'string'],
|
|
538
696
|
hasConfig: true,
|
|
697
|
+
runtime: {
|
|
698
|
+
timing: SemanticTiming.Before,
|
|
699
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
700
|
+
priority: 70, // Validate currency format and precision
|
|
701
|
+
},
|
|
539
702
|
},
|
|
540
703
|
[SemanticType.SKU]: {
|
|
541
704
|
id: SemanticType.SKU,
|
|
@@ -545,6 +708,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
545
708
|
category: SemanticCategory.Business,
|
|
546
709
|
applicableDataTypes: ['string'],
|
|
547
710
|
hasConfig: true,
|
|
711
|
+
runtime: {
|
|
712
|
+
timing: SemanticTiming.Before,
|
|
713
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
714
|
+
priority: 25, // High priority for uniqueness validation
|
|
715
|
+
},
|
|
548
716
|
},
|
|
549
717
|
|
|
550
718
|
//
|
|
@@ -559,6 +727,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
559
727
|
category: SemanticCategory.Contact,
|
|
560
728
|
applicableDataTypes: ['string'],
|
|
561
729
|
hasConfig: true,
|
|
730
|
+
runtime: {
|
|
731
|
+
timing: SemanticTiming.Before,
|
|
732
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
733
|
+
priority: 40, // Validate email format
|
|
734
|
+
},
|
|
562
735
|
},
|
|
563
736
|
[SemanticType.Phone]: {
|
|
564
737
|
id: SemanticType.Phone,
|
|
@@ -568,6 +741,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
568
741
|
category: SemanticCategory.Contact,
|
|
569
742
|
applicableDataTypes: ['string'],
|
|
570
743
|
hasConfig: true,
|
|
744
|
+
runtime: {
|
|
745
|
+
timing: SemanticTiming.Before,
|
|
746
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
747
|
+
priority: 40, // Validate phone format
|
|
748
|
+
},
|
|
571
749
|
},
|
|
572
750
|
[SemanticType.URL]: {
|
|
573
751
|
id: SemanticType.URL,
|
|
@@ -577,6 +755,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
577
755
|
category: SemanticCategory.Contact,
|
|
578
756
|
applicableDataTypes: ['string'],
|
|
579
757
|
hasConfig: true,
|
|
758
|
+
runtime: {
|
|
759
|
+
timing: SemanticTiming.Before,
|
|
760
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
761
|
+
priority: 40, // Validate URL format
|
|
762
|
+
},
|
|
580
763
|
},
|
|
581
764
|
|
|
582
765
|
//
|
|
@@ -591,6 +774,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
591
774
|
category: SemanticCategory.Organization,
|
|
592
775
|
applicableDataTypes: ['string'],
|
|
593
776
|
hasConfig: true,
|
|
777
|
+
runtime: {
|
|
778
|
+
timing: SemanticTiming.Before,
|
|
779
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
780
|
+
priority: 30, // Generate slug from title, validate uniqueness
|
|
781
|
+
},
|
|
594
782
|
},
|
|
595
783
|
[SemanticType.Tags]: {
|
|
596
784
|
id: SemanticType.Tags,
|
|
@@ -599,6 +787,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
599
787
|
description: 'Enable tagging functionality',
|
|
600
788
|
category: SemanticCategory.Organization,
|
|
601
789
|
hasConfig: true,
|
|
790
|
+
runtime: {
|
|
791
|
+
timing: SemanticTiming.After,
|
|
792
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Delete],
|
|
793
|
+
priority: 200, // Process after main operation
|
|
794
|
+
},
|
|
602
795
|
},
|
|
603
796
|
[SemanticType.Categories]: {
|
|
604
797
|
id: SemanticType.Categories,
|
|
@@ -607,6 +800,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
607
800
|
description: 'Enable categorization functionality',
|
|
608
801
|
category: SemanticCategory.Organization,
|
|
609
802
|
hasConfig: true,
|
|
803
|
+
runtime: {
|
|
804
|
+
timing: SemanticTiming.After,
|
|
805
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Delete],
|
|
806
|
+
priority: 200, // Process after main operation
|
|
807
|
+
},
|
|
610
808
|
},
|
|
611
809
|
|
|
612
810
|
//
|
|
@@ -621,6 +819,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
621
819
|
category: SemanticCategory.Location,
|
|
622
820
|
applicableDataTypes: ['string'],
|
|
623
821
|
hasConfig: true,
|
|
822
|
+
runtime: {
|
|
823
|
+
timing: SemanticTiming.Both,
|
|
824
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read, SemanticOperation.List],
|
|
825
|
+
priority: 60, // Validate coordinates before, enable spatial queries after
|
|
826
|
+
},
|
|
624
827
|
},
|
|
625
828
|
|
|
626
829
|
//
|
|
@@ -636,6 +839,11 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
636
839
|
category: SemanticCategory.Computed,
|
|
637
840
|
applicableDataTypes: ['string', 'number', 'boolean', 'date', 'datetime', 'time', 'binary'],
|
|
638
841
|
hasConfig: true,
|
|
842
|
+
runtime: {
|
|
843
|
+
timing: SemanticTiming.Both,
|
|
844
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update, SemanticOperation.Read],
|
|
845
|
+
priority: 150, // Calculate after other validations, recalculate on read if needed
|
|
846
|
+
},
|
|
639
847
|
},
|
|
640
848
|
[SemanticType.Derived]: {
|
|
641
849
|
id: SemanticType.Derived,
|
|
@@ -645,9 +853,55 @@ export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
|
645
853
|
category: SemanticCategory.Computed,
|
|
646
854
|
applicableDataTypes: ['string'],
|
|
647
855
|
hasConfig: true,
|
|
856
|
+
runtime: {
|
|
857
|
+
timing: SemanticTiming.After,
|
|
858
|
+
operations: [SemanticOperation.Create, SemanticOperation.Update],
|
|
859
|
+
priority: 180, // Derive after all other processing
|
|
860
|
+
},
|
|
648
861
|
},
|
|
649
862
|
}
|
|
650
863
|
|
|
864
|
+
/**
|
|
865
|
+
* Get all semantics that should run for a specific operation and timing
|
|
866
|
+
*/
|
|
867
|
+
export function getSemanticsForOperation(
|
|
868
|
+
semantics: AppliedDataSemantic[],
|
|
869
|
+
operation: SemanticOperation,
|
|
870
|
+
timing: SemanticTiming
|
|
871
|
+
): AppliedDataSemantic[] {
|
|
872
|
+
return semantics
|
|
873
|
+
.filter((semantic) => {
|
|
874
|
+
const definition = DataSemantics[semantic.id]
|
|
875
|
+
if (!definition?.runtime) {
|
|
876
|
+
return false
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
const { timing: semanticTiming, operations } = definition.runtime
|
|
880
|
+
|
|
881
|
+
// Check if timing matches
|
|
882
|
+
const timingMatches = semanticTiming === timing || semanticTiming === SemanticTiming.Both
|
|
883
|
+
|
|
884
|
+
// Check if operation is included
|
|
885
|
+
const operationMatches = operations.includes(operation)
|
|
886
|
+
|
|
887
|
+
return timingMatches && operationMatches
|
|
888
|
+
})
|
|
889
|
+
.sort((a, b) => {
|
|
890
|
+
// Sort by priority (lower number = higher priority)
|
|
891
|
+
const priorityA = DataSemantics[a.id]?.runtime?.priority ?? 100
|
|
892
|
+
const priorityB = DataSemantics[b.id]?.runtime?.priority ?? 100
|
|
893
|
+
return priorityA - priorityB
|
|
894
|
+
})
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Check if a specific semantic can be disabled at runtime
|
|
899
|
+
*/
|
|
900
|
+
export function canSemanticBeDisabled(semanticType: SemanticType): boolean {
|
|
901
|
+
const definition = DataSemantics[semanticType]
|
|
902
|
+
return definition?.runtime?.canDisable !== false // Default to true if not specified
|
|
903
|
+
}
|
|
904
|
+
|
|
651
905
|
export function getSemanticsByCategory(): Record<SemanticCategory, DataSemantic[]>
|
|
652
906
|
export function getSemanticsByCategory(scope: SemanticScope.Entity): Record<SemanticCategory, EntitySemantic[]>
|
|
653
907
|
export function getSemanticsByCategory(scope: SemanticScope.Property): Record<SemanticCategory, PropertySemantic[]>
|
|
@@ -14,10 +14,6 @@ export interface EmailConfig {
|
|
|
14
14
|
* Whether email verification is required.
|
|
15
15
|
*/
|
|
16
16
|
requireVerification?: boolean
|
|
17
|
-
/**
|
|
18
|
-
* Method to use for verification: 'email' or 'sms'.
|
|
19
|
-
*/
|
|
20
|
-
verificationMethod?: 'email' | 'sms'
|
|
21
17
|
/**
|
|
22
18
|
* Whether to allow subaddressing (user+tag@domain.com).
|
|
23
19
|
*/
|
|
@@ -83,8 +79,7 @@ export const createEmailSemantic = (config: EmailConfig = {}): AppliedEmailSeman
|
|
|
83
79
|
* Default configuration for Email semantic.
|
|
84
80
|
*/
|
|
85
81
|
export const DEFAULT_EMAIL_CONFIG: EmailConfig = {
|
|
86
|
-
requireVerification:
|
|
87
|
-
verificationMethod: 'email',
|
|
82
|
+
requireVerification: true,
|
|
88
83
|
allowSubaddressing: true,
|
|
89
84
|
allowInternational: true,
|
|
90
85
|
}
|