@api-client/core 0.17.3 → 0.17.5

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 (34) hide show
  1. package/build/src/modeling/Semantics.d.ts +6 -1
  2. package/build/src/modeling/Semantics.d.ts.map +1 -1
  3. package/build/src/modeling/Semantics.js +32 -4
  4. package/build/src/modeling/Semantics.js.map +1 -1
  5. package/build/src/modeling/definitions/{Price.d.ts → Currency.d.ts} +24 -24
  6. package/build/src/modeling/definitions/Currency.d.ts.map +1 -0
  7. package/build/src/modeling/definitions/{Price.js → Currency.js} +18 -18
  8. package/build/src/modeling/definitions/Currency.js.map +1 -0
  9. package/build/src/modeling/definitions/HTML.d.ts +17 -4
  10. package/build/src/modeling/definitions/HTML.d.ts.map +1 -1
  11. package/build/src/modeling/definitions/HTML.js +0 -1
  12. package/build/src/modeling/definitions/HTML.js.map +1 -1
  13. package/build/src/modeling/definitions/Markdown.d.ts +12 -4
  14. package/build/src/modeling/definitions/Markdown.d.ts.map +1 -1
  15. package/build/src/modeling/definitions/Markdown.js +0 -1
  16. package/build/src/modeling/definitions/Markdown.js.map +1 -1
  17. package/build/src/modeling/definitions/Status.d.ts +1 -1
  18. package/build/src/modeling/definitions/Status.d.ts.map +1 -1
  19. package/build/src/modeling/definitions/Status.js +1 -0
  20. package/build/src/modeling/definitions/Status.js.map +1 -1
  21. package/build/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +1 -1
  23. package/src/modeling/Semantics.ts +37 -4
  24. package/src/modeling/definitions/{Price.examples.md → Currency.examples.md} +12 -12
  25. package/src/modeling/definitions/{Price.ts → Currency.ts} +26 -26
  26. package/src/modeling/definitions/HTML.ts +17 -5
  27. package/src/modeling/definitions/Markdown.ts +12 -5
  28. package/src/modeling/definitions/Status.ts +2 -1
  29. package/tests/unit/modeling/definitions/{price.spec.ts → currency.spec.ts} +114 -114
  30. package/tests/unit/modeling/definitions/description.spec.ts +0 -2
  31. package/tests/unit/modeling/semantic-configs.spec.ts +44 -44
  32. package/tests/unit/modeling/semantics.spec.ts +10 -1
  33. package/build/src/modeling/definitions/Price.d.ts.map +0 -1
  34. package/build/src/modeling/definitions/Price.js.map +0 -1
@@ -69,12 +69,12 @@ import {
69
69
  } from '../../../src/modeling/definitions/URL.js'
70
70
 
71
71
  import {
72
- createPriceSemantic,
73
- isPriceSemantic,
74
- type PriceConfig,
75
- DEFAULT_PRICE_CONFIG,
76
- PRICE_PRESETS,
77
- } from '../../../src/modeling/definitions/Price.js'
72
+ createCurrencySemantic,
73
+ isCurrencySemantic,
74
+ type CurrencyConfig,
75
+ DEFAULT_CURRENCY_CONFIG,
76
+ CURRENCY_PRESETS,
77
+ } from '../../../src/modeling/definitions/Currency.js'
78
78
 
