@api-client/core 0.18.19 → 0.18.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/build/src/modeling/helpers/Intelisense.d.ts.map +1 -1
  2. package/build/src/modeling/helpers/Intelisense.js +1 -0
  3. package/build/src/modeling/helpers/Intelisense.js.map +1 -1
  4. package/build/src/modeling/templates/blog-domain.d.ts +2 -2
  5. package/build/src/modeling/templates/blog-domain.d.ts.map +1 -1
  6. package/build/src/modeling/templates/blog-domain.js +12 -12
  7. package/build/src/modeling/templates/blog-domain.js.map +1 -1
  8. package/build/src/modeling/templates/ecommerce-domain.d.ts +2 -2
  9. package/build/src/modeling/templates/ecommerce-domain.d.ts.map +1 -1
  10. package/build/src/modeling/templates/ecommerce-domain.js +12 -13
  11. package/build/src/modeling/templates/ecommerce-domain.js.map +1 -1
  12. package/build/src/modeling/templates/index.d.ts +20 -0
  13. package/build/src/modeling/templates/index.d.ts.map +1 -0
  14. package/build/src/modeling/templates/index.js +174 -0
  15. package/build/src/modeling/templates/index.js.map +1 -0
  16. package/build/src/modeling/templates/meta/blog-publishing-platform.json +1 -0
  17. package/build/src/modeling/templates/meta/ecommerce-platform.json +1 -0
  18. package/build/src/modeling/templates/meta/index.d.ts +56 -0
  19. package/build/src/modeling/templates/meta/index.d.ts.map +1 -0
  20. package/build/src/modeling/templates/meta/index.js +90 -0
  21. package/build/src/modeling/templates/meta/index.js.map +1 -0
  22. package/build/src/modeling/templates/template-registry.d.ts +41 -0
  23. package/build/src/modeling/templates/template-registry.d.ts.map +1 -0
  24. package/build/src/modeling/templates/template-registry.js +48 -0
  25. package/build/src/modeling/templates/template-registry.js.map +1 -0
  26. package/build/src/modeling/templates/types.d.ts +167 -0
  27. package/build/src/modeling/templates/types.d.ts.map +1 -0
  28. package/build/src/modeling/templates/types.js +2 -0
  29. package/build/src/modeling/templates/types.js.map +1 -0
  30. package/build/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +1 -1
  32. package/src/modeling/helpers/Intelisense.ts +1 -0
  33. package/src/modeling/templates/blog-domain.ts +15 -14
  34. package/src/modeling/templates/ecommerce-domain.ts +15 -15
  35. package/src/modeling/templates/meta/blog-publishing-platform.json +1 -0
  36. package/src/modeling/templates/meta/ecommerce-platform.json +1 -0
  37. package/src/modeling/templates/readme.md +246 -0
  38. package/src/modeling/templates/template-registry.ts +67 -0
  39. package/src/modeling/templates/types.ts +175 -0
  40. package/tests/unit/modeling/helpers/intellisense.spec.ts +971 -0
@@ -0,0 +1,971 @@
1
+ import { test } from '@japa/runner'
2
+ import { DataDomain, DomainEntity, DomainProperty, DomainAssociation } from '../../../../src/index.js'
3
+ import {
4
+ addAutoField,
5
+ addIdField,
6
+ addEmailField,
7
+ addPasswordField,
8
+ addVersionField,
9
+ addNameField,
10
+ addDescriptionField,
11
+ addStatusField,
12
+ addOwnerField,
13
+ addUpdatedByField,
14
+ addCreatedAtField,
15
+ addUpdatedAtField,
16
+ addDeletedAtField,
17
+ addIsDeletedField,
18
+ addFirstNameField,
19
+ addLastNameField,
20
+ addPhoneField,
21
+ addAvatarUrlField,
22
+ addPublicUniqueNameField,
23
+ addSkuField,
24
+ addPriceField,
25
+ addQuantityField,
26
+ addWeightField,
27
+ addImagesField,
28
+ addCustomStatusField,
29
+ addBooleanField,
30
+ addSessionIdField,
31
+ addExpiresAtField,
32
+ addUnitPriceField,
33
+ addCurrencyAmountField,
34
+ addRecommendedFields,
35
+ } from '../../../../src/modeling/helpers/Intelisense.js'
36
+ import { SemanticType } from '../../../../src/modeling/Semantics.js'
37
+
38
+ function createTestEntity(): DomainEntity {
39
+ const domain = new DataDomain({ key: 'test-domain', info: { name: 'Test Domain' } })
40
+ const namespace = domain.addNamespace({ info: { name: 'TestNamespace' } })
41
+ const model = namespace.addModel({ info: { name: 'TestModel' } })
42
+ return model.addEntity({ info: { name: 'TestEntity' } })
43
+ }
44
+
45
+ test.group('addAutoField()', () => {
46
+ test('throws error for unsupported auto field', ({ assert }) => {
47
+ const entity = createTestEntity()
48
+ assert.throws(() => addAutoField(entity, 'unsupported-field'), 'Unsupported auto field: unsupported-field')
49
+ })
50
+
51
+ test('adds id field when autoField is "id"', ({ assert }) => {
52
+ const entity = createTestEntity()
53
+ const field = addAutoField(entity, 'id') as DomainProperty
54
+ assert.instanceOf(field, DomainProperty)
55
+ assert.equal(field.info.name, 'id')
56
+ assert.isTrue(field.primary)
57
+ })
58
+
59
+ test('adds email field when autoField is "email"', ({ assert }) => {
60
+ const entity = createTestEntity()
61
+ const field = addAutoField(entity, 'email') as DomainProperty
62
+ assert.instanceOf(field, DomainProperty)
63
+ assert.equal(field.info.name, 'email')
64
+ assert.isTrue(field.required)
65
+ assert.isTrue(field.index)
66
+ })
67
+
68
+ test('adds name field when autoField is "name"', ({ assert }) => {
69
+ const entity = createTestEntity()
70
+ const field = addAutoField(entity, 'name') as DomainProperty
71
+ assert.instanceOf(field, DomainProperty)
72
+ assert.equal(field.info.name, 'name')
73
+ })
74
+
75
+ test('adds description field when autoField is "description"', ({ assert }) => {
76
+ const entity = createTestEntity()
77
+ const field = addAutoField(entity, 'description') as DomainProperty
78
+ assert.instanceOf(field, DomainProperty)
79
+ assert.equal(field.info.name, 'description')
80
+ })
81
+
82
+ test('adds status field when autoField is "status"', ({ assert }) => {
83
+ const entity = createTestEntity()
84
+ const field = addAutoField(entity, 'status') as DomainProperty
85
+ assert.instanceOf(field, DomainProperty)
86
+ assert.equal(field.info.name, 'status')
87
+ assert.deepEqual(field.schema?.enum, ['Active', 'Draft', 'Archived'])
88
+ })
89
+
90
+ test('adds version field when autoField is "version"', ({ assert }) => {
91
+ const entity = createTestEntity()
92
+ const field = addAutoField(entity, 'version') as DomainProperty
93
+ assert.instanceOf(field, DomainProperty)
94
+ assert.equal(field.info.name, 'version')
95
+ assert.equal(field.type, 'number')
96
+ assert.isTrue(field.readOnly)
97
+ })
98
+
99
+ test('adds owner field when autoField is "owner"', ({ assert }) => {
100
+ const entity = createTestEntity()
101
+ const field = addAutoField(entity, 'owner') as DomainAssociation
102
+ assert.instanceOf(field, DomainAssociation)
103
+ assert.equal(field.info.name, 'owner')
104
+ assert.isTrue(field.required)
105
+ })
106
+
107
+ test('adds created at field when autoField is "created"', ({ assert }) => {
108
+ const entity = createTestEntity()
109
+ const field = addAutoField(entity, 'created') as DomainProperty
110
+ assert.instanceOf(field, DomainProperty)
111
+ assert.equal(field.info.name, 'created_at')
112
+ assert.equal(field.type, 'datetime')
113
+ assert.isTrue(field.readOnly)
114
+ })
115
+
116
+ test('adds updated at field when autoField is "updated"', ({ assert }) => {
117
+ const entity = createTestEntity()
118
+ const field = addAutoField(entity, 'updated') as DomainProperty
119
+ assert.instanceOf(field, DomainProperty)
120
+ assert.equal(field.info.name, 'updated_at')
121
+ assert.equal(field.type, 'datetime')
122
+ assert.isTrue(field.readOnly)
123
+ })
124
+
125
+ test('adds updated by field when autoField is "updated-by"', ({ assert }) => {
126
+ const entity = createTestEntity()
127
+ const field = addAutoField(entity, 'updated-by') as DomainAssociation
128
+ assert.instanceOf(field, DomainAssociation)
129
+ assert.equal(field.info.name, 'updated_by')
130
+ assert.isTrue(field.required)
131
+ })
132
+
133
+ test('adds is deleted field when autoField is "is-deleted"', ({ assert }) => {
134
+ const entity = createTestEntity()
135
+ const field = addAutoField(entity, 'is-deleted') as DomainProperty
136
+ assert.instanceOf(field, DomainProperty)
137
+ assert.equal(field.info.name, 'is_deleted')
138
+ assert.equal(field.type, 'boolean')
139
+ assert.isTrue(field.readOnly)
140
+ })
141
+
142
+ test('adds deleted at field when autoField is "deleted"', ({ assert }) => {
143
+ const entity = createTestEntity()
144
+ const field = addAutoField(entity, 'deleted') as DomainProperty
145
+ assert.instanceOf(field, DomainProperty)
146
+ assert.equal(field.info.name, 'deleted_at')
147
+ assert.equal(field.type, 'datetime')
148
+ assert.isTrue(field.readOnly)
149
+ })
150
+
151
+ test('adds first name field when autoField is "first-name"', ({ assert }) => {
152
+ const entity = createTestEntity()
153
+ const field = addAutoField(entity, 'first-name') as DomainProperty
154
+ assert.instanceOf(field, DomainProperty)
155
+ assert.equal(field.info.name, 'first_name')
156
+ assert.equal(field.type, 'string')
157
+ })
158
+
159
+ test('adds last name field when autoField is "last-name"', ({ assert }) => {
160
+ const entity = createTestEntity()
161
+ const field = addAutoField(entity, 'last-name') as DomainProperty
162
+ assert.instanceOf(field, DomainProperty)
163
+ assert.equal(field.info.name, 'last_name')
164
+ assert.equal(field.type, 'string')
165
+ })
166
+
167
+ test('adds phone field when autoField is "phone"', ({ assert }) => {
168
+ const entity = createTestEntity()
169
+ const field = addAutoField(entity, 'phone') as DomainProperty
170
+ assert.instanceOf(field, DomainProperty)
171
+ assert.equal(field.info.name, 'phone')
172
+ assert.equal(field.type, 'string')
173
+ assert.isTrue(field.index)
174
+ })
175
+
176
+ test('adds avatar url field when autoField is "avatar-url"', ({ assert }) => {
177
+ const entity = createTestEntity()
178
+ const field = addAutoField(entity, 'avatar-url') as DomainProperty
179
+ assert.instanceOf(field, DomainProperty)
180
+ assert.equal(field.info.name, 'avatar_url')
181
+ assert.equal(field.type, 'string')
182
+ })
183
+
184
+ test('adds public unique name field when autoField is "public-unique-name"', ({ assert }) => {
185
+ const entity = createTestEntity()
186
+ const field = addAutoField(entity, 'public-unique-name') as DomainProperty
187
+ assert.instanceOf(field, DomainProperty)
188
+ assert.equal(field.info.name, 'slug')
189
+ assert.equal(field.type, 'string')
190
+ assert.isTrue(field.required)
191
+ assert.isTrue(field.index)
192
+ })
193
+
194
+ test('adds price field when autoField is "price"', ({ assert }) => {
195
+ const entity = createTestEntity()
196
+ const field = addAutoField(entity, 'price') as DomainProperty
197
+ assert.instanceOf(field, DomainProperty)
198
+ assert.equal(field.info.name, 'price')
199
+ assert.equal(field.type, 'number')
200
+ assert.isTrue(field.required)
201
+ })
202
+
203
+ test('adds sku field when autoField is "sku"', ({ assert }) => {
204
+ const entity = createTestEntity()
205
+ const field = addAutoField(entity, 'sku') as DomainProperty
206
+ assert.instanceOf(field, DomainProperty)
207
+ assert.equal(field.info.name, 'sku')
208
+ assert.equal(field.type, 'string')
209
+ assert.isTrue(field.required)
210
+ })
211
+
212
+ test('adds quantity field when autoField is "quantity"', ({ assert }) => {
213
+ const entity = createTestEntity()
214
+ const field = addAutoField(entity, 'quantity') as DomainProperty
215
+ assert.instanceOf(field, DomainProperty)
216
+ assert.equal(field.info.name, 'quantity')
217
+ assert.equal(field.type, 'number')
218
+ assert.isTrue(field.required)
219
+ })
220
+
221
+ test('adds weight field when autoField is "weight"', ({ assert }) => {
222
+ const entity = createTestEntity()
223
+ const field = addAutoField(entity, 'weight') as DomainProperty
224
+ assert.instanceOf(field, DomainProperty)
225
+ assert.equal(field.info.name, 'weight')
226
+ assert.equal(field.type, 'number')
227
+ })
228
+
229
+ test('adds images field when autoField is "images"', ({ assert }) => {
230
+ const entity = createTestEntity()
231
+ const field = addAutoField(entity, 'images') as DomainProperty
232
+ assert.instanceOf(field, DomainProperty)
233
+ assert.equal(field.info.name, 'images')
234
+ assert.equal(field.type, 'string')
235
+ assert.isTrue(field.multiple)
236
+ })
237
+
238
+ test('adds session id field when autoField is "session-id"', ({ assert }) => {
239
+ const entity = createTestEntity()
240
+ const field = addAutoField(entity, 'session-id') as DomainProperty
241
+ assert.instanceOf(field, DomainProperty)
242
+ assert.equal(field.info.name, 'sessionId')
243
+ assert.equal(field.type, 'string')
244
+ })
245
+
246
+ test('adds expires at field when autoField is "expires-at"', ({ assert }) => {
247
+ const entity = createTestEntity()
248
+ const field = addAutoField(entity, 'expires-at') as DomainProperty
249
+ assert.instanceOf(field, DomainProperty)
250
+ assert.equal(field.info.name, 'expiresAt')
251
+ assert.equal(field.type, 'datetime')
252
+ })
253
+
254
+ test('adds unit price field when autoField is "unit-price"', ({ assert }) => {
255
+ const entity = createTestEntity()
256
+ const field = addAutoField(entity, 'unit-price') as DomainProperty
257
+ assert.instanceOf(field, DomainProperty)
258
+ assert.equal(field.info.name, 'unitPrice')
259
+ assert.equal(field.type, 'number')
260
+ assert.isTrue(field.required)
261
+ })
262
+ })
263
+
264
+ test.group('addIdField()', () => {
265
+ test('creates new id field when none exists', ({ assert }) => {
266
+ const entity = createTestEntity()
267
+ const field = addIdField(entity) as DomainProperty
268
+ assert.instanceOf(field, DomainProperty)
269
+ assert.equal(field.info.name, 'id')
270
+ assert.equal(field.type, 'string')
271
+ assert.isTrue(field.primary)
272
+ assert.isTrue(field.readOnly)
273
+ assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'uuid-v4' })
274
+ })
275
+
276
+ test('returns existing id field when one exists', ({ assert }) => {
277
+ const entity = createTestEntity()
278
+ const firstField = addIdField(entity) as DomainProperty
279
+ const secondField = addIdField(entity) as DomainProperty
280
+ assert.equal(firstField, secondField)
281
+ assert.equal([...entity.properties].length, 1)
282
+ })
283
+
284
+ test('merges custom info with defaults', ({ assert }) => {
285
+ const entity = createTestEntity()
286
+ const field = addIdField(entity, { displayName: 'Unique Identifier' }) as DomainProperty
287
+ assert.equal(field.info.name, 'id')
288
+ assert.equal(field.info.displayName, 'Unique Identifier')
289
+ })
290
+ })
291
+
292
+ test.group('addEmailField()', () => {
293
+ test('creates new email field when none exists', ({ assert }) => {
294
+ const entity = createTestEntity()
295
+ const field = addEmailField(entity) as DomainProperty
296
+ assert.instanceOf(field, DomainProperty)
297
+ assert.equal(field.info.name, 'email')
298
+ assert.equal(field.info.displayName, 'Email Address')
299
+ assert.equal(field.type, 'string')
300
+ assert.isTrue(field.required)
301
+ assert.isTrue(field.index)
302
+ assert.isTrue(field.semantics.length > 0)
303
+ })
304
+
305
+ test('returns existing email field when one exists', ({ assert }) => {
306
+ const entity = createTestEntity()
307
+ const firstField = addEmailField(entity) as DomainProperty
308
+ const secondField = addEmailField(entity) as DomainProperty
309
+ assert.equal(firstField, secondField)
310
+ assert.lengthOf([...entity.properties], 1)
311
+ })
312
+
313
+ test('merges custom info with defaults', ({ assert }) => {
314
+ const entity = createTestEntity()
315
+ const field = addEmailField(entity, { description: 'User email address' }) as DomainProperty
316
+ assert.equal(field.info.name, 'email')
317
+ assert.equal(field.info.description, 'User email address')
318
+ })
319
+ })
320
+
321
+ test.group('addPasswordField()', () => {
322
+ test('creates new password field when none exists', ({ assert }) => {
323
+ const entity = createTestEntity()
324
+ const field = addPasswordField(entity) as DomainProperty
325
+ assert.instanceOf(field, DomainProperty)
326
+ assert.equal(field.info.name, 'password')
327
+ assert.equal(field.info.displayName, 'Password')
328
+ assert.equal(field.type, 'string')
329
+ assert.isTrue(field.required)
330
+ assert.isTrue(field.semantics.length > 0)
331
+ })
332
+
333
+ test('returns existing password field when one exists', ({ assert }) => {
334
+ const entity = createTestEntity()
335
+ const firstField = addPasswordField(entity) as DomainProperty
336
+ const secondField = addPasswordField(entity) as DomainProperty
337
+ assert.equal(firstField, secondField)
338
+ assert.lengthOf([...entity.properties], 1)
339
+ })
340
+
341
+ test('merges custom info with defaults', ({ assert }) => {
342
+ const entity = createTestEntity()
343
+ const field = addPasswordField(entity, { description: 'User password hash' }) as DomainProperty
344
+ assert.equal(field.info.name, 'password')
345
+ assert.equal(field.info.description, 'User password hash')
346
+ })
347
+ })
348
+
349
+ test.group('addVersionField()', () => {
350
+ test('creates new version field when none exists', ({ assert }) => {
351
+ const entity = createTestEntity()
352
+ const field = addVersionField(entity) as DomainProperty
353
+ assert.instanceOf(field, DomainProperty)
354
+ assert.equal(field.info.name, 'version')
355
+ assert.equal(field.info.displayName, 'Version')
356
+ assert.equal(field.type, 'number')
357
+ assert.isTrue(field.readOnly)
358
+ assert.isTrue(field.index)
359
+ assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'incremental' })
360
+ assert.equal(field.schema?.minimum, 0)
361
+ })
362
+
363
+ test('returns existing version field when one exists', ({ assert }) => {
364
+ const entity = createTestEntity()
365
+ const firstField = addVersionField(entity) as DomainProperty
366
+ const secondField = addVersionField(entity) as DomainProperty
367
+ assert.equal(firstField, secondField)
368
+ assert.lengthOf([...entity.properties], 1)
369
+ })
370
+
371
+ test('adds semantic annotation', ({ assert }) => {
372
+ const entity = createTestEntity()
373
+ const field = addVersionField(entity) as DomainProperty
374
+ const hasSemantic = field.hasSemantic(SemanticType.Version)
375
+ assert.isTrue(hasSemantic)
376
+ })
377
+ })
378
+
379
+ test.group('addNameField()', () => {
380
+ test('creates new name field when none exists', ({ assert }) => {
381
+ const entity = createTestEntity()
382
+ const field = addNameField(entity) as DomainProperty
383
+ assert.instanceOf(field, DomainProperty)
384
+ assert.equal(field.info.name, 'name')
385
+ assert.equal(field.info.displayName, 'Name')
386
+ assert.equal(field.type, 'string')
387
+ })
388
+
389
+ test('returns existing name field when one exists', ({ assert }) => {
390
+ const entity = createTestEntity()
391
+ const firstField = addNameField(entity) as DomainProperty
392
+ const secondField = addNameField(entity) as DomainProperty
393
+ assert.equal(firstField, secondField)
394
+ assert.lengthOf([...entity.properties], 1)
395
+ })
396
+
397
+ test('adds semantic annotation', ({ assert }) => {
398
+ const entity = createTestEntity()
399
+ const field = addNameField(entity) as DomainProperty
400
+ const hasSemantic = field.hasSemantic(SemanticType.Title)
401
+ assert.isTrue(hasSemantic)
402
+ })
403
+ })
404
+
405
+ test.group('addDescriptionField()', () => {
406
+ test('creates new description field when none exists', ({ assert }) => {
407
+ const entity = createTestEntity()
408
+ const field = addDescriptionField(entity) as DomainProperty
409
+ assert.instanceOf(field, DomainProperty)
410
+ assert.equal(field.info.name, 'description')
411
+ assert.equal(field.info.displayName, 'Description')
412
+ assert.equal(field.type, 'string')
413
+ assert.isTrue(field.semantics.length > 0)
414
+ })
415
+
416
+ test('returns existing description field when one exists', ({ assert }) => {
417
+ const entity = createTestEntity()
418
+ const firstField = addDescriptionField(entity) as DomainProperty
419
+ const secondField = addDescriptionField(entity) as DomainProperty
420
+ assert.equal(firstField, secondField)
421
+ assert.lengthOf([...entity.properties], 1)
422
+ })
423
+ })
424
+
425
+ test.group('addStatusField()', () => {
426
+ test('creates new status field when none exists', ({ assert }) => {
427
+ const entity = createTestEntity()
428
+ const field = addStatusField(entity) as DomainProperty
429
+ assert.instanceOf(field, DomainProperty)
430
+ assert.equal(field.info.name, 'status')
431
+ assert.equal(field.info.displayName, 'Status')
432
+ assert.equal(field.type, 'string')
433
+ assert.deepEqual(field.schema?.enum, ['Active', 'Draft', 'Archived'])
434
+ assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'Draft' })
435
+ })
436
+
437
+ test('returns existing status field when one exists', ({ assert }) => {
438
+ const entity = createTestEntity()
439
+ const firstField = addStatusField(entity) as DomainProperty
440
+ const secondField = addStatusField(entity) as DomainProperty
441
+ assert.equal(firstField, secondField)
442
+ assert.lengthOf([...entity.properties], 1)
443
+ })
444
+
445
+ test('adds semantic annotation', ({ assert }) => {
446
+ const entity = createTestEntity()
447
+ const field = addStatusField(entity) as DomainProperty
448
+ const hasSemantic = field.hasSemantic(SemanticType.Status)
449
+ assert.isTrue(hasSemantic)
450
+ })
451
+ })
452
+
453
+ test.group('addOwnerField()', () => {
454
+ test('creates new owner association when none exists', ({ assert }) => {
455
+ const entity = createTestEntity()
456
+ const field = addOwnerField(entity) as DomainAssociation
457
+ assert.instanceOf(field, DomainAssociation)
458
+ assert.equal(field.info.name, 'owner')
459
+ assert.equal(field.info.displayName, 'Owner')
460
+ assert.isTrue(field.required)
461
+ })
462
+
463
+ test('returns existing owner field when one exists', ({ assert }) => {
464
+ const entity = createTestEntity()
465
+ const firstField = addOwnerField(entity)
466
+ const secondField = addOwnerField(entity)
467
+ assert.equal(firstField, secondField)
468
+ assert.lengthOf([...entity.associations], 1)
469
+ })
470
+
471
+ test('adds semantic annotation', ({ assert }) => {
472
+ const entity = createTestEntity()
473
+ const field = addOwnerField(entity)
474
+ const hasSemantic = field.hasSemantic(SemanticType.ResourceOwnerIdentifier)
475
+ assert.isTrue(hasSemantic)
476
+ })
477
+ })
478
+
479
+ test.group('addUpdatedByField()', () => {
480
+ test('creates new updated by association when none exists', ({ assert }) => {
481
+ const entity = createTestEntity()
482
+ const field = addUpdatedByField(entity)
483
+ assert.instanceOf(field, DomainAssociation)
484
+ assert.equal(field.info.name, 'updated_by')
485
+ assert.equal(field.info.displayName, 'Updated By')
486
+ assert.isTrue(field.required)
487
+ })
488
+
489
+ test('returns existing updated by field when one exists', ({ assert }) => {
490
+ const entity = createTestEntity()
491
+ const firstField = addUpdatedByField(entity)
492
+ const secondField = addUpdatedByField(entity)
493
+ assert.equal(firstField, secondField)
494
+ assert.lengthOf([...entity.associations], 1)
495
+ })
496
+
497
+ test('adds semantic annotation', ({ assert }) => {
498
+ const entity = createTestEntity()
499
+ const field = addUpdatedByField(entity)
500
+ const hasSemantic = field.hasSemantic(SemanticType.ResourceOwnerIdentifier)
501
+ assert.isTrue(hasSemantic)
502
+ })
503
+ })
504
+
505
+ test.group('addCreatedAtField()', () => {
506
+ test('creates new created at field when none exists', ({ assert }) => {
507
+ const entity = createTestEntity()
508
+ const field = addCreatedAtField(entity)
509
+ assert.instanceOf(field, DomainProperty)
510
+ assert.equal(field.info.name, 'created_at')
511
+ assert.equal(field.info.displayName, 'Created At')
512
+ assert.equal(field.type, 'datetime')
513
+ assert.isTrue(field.readOnly)
514
+ assert.isTrue(field.index)
515
+ assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'now' })
516
+ })
517
+
518
+ test('returns existing created at field when one exists', ({ assert }) => {
519
+ const entity = createTestEntity()
520
+ const firstField = addCreatedAtField(entity)
521
+ const secondField = addCreatedAtField(entity)
522
+ assert.equal(firstField, secondField)
523
+ assert.lengthOf([...entity.properties], 1)
524
+ })
525
+ })
526
+
527
+ test.group('addUpdatedAtField()', () => {
528
+ test('creates new updated at field when none exists', ({ assert }) => {
529
+ const entity = createTestEntity()
530
+ const field = addUpdatedAtField(entity)
531
+ assert.instanceOf(field, DomainProperty)
532
+ assert.equal(field.info.name, 'updated_at')
533
+ assert.equal(field.info.displayName, 'Updated At')
534
+ assert.equal(field.type, 'datetime')
535
+ assert.isTrue(field.readOnly)
536
+ assert.isTrue(field.index)
537
+ assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'now' })
538
+ })
539
+
540
+ test('returns existing updated at field when one exists', ({ assert }) => {
541
+ const entity = createTestEntity()
542
+ const firstField = addUpdatedAtField(entity)
543
+ const secondField = addUpdatedAtField(entity)
544
+ assert.equal(firstField, secondField)
545
+ assert.lengthOf([...entity.properties], 1)
546
+ })
547
+ })
548
+
549
+ test.group('addDeletedAtField()', () => {
550
+ test('creates new deleted at field when none exists', ({ assert }) => {
551
+ const entity = createTestEntity()
552
+ const field = addDeletedAtField(entity)
553
+ assert.instanceOf(field, DomainProperty)
554
+ assert.equal(field.info.name, 'deleted_at')
555
+ assert.equal(field.info.displayName, 'Deleted At')
556
+ assert.equal(field.type, 'datetime')
557
+ assert.isTrue(field.readOnly)
558
+ assert.isTrue(field.index)
559
+ assert.deepEqual(field.schema?.defaultValue, { type: 'function', value: 'now' })
560
+ })
561
+
562
+ test('returns existing deleted at field when one exists', ({ assert }) => {
563
+ const entity = createTestEntity()
564
+ const firstField = addDeletedAtField(entity)
565
+ const secondField = addDeletedAtField(entity)
566
+ assert.equal(firstField, secondField)
567
+ assert.lengthOf([...entity.properties], 1)
568
+ })
569
+ })
570
+
571
+ test.group('addIsDeletedField()', () => {
572
+ test('creates new is deleted field when none exists', ({ assert }) => {
573
+ const entity = createTestEntity()
574
+ const field = addIsDeletedField(entity)
575
+ assert.instanceOf(field, DomainProperty)
576
+ assert.equal(field.info.name, 'is_deleted')
577
+ assert.equal(field.info.displayName, 'Is Deleted')
578
+ assert.equal(field.type, 'boolean')
579
+ assert.isTrue(field.readOnly)
580
+ assert.isTrue(field.index)
581
+ assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'false' })
582
+ })
583
+
584
+ test('returns existing is deleted field when one exists', ({ assert }) => {
585
+ const entity = createTestEntity()
586
+ const firstField = addIsDeletedField(entity)
587
+ const secondField = addIsDeletedField(entity)
588
+ assert.equal(firstField, secondField)
589
+ assert.lengthOf([...entity.properties], 1)
590
+ })
591
+ })
592
+
593
+ test.group('addFirstNameField()', () => {
594
+ test('creates new first name field when none exists', ({ assert }) => {
595
+ const entity = createTestEntity()
596
+ const field = addFirstNameField(entity)
597
+ assert.instanceOf(field, DomainProperty)
598
+ assert.equal(field.info.name, 'first_name')
599
+ assert.equal(field.info.displayName, 'First Name')
600
+ assert.equal(field.type, 'string')
601
+ })
602
+
603
+ test('returns existing first name field when one exists', ({ assert }) => {
604
+ const entity = createTestEntity()
605
+ const firstField = addFirstNameField(entity)
606
+ const secondField = addFirstNameField(entity)
607
+ assert.equal(firstField, secondField)
608
+ assert.lengthOf([...entity.properties], 1)
609
+ })
610
+ })
611
+
612
+ test.group('addLastNameField()', () => {
613
+ test('creates new last name field when none exists', ({ assert }) => {
614
+ const entity = createTestEntity()
615
+ const field = addLastNameField(entity)
616
+ assert.instanceOf(field, DomainProperty)
617
+ assert.equal(field.info.name, 'last_name')
618
+ assert.equal(field.info.displayName, 'Last Name')
619
+ assert.equal(field.type, 'string')
620
+ })
621
+
622
+ test('returns existing last name field when one exists', ({ assert }) => {
623
+ const entity = createTestEntity()
624
+ const firstField = addLastNameField(entity)
625
+ const secondField = addLastNameField(entity)
626
+ assert.equal(firstField, secondField)
627
+ assert.lengthOf([...entity.properties], 1)
628
+ })
629
+ })
630
+
631
+ test.group('addPhoneField()', () => {
632
+ test('creates new phone field when none exists', ({ assert }) => {
633
+ const entity = createTestEntity()
634
+ const field = addPhoneField(entity)
635
+ assert.instanceOf(field, DomainProperty)
636
+ assert.equal(field.info.name, 'phone')
637
+ assert.equal(field.info.displayName, 'Phone Number')
638
+ assert.equal(field.type, 'string')
639
+ assert.isTrue(field.index)
640
+ assert.isTrue(field.semantics.length > 0)
641
+ })
642
+
643
+ test('returns existing phone field when one exists', ({ assert }) => {
644
+ const entity = createTestEntity()
645
+ const firstField = addPhoneField(entity)
646
+ const secondField = addPhoneField(entity)
647
+ assert.equal(firstField, secondField)
648
+ assert.lengthOf([...entity.properties], 1)
649
+ })
650
+ })
651
+
652
+ test.group('addAvatarUrlField()', () => {
653
+ test('creates new avatar url field when none exists', ({ assert }) => {
654
+ const entity = createTestEntity()
655
+ const field = addAvatarUrlField(entity)
656
+ assert.instanceOf(field, DomainProperty)
657
+ assert.equal(field.info.name, 'avatar_url')
658
+ assert.equal(field.info.displayName, 'Avatar URL')
659
+ assert.equal(field.type, 'string')
660
+ assert.isTrue(field.semantics.length > 0)
661
+ })
662
+
663
+ test('returns existing avatar url field when one exists', ({ assert }) => {
664
+ const entity = createTestEntity()
665
+ const firstField = addAvatarUrlField(entity)
666
+ const secondField = addAvatarUrlField(entity)
667
+ assert.equal(firstField, secondField)
668
+ assert.lengthOf([...entity.properties], 1)
669
+ })
670
+ })
671
+
672
+ test.group('addPublicUniqueNameField()', () => {
673
+ test('creates new public unique name field when none exists', ({ assert }) => {
674
+ const entity = createTestEntity()
675
+ const field = addPublicUniqueNameField(entity)
676
+ assert.instanceOf(field, DomainProperty)
677
+ assert.equal(field.info.name, 'slug')
678
+ assert.equal(field.info.displayName, 'Public Unique Name')
679
+ assert.equal(field.type, 'string')
680
+ assert.isTrue(field.index)
681
+ assert.isTrue(field.required)
682
+ assert.isTrue(field.semantics.length > 0)
683
+ })
684
+
685
+ test('returns existing public unique name field when one exists', ({ assert }) => {
686
+ const entity = createTestEntity()
687
+ const firstField = addPublicUniqueNameField(entity)
688
+ const secondField = addPublicUniqueNameField(entity)
689
+ assert.equal(firstField, secondField)
690
+ assert.lengthOf([...entity.properties], 1)
691
+ })
692
+ })
693
+
694
+ test.group('addSkuField()', () => {
695
+ test('creates new sku field when none exists', ({ assert }) => {
696
+ const entity = createTestEntity()
697
+ const field = addSkuField(entity)
698
+ assert.instanceOf(field, DomainProperty)
699
+ assert.equal(field.info.name, 'sku')
700
+ assert.equal(field.info.displayName, 'SKU')
701
+ assert.equal(field.type, 'string')
702
+ assert.isTrue(field.required)
703
+ assert.isTrue(field.semantics.length > 0)
704
+ })
705
+
706
+ test('returns existing sku field when one exists', ({ assert }) => {
707
+ const entity = createTestEntity()
708
+ const firstField = addSkuField(entity)
709
+ const secondField = addSkuField(entity)
710
+ assert.equal(firstField, secondField)
711
+ assert.lengthOf([...entity.properties], 1)
712
+ })
713
+ })
714
+
715
+ test.group('addPriceField()', () => {
716
+ test('creates new price field when none exists', ({ assert }) => {
717
+ const entity = createTestEntity()
718
+ const field = addPriceField(entity)
719
+ assert.instanceOf(field, DomainProperty)
720
+ assert.equal(field.info.name, 'price')
721
+ assert.equal(field.info.displayName, 'Price')
722
+ assert.equal(field.type, 'number')
723
+ assert.isTrue(field.required)
724
+ assert.isUndefined(field.schema?.minimum)
725
+ assert.isTrue(field.semantics.length > 0)
726
+ })
727
+
728
+ test('returns existing price field when one exists', ({ assert }) => {
729
+ const entity = createTestEntity()
730
+ const firstField = addPriceField(entity)
731
+ const secondField = addPriceField(entity)
732
+ assert.equal(firstField, secondField)
733
+ assert.lengthOf([...entity.properties], 1)
734
+ })
735
+ })
736
+
737
+ test.group('addQuantityField()', () => {
738
+ test('creates new quantity field when none exists', ({ assert }) => {
739
+ const entity = createTestEntity()
740
+ const field = addQuantityField(entity)
741
+ assert.instanceOf(field, DomainProperty)
742
+ assert.equal(field.info.name, 'quantity')
743
+ assert.equal(field.info.displayName, 'Quantity')
744
+ assert.equal(field.type, 'number')
745
+ assert.isTrue(field.required)
746
+ assert.equal(field.schema?.minimum, 0)
747
+ })
748
+
749
+ test('returns existing quantity field when one exists', ({ assert }) => {
750
+ const entity = createTestEntity()
751
+ const firstField = addQuantityField(entity)
752
+ const secondField = addQuantityField(entity)
753
+ assert.equal(firstField, secondField)
754
+ assert.lengthOf([...entity.properties], 1)
755
+ })
756
+ })
757
+
758
+ test.group('addWeightField()', () => {
759
+ test('creates new weight field when none exists', ({ assert }) => {
760
+ const entity = createTestEntity()
761
+ const field = addWeightField(entity)
762
+ assert.instanceOf(field, DomainProperty)
763
+ assert.equal(field.info.name, 'weight')
764
+ assert.equal(field.info.displayName, 'Weight')
765
+ assert.equal(field.type, 'number')
766
+ })
767
+
768
+ test('returns existing weight field when one exists', ({ assert }) => {
769
+ const entity = createTestEntity()
770
+ const firstField = addWeightField(entity)
771
+ const secondField = addWeightField(entity)
772
+ assert.equal(firstField, secondField)
773
+ assert.lengthOf([...entity.properties], 1)
774
+ })
775
+ })
776
+
777
+ test.group('addImagesField()', () => {
778
+ test('creates new images field when none exists', ({ assert }) => {
779
+ const entity = createTestEntity()
780
+ const field = addImagesField(entity)
781
+ assert.instanceOf(field, DomainProperty)
782
+ assert.equal(field.info.name, 'images')
783
+ assert.equal(field.info.displayName, 'Images')
784
+ assert.equal(field.type, 'string')
785
+ assert.isTrue(field.multiple)
786
+ assert.isTrue(field.semantics.length > 0)
787
+ })
788
+
789
+ test('returns existing images field when one exists', ({ assert }) => {
790
+ const entity = createTestEntity()
791
+ const firstField = addImagesField(entity)
792
+ const secondField = addImagesField(entity)
793
+ assert.equal(firstField, secondField)
794
+ assert.lengthOf([...entity.properties], 1)
795
+ })
796
+ })
797
+
798
+ test.group('addCustomStatusField()', () => {
799
+ test('creates new custom status field with provided enum values', ({ assert }) => {
800
+ const entity = createTestEntity()
801
+ const enumValues = ['Pending', 'In Progress', 'Completed', 'Cancelled']
802
+ const field = addCustomStatusField(entity, enumValues)
803
+ assert.instanceOf(field, DomainProperty)
804
+ assert.equal(field.info.name, 'status')
805
+ assert.equal(field.info.displayName, 'Status')
806
+ assert.equal(field.type, 'string')
807
+ assert.isTrue(field.required)
808
+ assert.deepEqual(field.schema?.enum, enumValues)
809
+ assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: enumValues[0] })
810
+ })
811
+
812
+ test('returns existing status field when one exists', ({ assert }) => {
813
+ const entity = createTestEntity()
814
+ const enumValues = ['Active', 'Inactive']
815
+ const firstField = addCustomStatusField(entity, enumValues)
816
+ const secondField = addCustomStatusField(entity, ['Different', 'Values'])
817
+ assert.equal(firstField, secondField)
818
+ assert.lengthOf([...entity.properties], 1)
819
+ })
820
+ })
821
+
822
+ test.group('addBooleanField()', () => {
823
+ test('creates new boolean field with default value', ({ assert }) => {
824
+ const entity = createTestEntity()
825
+ const field = addBooleanField(entity, 'isActive')
826
+ assert.instanceOf(field, DomainProperty)
827
+ assert.equal(field.info.name, 'isActive')
828
+ assert.equal(field.type, 'boolean')
829
+ assert.isTrue(field.required)
830
+ assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'false' })
831
+ })
832
+
833
+ test('creates new boolean field with custom default value', ({ assert }) => {
834
+ const entity = createTestEntity()
835
+ const field = addBooleanField(entity, 'isEnabled', 'true')
836
+ assert.instanceOf(field, DomainProperty)
837
+ assert.equal(field.info.name, 'isEnabled')
838
+ assert.equal(field.type, 'boolean')
839
+ assert.isTrue(field.required)
840
+ assert.deepEqual(field.schema?.defaultValue, { type: 'literal', value: 'true' })
841
+ })
842
+
843
+ test('merges custom info with defaults', ({ assert }) => {
844
+ const entity = createTestEntity()
845
+ const field = addBooleanField(entity, 'isVisible', 'false', { displayName: 'Visible' })
846
+ assert.equal(field.info.name, 'isVisible')
847
+ assert.equal(field.info.displayName, 'Visible')
848
+ })
849
+ })
850
+
851
+ test.group('addSessionIdField()', () => {
852
+ test('creates new session id field when none exists', ({ assert }) => {
853
+ const entity = createTestEntity()
854
+ const field = addSessionIdField(entity)
855
+ assert.instanceOf(field, DomainProperty)
856
+ assert.equal(field.info.name, 'sessionId')
857
+ assert.equal(field.info.displayName, 'Session ID')
858
+ assert.equal(field.type, 'string')
859
+ })
860
+
861
+ test('returns existing session id field when one exists', ({ assert }) => {
862
+ const entity = createTestEntity()
863
+ const firstField = addSessionIdField(entity)
864
+ const secondField = addSessionIdField(entity)
865
+ assert.equal(firstField, secondField)
866
+ assert.lengthOf([...entity.properties], 1)
867
+ })
868
+ })
869
+
870
+ test.group('addExpiresAtField()', () => {
871
+ test('creates new expires at field when none exists', ({ assert }) => {
872
+ const entity = createTestEntity()
873
+ const field = addExpiresAtField(entity)
874
+ assert.instanceOf(field, DomainProperty)
875
+ assert.equal(field.info.name, 'expiresAt')
876
+ assert.equal(field.info.displayName, 'Expires At')
877
+ assert.equal(field.type, 'datetime')
878
+ })
879
+
880
+ test('returns existing expires at field when one exists', ({ assert }) => {
881
+ const entity = createTestEntity()
882
+ const firstField = addExpiresAtField(entity)
883
+ const secondField = addExpiresAtField(entity)
884
+ assert.equal(firstField, secondField)
885
+ assert.lengthOf([...entity.properties], 1)
886
+ })
887
+ })
888
+
889
+ test.group('addUnitPriceField()', () => {
890
+ test('creates new unit price field when none exists', ({ assert }) => {
891
+ const entity = createTestEntity()
892
+ const field = addUnitPriceField(entity)
893
+ assert.instanceOf(field, DomainProperty)
894
+ assert.equal(field.info.name, 'unitPrice')
895
+ assert.equal(field.info.displayName, 'Unit Price')
896
+ assert.equal(field.type, 'number')
897
+ assert.isTrue(field.required)
898
+ assert.isTrue(field.semantics.length > 0)
899
+ })
900
+
901
+ test('returns existing unit price field when one exists', ({ assert }) => {
902
+ const entity = createTestEntity()
903
+ const firstField = addUnitPriceField(entity)
904
+ const secondField = addUnitPriceField(entity)
905
+ assert.equal(firstField, secondField)
906
+ assert.lengthOf([...entity.properties], 1)
907
+ })
908
+ })
909
+
910
+ test.group('addCurrencyAmountField()', () => {
911
+ test('creates new currency amount field with provided parameters', ({ assert }) => {
912
+ const entity = createTestEntity()
913
+ const field = addCurrencyAmountField(entity, 'subtotal', 'Subtotal')
914
+ assert.instanceOf(field, DomainProperty)
915
+ assert.equal(field.info.name, 'subtotal')
916
+ assert.equal(field.info.displayName, 'Subtotal')
917
+ assert.equal(field.type, 'number')
918
+ assert.isTrue(field.required)
919
+ assert.isTrue(field.semantics.length > 0)
920
+ })
921
+
922
+ test('merges custom info with defaults', ({ assert }) => {
923
+ const entity = createTestEntity()
924
+ const field = addCurrencyAmountField(entity, 'tax', 'Tax Amount', { description: 'Tax calculation' })
925
+ assert.equal(field.info.name, 'tax')
926
+ assert.equal(field.info.displayName, 'Tax Amount')
927
+ assert.equal(field.info.description, 'Tax calculation')
928
+ })
929
+ })
930
+
931
+ test.group('addRecommendedFields()', () => {
932
+ test('adds multiple recommended fields to entity', ({ assert }) => {
933
+ const entity = createTestEntity()
934
+ const fields = addRecommendedFields(entity)
935
+ assert.isArray(fields)
936
+ assert.isAtLeast(fields.length, 3) // Should add at least id, created_at, updated_at
937
+
938
+ // Check that ID field was added
939
+ const idField = [...entity.properties].find((p) => p.info.name === 'id')
940
+ assert.isDefined(idField)
941
+ assert.isTrue(idField?.primary)
942
+
943
+ // Check that created_at field was added
944
+ const createdAtField = [...entity.properties].find((p) => p.info.name === 'created_at')
945
+ assert.isDefined(createdAtField)
946
+ assert.equal(createdAtField?.type, 'datetime')
947
+
948
+ // Check that updated_at field was added
949
+ const updatedAtField = [...entity.properties].find((p) => p.info.name === 'updated_at')
950
+ assert.isDefined(updatedAtField)
951
+ assert.equal(updatedAtField?.type, 'datetime')
952
+ })
953
+
954
+ test('does not add duplicate fields when recommended fields already exist', ({ assert }) => {
955
+ const entity = createTestEntity()
956
+
957
+ // Add an ID field first
958
+ addIdField(entity)
959
+ const initialFieldCount = [...entity.properties].length
960
+
961
+ // Add recommended fields
962
+ addRecommendedFields(entity)
963
+
964
+ // Should not have duplicated the ID field
965
+ const idFields = [...entity.properties].filter((p) => p.info.name === 'id')
966
+ assert.equal(idFields.length, 1)
967
+
968
+ // But should have added other recommended fields
969
+ assert.isAtLeast([...entity.properties].length, initialFieldCount + 1)
970
+ })
971
+ })