79
79
  import {
80
80
  createSKUSemantic,
@@ -322,27 +322,27 @@ test.group('Semantic Configurations', () => {
322
322
  assert.isTrue(isURLSemantic(semantic))
323
323
  })
324
324
 
325
- test('Price: should create semantic with default config', ({ assert }) => {
326
- const semantic = createPriceSemantic()
327
- assert.equal(semantic.id, SemanticType.Price)
328
- assert.deepEqual(semantic.config, DEFAULT_PRICE_CONFIG)
325
+ test('Currency: should create semantic with default config', ({ assert }) => {
326
+ const semantic = createCurrencySemantic()
327
+ assert.equal(semantic.id, SemanticType.Currency)
328
+ assert.deepEqual(semantic.config, DEFAULT_CURRENCY_CONFIG)
329
329
  })
330
330
 
331
- test('Price: should create semantic with custom config', ({ assert }) => {
332
- const config: PriceConfig = {
331
+ test('Currency: should create semantic with custom config', ({ assert }) => {
332
+ const config: CurrencyConfig = {
333
333
  storageFormat: 'complex_object',
334
334
  allowedCurrencies: ['USD', 'EUR'],
335
335
  decimalPlaces: 4,
336
336
  allowNegative: true,
337
337
  }
338
- const semantic = createPriceSemantic(config)
339
- assert.equal(semantic.id, SemanticType.Price)
340
- assert.deepEqual(semantic.config, { ...DEFAULT_PRICE_CONFIG, ...config })
338
+ const semantic = createCurrencySemantic(config)
339
+ assert.equal(semantic.id, SemanticType.Currency)
340
+ assert.deepEqual(semantic.config, { ...DEFAULT_CURRENCY_CONFIG, ...config })
341
341
  })
342
342
 
343
- test('Price: should identify price semantic', ({ assert }) => {
344
- const semantic = createPriceSemantic()
345
- assert.isTrue(isPriceSemantic(semantic))
343
+ test('Currency: should identify currency semantic', ({ assert }) => {
344
+ const semantic = createCurrencySemantic()
345
+ assert.isTrue(isCurrencySemantic(semantic))
346
346
  })
347
347
 
348
348
  test('SKU: should create semantic with default config', ({ assert }) => {
@@ -491,33 +491,33 @@ test.group('Semantic Configurations', () => {
491
491
  assert.isTrue(isCategoriesSemantic(semantic))
492
492
  })
493
493
 
494
- test('Price: should create semantic with default config', ({ assert }) => {
495
- const semantic = createPriceSemantic()
496
- assert.equal(semantic.id, SemanticType.Price)
497
- assert.deepEqual(semantic.config, DEFAULT_PRICE_CONFIG)
494
+ test('Currency: should create semantic with default config', ({ assert }) => {
495
+ const semantic = createCurrencySemantic()
496
+ assert.equal(semantic.id, SemanticType.Currency)
497
+ assert.deepEqual(semantic.config, DEFAULT_CURRENCY_CONFIG)
498
498
  })
499
499
 
500
- test('Price: should create semantic with custom config', ({ assert }) => {
501
- const config: PriceConfig = {
500
+ test('Currency: should create semantic with custom config', ({ assert }) => {
501
+ const config: CurrencyConfig = {
502
502
  storageFormat: 'complex_object',
503
503
  allowedCurrencies: ['USD', 'EUR'],
504
504
  decimalPlaces: 4,
505
505
  allowNegative: true,
506
506
  }
507
- const semantic = createPriceSemantic(config)
508
- assert.equal(semantic.id, SemanticType.Price)
509
- assert.deepEqual(semantic.config, { ...DEFAULT_PRICE_CONFIG, ...config })
507
+ const semantic = createCurrencySemantic(config)
508
+ assert.equal(semantic.id, SemanticType.Currency)
509
+ assert.deepEqual(semantic.config, { ...DEFAULT_CURRENCY_CONFIG, ...config })
510
510
  })
511
511
 
512
- test('Price: should identify price semantic', ({ assert }) => {
513
- const semantic = createPriceSemantic()
514
- assert.isTrue(isPriceSemantic(semantic))
512
+ test('Currency: should identify currency semantic', ({ assert }) => {
513
+ const semantic = createCurrencySemantic()
514
+ assert.isTrue(isCurrencySemantic(semantic))
515
515
  })
516
516
 
517
- test('Price: presets should be valid', ({ assert }) => {
518
- Object.values(PRICE_PRESETS).forEach((preset) => {
519
- assert.isTrue(isPriceSemantic(preset))
520
- assert.equal(preset.id, SemanticType.Price)
517
+ test('Currency: presets should be valid', ({ assert }) => {
518
+ Object.values(CURRENCY_PRESETS).forEach((preset) => {
519
+ assert.isTrue(isCurrencySemantic(preset))
520
+ assert.equal(preset.id, SemanticType.Currency)
521
521
  })
522
522
  })
523
523
 
@@ -532,38 +532,38 @@ test.group('Semantic Configurations', () => {
532
532
  const emailSemantic = createEmailSemantic()
533
533
  const phoneSemantic = createPhoneSemantic()
534
534
  const statusSemantic = createStatusSemantic()
535
- const priceSemantic = createPriceSemantic()
535
+ const currencySemantic = createCurrencySemantic()
536
536
  const skuSemantic = createSKUSemantic()
537
537
 
538
538
  // Each should only be identified as its own type
539
539
  assert.isTrue(isEmailSemantic(emailSemantic))
540
540
  assert.isFalse(isEmailSemantic(phoneSemantic))
541
541
  assert.isFalse(isEmailSemantic(statusSemantic))
542
- assert.isFalse(isEmailSemantic(priceSemantic))
542
+ assert.isFalse(isEmailSemantic(currencySemantic))
543
543
  assert.isFalse(isEmailSemantic(skuSemantic))
544
544
 
545
545
  assert.isFalse(isPhoneSemantic(emailSemantic))
546
546
  assert.isTrue(isPhoneSemantic(phoneSemantic))
547
547
  assert.isFalse(isPhoneSemantic(statusSemantic))
548
- assert.isFalse(isPhoneSemantic(priceSemantic))
548
+ assert.isFalse(isPhoneSemantic(currencySemantic))
549
549
  assert.isFalse(isPhoneSemantic(skuSemantic))
550
550
 
551
551
  assert.isFalse(isStatusSemantic(emailSemantic))
552
552
  assert.isFalse(isStatusSemantic(phoneSemantic))
553
553
  assert.isTrue(isStatusSemantic(statusSemantic))
554
- assert.isFalse(isStatusSemantic(priceSemantic))
554
+ assert.isFalse(isStatusSemantic(currencySemantic))
555
555
  assert.isFalse(isStatusSemantic(skuSemantic))
556
556
 
557
- assert.isFalse(isPriceSemantic(emailSemantic))
558
- assert.isFalse(isPriceSemantic(phoneSemantic))
559
- assert.isFalse(isPriceSemantic(statusSemantic))
560
- assert.isTrue(isPriceSemantic(priceSemantic))
561
- assert.isFalse(isPriceSemantic(skuSemantic))
557
+ assert.isFalse(isCurrencySemantic(emailSemantic))
558
+ assert.isFalse(isCurrencySemantic(phoneSemantic))
559
+ assert.isFalse(isCurrencySemantic(statusSemantic))
560
+ assert.isTrue(isCurrencySemantic(currencySemantic))
561
+ assert.isFalse(isCurrencySemantic(skuSemantic))
562
562
 
563
563
  assert.isFalse(isSKUSemantic(emailSemantic))
564
564
  assert.isFalse(isSKUSemantic(phoneSemantic))
565
565
  assert.isFalse(isSKUSemantic(statusSemantic))
566
- assert.isFalse(isSKUSemantic(priceSemantic))
566
+ assert.isFalse(isSKUSemantic(currencySemantic))
567
567
  assert.isTrue(isSKUSemantic(skuSemantic))
568
568
  })
569
569
  })
@@ -31,7 +31,7 @@ test.group('Semantics', () => {
31
31
  assert.equal(SemanticType.FileURL, 'Semantic#FileURL')
32
32
  assert.equal(SemanticType.Markdown, 'Semantic#Markdown')
33
33
  assert.equal(SemanticType.GeospatialCoordinates, 'Semantic#GeospatialCoordinates')
34
- assert.equal(SemanticType.Price, 'Semantic#Price')
34
+ assert.equal(SemanticType.Currency, 'Semantic#Currency')
35
35
  assert.equal(SemanticType.ResourceOwnerIdentifier, 'Semantic#ResourceOwnerIdentifier')
36
36
  assert.equal(SemanticType.SKU, 'Semantic#SKU')
37
37
  })
@@ -49,6 +49,7 @@ test.group('Semantics', () => {
49
49
  description: 'Test',
50
50
  scope: SemanticScope.Entity,
51
51
  category: SemanticCategory.Identity,
52
+ hasConfig: false,
52
53
  }
53
54
  const propertySemantic: PropertySemantic = {
54
55
  id: SemanticType.CreatedTimestamp,
@@ -56,6 +57,7 @@ test.group('Semantics', () => {
56
57
  description: 'Test',
57
58
  scope: SemanticScope.Property,
58
59
  category: SemanticCategory.Lifecycle,
60
+ hasConfig: false,
59
61
  }
60
62
  const associationSemantic: AssociationSemantic = {
61
63
  id: SemanticType.ResourceOwnerIdentifier,
@@ -63,6 +65,7 @@ test.group('Semantics', () => {
63
65
  description: 'Test',
64
66
  scope: SemanticScope.Association,
65
67
  category: SemanticCategory.Identity,
68
+ hasConfig: false,
66
69
  }
67
70
 
68
71
  assert.isTrue(isEntitySemantic(entitySemantic))
@@ -77,6 +80,7 @@ test.group('Semantics', () => {
77
80
  description: 'Test',
78
81
  scope: SemanticScope.Entity,
79
82
  category: SemanticCategory.Identity,
83
+ hasConfig: false,
80
84
  }
81
85
  const propertySemantic: PropertySemantic = {
82
86
  id: SemanticType.CreatedTimestamp,
@@ -84,6 +88,7 @@ test.group('Semantics', () => {
84
88
  description: 'Test',
85
89
  scope: SemanticScope.Property,
86
90
  category: SemanticCategory.Lifecycle,
91
+ hasConfig: false,
87
92
  }
88
93
  const associationSemantic: AssociationSemantic = {
89
94
  id: SemanticType.ResourceOwnerIdentifier,
@@ -91,6 +96,7 @@ test.group('Semantics', () => {
91
96
  description: 'Test',
92
97
  scope: SemanticScope.Association,
93
98
  category: SemanticCategory.Identity,
99
+ hasConfig: false,
94
100
  }
95
101
 
96
102
  assert.isFalse(isPropertySemantic(entitySemantic))
@@ -105,6 +111,7 @@ test.group('Semantics', () => {
105
111
  description: 'Test',
106
112
  scope: SemanticScope.Entity,
107
113
  category: SemanticCategory.Identity,
114
+ hasConfig: false,
108
115
  }
109
116
  const propertySemantic: PropertySemantic = {
110
117
  id: SemanticType.CreatedTimestamp,
@@ -112,6 +119,7 @@ test.group('Semantics', () => {
112
119
  description: 'Test',
113
120
  scope: SemanticScope.Property,
114
121
  category: SemanticCategory.Lifecycle,
122
+ hasConfig: false,
115
123
  }
116
124
  const associationSemantic: AssociationSemantic = {
117
125
  id: SemanticType.ResourceOwnerIdentifier,
@@ -119,6 +127,7 @@ test.group('Semantics', () => {
119
127
  description: 'Test',
120
128
  scope: SemanticScope.Association,
121
129
  category: SemanticCategory.Identity,
130
+ hasConfig: false,
122
131
  }
123
132
 
124
133
  assert.isFalse(isAssociationSemantic(entitySemantic))
@@ -1 +0,0 @@
1
- {"version":3,"file":"Price.d.ts","sourceRoot":"","sources":["../../../../src/modeling/definitions/Price.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,eAAe,GAAG,gBAAgB,CAAA;AAE/E;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAA;IAElC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAE5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAE9B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAElC;;OAEG;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,EAAE,EAAE,YAAY,CAAC,KAAK,CAAA;IACtB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,mBAAmB,KAAG,QAAQ,IAAI,oBAE3E,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAQ,WAAgB,KAAG,oBAe9D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAMlC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;;IAQH;;OAEG;;IAQH;;OAEG;;IAQH;;OAEG;;IAQH;;OAEG;;CAOK,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,WAAW,KAAG,MAAM,EAY/D,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Price.js","sourceRoot":"","sources":["../../../../src/modeling/definitions/Price.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAqE9C;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAA6B,EAAoC,EAAE;IACjG,OAAO,QAAQ,CAAC,EAAE,KAAK,YAAY,CAAC,KAAK,CAAA;AAC3C,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAsB,EAAE,EAAwB,EAAE;IACpF,MAAM,YAAY,GAAG;QACnB,GAAG,oBAAoB;QACvB,GAAG,MAAM;KACV,CAAA;IAED,4BAA4B;IAC5B,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,YAAY,CAAC,QAAQ,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;IAChD,CAAC;IAED,OAAO;QACL,EAAE,EAAE,YAAY,CAAC,KAAK;QACtB,MAAM,EAAE,YAAY;KACrB,CAAA;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAgB;IAC/C,aAAa,EAAE,SAAS;IACxB,eAAe,EAAE,KAAK;IACtB,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,KAAK;IACpB,oBAAoB,EAAE,IAAI;CAC3B,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;OAEG;IACH,WAAW,EAAE,mBAAmB,CAAC;QAC/B,aAAa,EAAE,SAAS;QACxB,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,KAAK;KACrB,CAAC;IAEF;;OAEG;IACH,SAAS,EAAE,mBAAmB,CAAC;QAC7B,aAAa,EAAE,eAAe;QAC9B,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,KAAK;KACrB,CAAC;IAEF;;OAEG;IACH,cAAc,EAAE,mBAAmB,CAAC;QAClC,aAAa,EAAE,gBAAgB;QAC/B,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;QACtD,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,KAAK;KACrB,CAAC;IAEF;;OAEG;IACH,cAAc,EAAE,mBAAmB,CAAC;QAClC,aAAa,EAAE,SAAS;QACxB,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,IAAI;KACpB,CAAC;IAEF;;OAEG;IACH,cAAc,EAAE,mBAAmB,CAAC;QAClC,aAAa,EAAE,SAAS;QACxB,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,KAAK;KACrB,CAAC;CACM,CAAA;AAEV;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAmB,EAAY,EAAE;IACnE,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,IAAI,MAAM,CAAC,aAAa,KAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAA;IACrF,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAA;IACnD,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["import type { AppliedDataSemantic } from '../Semantics.js'\nimport { SemanticType } from '../Semantics.js'\n\n/**\n * Supported storage formats for monetary values.\n */\nexport type PriceStorageFormat = 'decimal' | 'integer_cents' | 'complex_object'\n\n/**\n * Configuration options for the Price semantic.\n * Controls monetary value storage, validation, currency handling, and precision.\n */\nexport interface PriceConfig {\n /**\n * How the monetary value is stored in the database.\n *\n * - 'decimal': Store as DECIMAL/NUMERIC type (e.g., 19.99)\n * - 'integer_cents': Store as INTEGER in smallest currency unit (e.g., 1999 for $19.99)\n * - 'complex_object': Store as JSON/JSONB with amount and currency (e.g., {\"amount\": 1999, \"currency\": \"USD\"})\n */\n storageFormat?: PriceStorageFormat\n\n /**\n * Default currency code (ISO 4217) when not specified.\n * Required when using 'decimal' or 'integer_cents' format.\n */\n defaultCurrency?: string\n\n /**\n * List of allowed currency codes (ISO 4217).\n * If not specified, all valid ISO 4217 currencies are allowed.\n */\n allowedCurrencies?: string[]\n\n /**\n * Number of decimal places for precision.\n * Default: 2 (for most currencies like USD, EUR)\n * Some currencies may need 0 (JPY, KRW) or 3 (BHD, KWD)\n */\n decimalPlaces?: number\n\n /**\n * Whether negative values are allowed (for refunds, discounts, etc.).\n */\n allowNegative?: boolean\n\n /**\n * Whether to automatically validate currency codes against ISO 4217.\n */\n validateCurrencyCode?: boolean\n\n /**\n * Custom metadata for the price field.\n */\n metadata?: Record<string, unknown>\n\n /**\n * Index signature to allow additional properties.\n */\n [key: string]: unknown\n}\n\n/**\n * Type-safe configuration for Price semantic.\n */\nexport interface AppliedPriceSemantic extends AppliedDataSemantic {\n id: SemanticType.Price\n config?: PriceConfig\n}\n\n/**\n * Type guard to check if a semantic is a Price semantic.\n */\nexport const isPriceSemantic = (semantic: AppliedDataSemantic): semantic is AppliedPriceSemantic => {\n return semantic.id === SemanticType.Price\n}\n\n/**\n * Helper function to create a Price semantic with configuration.\n */\nexport const createPriceSemantic = (config: PriceConfig = {}): AppliedPriceSemantic => {\n const mergedConfig = {\n ...DEFAULT_PRICE_CONFIG,\n ...config,\n }\n\n // Merge metadata separately\n if (config.metadata) {\n mergedConfig.metadata = { ...config.metadata }\n }\n\n return {\n id: SemanticType.Price,\n config: mergedConfig,\n }\n}\n\n/**\n * Default configuration for Price semantic.\n * Optimized for common e-commerce use cases with USD currency.\n */\nexport const DEFAULT_PRICE_CONFIG: PriceConfig = {\n storageFormat: 'decimal',\n defaultCurrency: 'USD',\n decimalPlaces: 2,\n allowNegative: false,\n validateCurrencyCode: true,\n}\n\n/**\n * Predefined configurations for common use cases.\n */\nexport const PRICE_PRESETS = {\n /**\n * Simple USD decimal storage - good for most e-commerce sites.\n */\n USD_DECIMAL: createPriceSemantic({\n storageFormat: 'decimal',\n defaultCurrency: 'USD',\n decimalPlaces: 2,\n allowNegative: false,\n }),\n\n /**\n * Integer cents storage - avoids floating point issues, good for financial calculations.\n */\n USD_CENTS: createPriceSemantic({\n storageFormat: 'integer_cents',\n defaultCurrency: 'USD',\n decimalPlaces: 2,\n allowNegative: false,\n }),\n\n /**\n * Multi-currency support with complex object storage.\n */\n MULTI_CURRENCY: createPriceSemantic({\n storageFormat: 'complex_object',\n allowedCurrencies: ['USD', 'EUR', 'GBP', 'JPY', 'CAD'],\n decimalPlaces: 2,\n allowNegative: false,\n }),\n\n /**\n * Configuration that allows negative values for refunds, discounts, etc.\n */\n WITH_NEGATIVES: createPriceSemantic({\n storageFormat: 'decimal',\n defaultCurrency: 'USD',\n decimalPlaces: 2,\n allowNegative: true,\n }),\n\n /**\n * High-precision configuration for cryptocurrency or precious metals.\n */\n HIGH_PRECISION: createPriceSemantic({\n storageFormat: 'decimal',\n defaultCurrency: 'BTC',\n decimalPlaces: 8,\n allowNegative: false,\n }),\n} as const\n\n/**\n * Helper function to validate a price configuration.\n */\nexport const validatePriceConfig = (config: PriceConfig): string[] => {\n const errors: string[] = []\n\n if (config.storageFormat !== 'complex_object' && !config.defaultCurrency) {\n errors.push('defaultCurrency is required when storageFormat is not complex_object')\n }\n\n if (config.decimalPlaces !== undefined && config.decimalPlaces < 0) {\n errors.push('decimalPlaces must be non-negative')\n }\n\n return errors\n}\n"]}