@api-client/core 0.15.0 → 0.16.0

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 (126) hide show
  1. package/TESTING_READY.md +114 -0
  2. package/TESTING_SETUP.md +198 -0
  3. package/build/src/modeling/Semantics.d.ts +126 -2
  4. package/build/src/modeling/Semantics.d.ts.map +1 -1
  5. package/build/src/modeling/Semantics.js +281 -13
  6. package/build/src/modeling/Semantics.js.map +1 -1
  7. package/build/src/modeling/definitions/Calculated.d.ts +54 -0
  8. package/build/src/modeling/definitions/Calculated.d.ts.map +1 -0
  9. package/build/src/modeling/definitions/Calculated.js +31 -0
  10. package/build/src/modeling/definitions/Calculated.js.map +1 -0
  11. package/build/src/modeling/definitions/Categories.d.ts +60 -0
  12. package/build/src/modeling/definitions/Categories.d.ts.map +1 -0
  13. package/build/src/modeling/definitions/Categories.js +33 -0
  14. package/build/src/modeling/definitions/Categories.js.map +1 -0
  15. package/build/src/modeling/definitions/Derived.d.ts +54 -0
  16. package/build/src/modeling/definitions/Derived.d.ts.map +1 -0
  17. package/build/src/modeling/definitions/Derived.js +31 -0
  18. package/build/src/modeling/definitions/Derived.js.map +1 -0
  19. package/build/src/modeling/definitions/Description.d.ts +36 -0
  20. package/build/src/modeling/definitions/Description.d.ts.map +1 -0
  21. package/build/src/modeling/definitions/Description.js +28 -0
  22. package/build/src/modeling/definitions/Description.js.map +1 -0
  23. package/build/src/modeling/definitions/Email.d.ts +66 -0
  24. package/build/src/modeling/definitions/Email.d.ts.map +1 -0
  25. package/build/src/modeling/definitions/Email.js +33 -0
  26. package/build/src/modeling/definitions/Email.js.map +1 -0
  27. package/build/src/modeling/definitions/GeospatialCoordinates.d.ts +212 -0
  28. package/build/src/modeling/definitions/GeospatialCoordinates.d.ts.map +1 -0
  29. package/build/src/modeling/definitions/GeospatialCoordinates.js +129 -0
  30. package/build/src/modeling/definitions/GeospatialCoordinates.js.map +1 -0
  31. package/build/src/modeling/definitions/HTML.d.ts +88 -0
  32. package/build/src/modeling/definitions/HTML.d.ts.map +1 -0
  33. package/build/src/modeling/definitions/HTML.js +42 -0
  34. package/build/src/modeling/definitions/HTML.js.map +1 -0
  35. package/build/src/modeling/definitions/Markdown.d.ts +84 -0
  36. package/build/src/modeling/definitions/Markdown.d.ts.map +1 -0
  37. package/build/src/modeling/definitions/Markdown.js +41 -0
  38. package/build/src/modeling/definitions/Markdown.js.map +1 -0
  39. package/build/src/modeling/definitions/Password.d.ts +112 -0
  40. package/build/src/modeling/definitions/Password.d.ts.map +1 -0
  41. package/build/src/modeling/definitions/Password.js +57 -0
  42. package/build/src/modeling/definitions/Password.js.map +1 -0
  43. package/build/src/modeling/definitions/Phone.d.ts +83 -0
  44. package/build/src/modeling/definitions/Phone.d.ts.map +1 -0
  45. package/build/src/modeling/definitions/Phone.js +39 -0
  46. package/build/src/modeling/definitions/Phone.js.map +1 -0
  47. package/build/src/modeling/definitions/Price.d.ts +102 -0
  48. package/build/src/modeling/definitions/Price.d.ts.map +1 -0
  49. package/build/src/modeling/definitions/Price.js +99 -0
  50. package/build/src/modeling/definitions/Price.js.map +1 -0
  51. package/build/src/modeling/definitions/PublicUniqueName.d.ts +69 -0
  52. package/build/src/modeling/definitions/PublicUniqueName.d.ts.map +1 -0
  53. package/build/src/modeling/definitions/PublicUniqueName.js +34 -0
  54. package/build/src/modeling/definitions/PublicUniqueName.js.map +1 -0
  55. package/build/src/modeling/definitions/SKU.d.ts +127 -0
  56. package/build/src/modeling/definitions/SKU.d.ts.map +1 -0
  57. package/build/src/modeling/definitions/SKU.js +142 -0
  58. package/build/src/modeling/definitions/SKU.js.map +1 -0
  59. package/build/src/modeling/definitions/Status.d.ts +150 -0
  60. package/build/src/modeling/definitions/Status.d.ts.map +1 -0
  61. package/build/src/modeling/definitions/Status.js +60 -0
  62. package/build/src/modeling/definitions/Status.js.map +1 -0
  63. package/build/src/modeling/definitions/Summary.d.ts +53 -0
  64. package/build/src/modeling/definitions/Summary.d.ts.map +1 -0
  65. package/build/src/modeling/definitions/Summary.js +50 -0
  66. package/build/src/modeling/definitions/Summary.js.map +1 -0
  67. package/build/src/modeling/definitions/Tags.d.ts +52 -0
  68. package/build/src/modeling/definitions/Tags.d.ts.map +1 -0
  69. package/build/src/modeling/definitions/Tags.js +32 -0
  70. package/build/src/modeling/definitions/Tags.js.map +1 -0
  71. package/build/src/modeling/definitions/URL.d.ts +68 -0
  72. package/build/src/modeling/definitions/URL.d.ts.map +1 -0
  73. package/build/src/modeling/definitions/URL.js +37 -0
  74. package/build/src/modeling/definitions/URL.js.map +1 -0
  75. package/build/src/modeling/validation/semantic_validation.d.ts +4 -0
  76. package/build/src/modeling/validation/semantic_validation.d.ts.map +1 -1
  77. package/build/src/modeling/validation/semantic_validation.js +32 -1
  78. package/build/src/modeling/validation/semantic_validation.js.map +1 -1
  79. package/build/tsconfig.tsbuildinfo +1 -1
  80. package/data/models/example-generator-api.json +9 -9
  81. package/package.json +1 -1
  82. package/src/modeling/Semantics.ts +297 -14
  83. package/src/modeling/definitions/Calculated.ts +76 -0
  84. package/src/modeling/definitions/Categories.ts +84 -0
  85. package/src/modeling/definitions/Derived.ts +76 -0
  86. package/src/modeling/definitions/Description.ts +55 -0
  87. package/src/modeling/definitions/Email.ts +90 -0
  88. package/src/modeling/definitions/GeospatialCoordinates.ts +274 -0
  89. package/src/modeling/definitions/HTML.ts +121 -0
  90. package/src/modeling/definitions/Markdown.ts +116 -0
  91. package/src/modeling/definitions/Password.ts +156 -0
  92. package/src/modeling/definitions/Phone.ts +116 -0
  93. package/src/modeling/definitions/Price.examples.md +158 -0
  94. package/src/modeling/definitions/Price.ts +180 -0
  95. package/src/modeling/definitions/PublicUniqueName.ts +98 -0
  96. package/src/modeling/definitions/SKU.examples.md +230 -0
  97. package/src/modeling/definitions/SKU.ts +254 -0
  98. package/src/modeling/definitions/Status.ts +227 -0
  99. package/src/modeling/definitions/Summary.ts +73 -0
  100. package/src/modeling/definitions/Tags.ts +75 -0
  101. package/src/modeling/definitions/URL.ts +96 -0
  102. package/src/modeling/validation/semantic_validation.ts +35 -1
  103. package/tests/example-test-setup.ts +133 -0
  104. package/tests/template-node.spec.ts +75 -0
  105. package/tests/test-utils.ts +293 -0
  106. package/tests/unit/modeling/definitions/calculated.spec.ts +33 -0
  107. package/tests/unit/modeling/definitions/categories.spec.ts +38 -0
  108. package/tests/unit/modeling/definitions/derived.spec.ts +34 -0
  109. package/tests/unit/modeling/definitions/description.spec.ts +38 -0
  110. package/tests/unit/modeling/definitions/email.spec.ts +38 -0
  111. package/tests/unit/modeling/definitions/geospatial-coordinates.spec.ts +41 -0
  112. package/tests/unit/modeling/definitions/html.spec.ts +38 -0
  113. package/tests/unit/modeling/definitions/markdown.spec.ts +38 -0
  114. package/tests/unit/modeling/definitions/password.spec.ts +347 -0
  115. package/tests/unit/modeling/definitions/phone.spec.ts +38 -0
  116. package/tests/unit/modeling/definitions/price.spec.ts +465 -0
  117. package/tests/unit/modeling/definitions/public-unique-name.spec.ts +38 -0
  118. package/tests/unit/modeling/definitions/sku.spec.ts +240 -0
  119. package/tests/unit/modeling/definitions/status.spec.ts +37 -0
  120. package/tests/unit/modeling/definitions/summary.spec.ts +36 -0
  121. package/tests/unit/modeling/definitions/tags.spec.ts +38 -0
  122. package/tests/unit/modeling/definitions/url.spec.ts +38 -0
  123. package/tests/unit/modeling/domain_property.spec.ts +106 -0
  124. package/tests/unit/modeling/domain_validation.spec.ts +5 -5
  125. package/tests/unit/modeling/semantic-configs.spec.ts +569 -0
  126. package/tests/unit/modeling/semantics.spec.ts +52 -0
@@ -0,0 +1,180 @@
1
+ import type { AppliedDataSemantic } from '../Semantics.js'
2
+ import { SemanticType } from '../Semantics.js'
3
+
4
+ /**
5
+ * Supported storage formats for monetary values.
6
+ */
7
+ export type PriceStorageFormat = 'decimal' | 'integer_cents' | 'complex_object'
8
+
9
+ /**
10
+ * Configuration options for the Price semantic.
11
+ * Controls monetary value storage, validation, currency handling, and precision.
12
+ */
13
+ export interface PriceConfig {
14
+ /**
15
+ * How the monetary value is stored in the database.
16
+ *
17
+ * - 'decimal': Store as DECIMAL/NUMERIC type (e.g., 19.99)
18
+ * - 'integer_cents': Store as INTEGER in smallest currency unit (e.g., 1999 for $19.99)
19
+ * - 'complex_object': Store as JSON/JSONB with amount and currency (e.g., {"amount": 1999, "currency": "USD"})
20
+ */
21
+ storageFormat?: PriceStorageFormat
22
+
23
+ /**
24
+ * Default currency code (ISO 4217) when not specified.
25
+ * Required when using 'decimal' or 'integer_cents' format.
26
+ */
27
+ defaultCurrency?: string
28
+
29
+ /**
30
+ * List of allowed currency codes (ISO 4217).
31
+ * If not specified, all valid ISO 4217 currencies are allowed.
32
+ */
33
+ allowedCurrencies?: string[]
34
+
35
+ /**
36
+ * Number of decimal places for precision.
37
+ * Default: 2 (for most currencies like USD, EUR)
38
+ * Some currencies may need 0 (JPY, KRW) or 3 (BHD, KWD)
39
+ */
40
+ decimalPlaces?: number
41
+
42
+ /**
43
+ * Whether negative values are allowed (for refunds, discounts, etc.).
44
+ */
45
+ allowNegative?: boolean
46
+
47
+ /**
48
+ * Whether to automatically validate currency codes against ISO 4217.
49
+ */
50
+ validateCurrencyCode?: boolean
51
+
52
+ /**
53
+ * Custom metadata for the price field.
54
+ */
55
+ metadata?: Record<string, unknown>
56
+
57
+ /**
58
+ * Index signature to allow additional properties.
59
+ */
60
+ [key: string]: unknown
61
+ }
62
+
63
+ /**
64
+ * Type-safe configuration for Price semantic.
65
+ */
66
+ export interface AppliedPriceSemantic extends AppliedDataSemantic {
67
+ id: SemanticType.Price
68
+ config?: PriceConfig
69
+ }
70
+
71
+ /**
72
+ * Type guard to check if a semantic is a Price semantic.
73
+ */
74
+ export const isPriceSemantic = (semantic: AppliedDataSemantic): semantic is AppliedPriceSemantic => {
75
+ return semantic.id === SemanticType.Price
76
+ }
77
+
78
+ /**
79
+ * Helper function to create a Price semantic with configuration.
80
+ */
81
+ export const createPriceSemantic = (config: PriceConfig = {}): AppliedPriceSemantic => {
82
+ const mergedConfig = {
83
+ ...DEFAULT_PRICE_CONFIG,
84
+ ...config,
85
+ }
86
+
87
+ // Merge metadata separately
88
+ if (config.metadata) {
89
+ mergedConfig.metadata = { ...config.metadata }
90
+ }
91
+
92
+ return {
93
+ id: SemanticType.Price,
94
+ config: mergedConfig,
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Default configuration for Price semantic.
100
+ * Optimized for common e-commerce use cases with USD currency.
101
+ */
102
+ export const DEFAULT_PRICE_CONFIG: PriceConfig = {
103
+ storageFormat: 'decimal',
104
+ defaultCurrency: 'USD',
105
+ decimalPlaces: 2,
106
+ allowNegative: false,
107
+ validateCurrencyCode: true,
108
+ }
109
+
110
+ /**
111
+ * Predefined configurations for common use cases.
112
+ */
113
+ export const PRICE_PRESETS = {
114
+ /**
115
+ * Simple USD decimal storage - good for most e-commerce sites.
116
+ */
117
+ USD_DECIMAL: createPriceSemantic({
118
+ storageFormat: 'decimal',
119
+ defaultCurrency: 'USD',
120
+ decimalPlaces: 2,
121
+ allowNegative: false,
122
+ }),
123
+
124
+ /**
125
+ * Integer cents storage - avoids floating point issues, good for financial calculations.
126
+ */
127
+ USD_CENTS: createPriceSemantic({
128
+ storageFormat: 'integer_cents',
129
+ defaultCurrency: 'USD',
130
+ decimalPlaces: 2,
131
+ allowNegative: false,
132
+ }),
133
+
134
+ /**
135
+ * Multi-currency support with complex object storage.
136
+ */
137
+ MULTI_CURRENCY: createPriceSemantic({
138
+ storageFormat: 'complex_object',
139
+ allowedCurrencies: ['USD', 'EUR', 'GBP', 'JPY', 'CAD'],
140
+ decimalPlaces: 2,
141
+ allowNegative: false,
142
+ }),
143
+
144
+ /**
145
+ * Configuration that allows negative values for refunds, discounts, etc.
146
+ */
147
+ WITH_NEGATIVES: createPriceSemantic({
148
+ storageFormat: 'decimal',
149
+ defaultCurrency: 'USD',
150
+ decimalPlaces: 2,
151
+ allowNegative: true,
152
+ }),
153
+
154
+ /**
155
+ * High-precision configuration for cryptocurrency or precious metals.
156
+ */
157
+ HIGH_PRECISION: createPriceSemantic({
158
+ storageFormat: 'decimal',
159
+ defaultCurrency: 'BTC',
160
+ decimalPlaces: 8,
161
+ allowNegative: false,
162
+ }),
163
+ } as const
164
+
165
+ /**
166
+ * Helper function to validate a price configuration.
167
+ */
168
+ export const validatePriceConfig = (config: PriceConfig): string[] => {
169
+ const errors: string[] = []
170
+
171
+ if (config.storageFormat !== 'complex_object' && !config.defaultCurrency) {
172
+ errors.push('defaultCurrency is required when storageFormat is not complex_object')
173
+ }
174
+
175
+ if (config.decimalPlaces !== undefined && config.decimalPlaces < 0) {
176
+ errors.push('decimalPlaces must be non-negative')
177
+ }
178
+
179
+ return errors
180
+ }
@@ -0,0 +1,98 @@
1
+ import type { AppliedDataSemantic } from '../Semantics.js'
2
+ import { SemanticType } from '../Semantics.js'
3
+
4
+ /**
5
+ * Configuration options for the PublicUniqueName (slug) semantic.
6
+ * Controls how slugs are generated and validated.
7
+ */
8
+ export interface PublicUniqueNameConfig {
9
+ /**
10
+ * The source field to generate the slug from (e.g., 'title').
11
+ * Default to the field that is annotated with the Title semantic.
12
+ */
13
+ sourceField?: string
14
+ /**
15
+ * Separator character to use in the slug (default: '-').
16
+ */
17
+ separator?: string
18
+ /**
19
+ * Maximum length of the slug (default: 64).
20
+ */
21
+ maxLength?: number
22
+ /**
23
+ * Whether the slug is case sensitive (default: false).
24
+ */
25
+ caseSensitive?: boolean
26
+ /**
27
+ * Whether to allow Unicode characters in the slug (default: false).
28
+ */
29
+ allowUnicode?: boolean
30
+ /**
31
+ * Name of a custom generator function to use for slug creation.
32
+ */
33
+ customGenerator?: string
34
+ /**
35
+ * Whether to allow duplicate slugs (default: false).
36
+ */
37
+ allowDuplicates?: boolean
38
+ /**
39
+ * Fallback field to use if the source field is empty or invalid.
40
+ */
41
+ fallbackField?: string
42
+ /**
43
+ * Custom metadata for the slug field.
44
+ */
45
+ metadata?: Record<string, unknown>
46
+ /**
47
+ * Index signature to allow additional properties.
48
+ */
49
+ [key: string]: unknown
50
+ }
51
+
52
+ /**
53
+ * Type-safe configuration for PublicUniqueName semantic.
54
+ */
55
+ export interface AppliedPublicUniqueNameSemantic extends AppliedDataSemantic {
56
+ id: SemanticType.PublicUniqueName
57
+ config?: PublicUniqueNameConfig
58
+ }
59
+
60
+ /**
61
+ * Type guard to check if a semantic is a PublicUniqueName semantic.
62
+ */
63
+ export const isPublicUniqueNameSemantic = (
64
+ semantic: AppliedDataSemantic
65
+ ): semantic is AppliedPublicUniqueNameSemantic => {
66
+ return semantic.id === SemanticType.PublicUniqueName
67
+ }
68
+
69
+ /**
70
+ * Helper function to create a PublicUniqueName semantic with configuration.
71
+ */
72
+ export const createPublicUniqueNameSemantic = (
73
+ config: PublicUniqueNameConfig = {}
74
+ ): AppliedPublicUniqueNameSemantic => {
75
+ const mergedConfig = {
76
+ ...DEFAULT_PUBLIC_UNIQUE_NAME_CONFIG,
77
+ ...config,
78
+ }
79
+ if (config.metadata) {
80
+ mergedConfig.metadata = { ...config.metadata }
81
+ }
82
+
83
+ return {
84
+ id: SemanticType.PublicUniqueName,
85
+ config: mergedConfig,
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Default configuration for PublicUniqueName semantic.
91
+ */
92
+ export const DEFAULT_PUBLIC_UNIQUE_NAME_CONFIG: PublicUniqueNameConfig = {
93
+ separator: '-',
94
+ maxLength: 64,
95
+ caseSensitive: false,
96
+ allowUnicode: false,
97
+ allowDuplicates: false,
98
+ }
@@ -0,0 +1,230 @@
1
+ # SKU Semantic Examples
2
+
3
+ This document provides examples of how to use the SKU semantic with different configurations.
4
+
5
+ ## Basic Usage
6
+
7
+ ```typescript
8
+ import { createSKUSemantic, SKU_PRESETS } from './SKU.js'
9
+
10
+ // Simple SKU with default settings
11
+ const basicSKU = createSKUSemantic()
12
+
13
+ // Using a preset for product catalogs
14
+ const productSKU = SKU_PRESETS.PRODUCT_STANDARD
15
+ ```
16
+
17
+ ## Configuration Examples
18
+
19
+ ### 1. Standard Product Catalog
20
+
21
+ ```typescript
22
+ const productCatalogSKU = createSKUSemantic({
23
+ validationMode: 'strict',
24
+ caseMode: 'uppercase',
25
+ prefix: 'PROD-',
26
+ enforceUniqueness: true,
27
+ validateReservedWords: true,
28
+ })
29
+ ```
30
+
31
+ ### 2. Simple Inventory System
32
+
33
+ ```typescript
34
+ const simpleSKU = createSKUSemantic({
35
+ validationMode: 'lenient',
36
+ caseMode: 'preserve',
37
+ enforceUniqueness: true,
38
+ })
39
+ ```
40
+
41
+ ### 3. Auto-generating SKUs
42
+
43
+ ```typescript
44
+ const autoGeneratedSKU = createSKUSemantic({
45
+ validationMode: 'strict',
46
+ caseMode: 'uppercase',
47
+ autoGenerate: true,
48
+ autoGenerateSource: 'name', // Generate from product name
49
+ enforceUniqueness: true,
50
+ })
51
+ ```
52
+
53
+ ### 4. Custom Pattern Validation
54
+
55
+ ```typescript
56
+ const customPatternSKU = createSKUSemantic({
57
+ validationMode: 'custom',
58
+ customPattern: '^[A-Z]{3}-\\d{4}-[A-Z]{2}$', // Format: ABC-1234-XY
59
+ caseMode: 'uppercase',
60
+ enforceUniqueness: true,
61
+ })
62
+ ```
63
+
64
+ ### 5. Flexible Multi-category System
65
+
66
+ ```typescript
67
+ const flexibleSKU = createSKUSemantic({
68
+ validationMode: 'lenient',
69
+ caseMode: 'preserve',
70
+ enforceUniqueness: true,
71
+ validateReservedWords: false, // Allow more flexibility
72
+ })
73
+ ```
74
+
75
+ ## Storage Format Details
76
+
77
+ ### Database Schema Generation
78
+
79
+ The runtime will generate appropriate database schemas with unique constraints:
80
+
81
+ ```sql
82
+ CREATE TABLE products (
83
+ id SERIAL PRIMARY KEY,
84
+ name VARCHAR(255),
85
+ sku VARCHAR(50) UNIQUE NOT NULL,
86
+ description TEXT
87
+ );
88
+
89
+ -- Automatically creates unique index
90
+ CREATE UNIQUE INDEX idx_products_sku ON products(sku);
91
+
92
+ -- For case-insensitive uniqueness (depending on configuration)
93
+ CREATE UNIQUE INDEX idx_products_sku_lower ON products(LOWER(sku));
94
+ ```
95
+
96
+ ### Case Transformation Examples
97
+
98
+ ```typescript
99
+ // Uppercase transformation
100
+ const uppercaseSKU = createSKUSemantic({ caseMode: 'uppercase' })
101
+ // Input: "prod-123" → Stored: "PROD-123"
102
+
103
+ // Lowercase transformation
104
+ const lowercaseSKU = createSKUSemantic({ caseMode: 'lowercase' })
105
+ // Input: "PROD-123" → Stored: "prod-123"
106
+
107
+ // Preserve original case
108
+ const preserveCaseSKU = createSKUSemantic({ caseMode: 'preserve' })
109
+ // Input: "Prod-123" → Stored: "Prod-123"
110
+ ```
111
+
112
+ ## Validation Examples
113
+
114
+ ### Strict Validation
115
+
116
+ ```typescript
117
+ const strictSKU = createSKUSemantic({ validationMode: 'strict' })
118
+
119
+ // Valid SKUs
120
+ strictSKU.validate('PRODUCT123') // ✓ Valid
121
+ strictSKU.validate('PROD-123') // ✓ Valid
122
+ strictSKU.validate('PROD_123') // ✓ Valid
123
+
124
+ // Invalid SKUs
125
+ strictSKU.validate('PROD.123') // ✗ Contains dot
126
+ strictSKU.validate('PROD@123') // ✗ Contains special character
127
+ strictSKU.validate('PROD 123') // ✗ Contains space
128
+ ```
129
+
130
+ ### Lenient Validation
131
+
132
+ ```typescript
133
+ const lenientSKU = createSKUSemantic({ validationMode: 'lenient' })
134
+
135
+ // Valid SKUs
136
+ lenientSKU.validate('PRODUCT123') // ✓ Valid
137
+ lenientSKU.validate('PROD-123') // ✓ Valid
138
+ lenientSKU.validate('PROD.123') // ✓ Valid (dots allowed)
139
+
140
+ // Invalid SKUs
141
+ lenientSKU.validate('PROD@123') // ✗ Special characters not allowed
142
+ lenientSKU.validate('PROD#123') // ✗ Hash not allowed
143
+ ```
144
+
145
+ ### Custom Pattern Validation
146
+
147
+ ```typescript
148
+ const customSKU = createSKUSemantic({
149
+ validationMode: 'custom',
150
+ customPattern: '^[A-Z]{2}\\d{4}$' // Two letters followed by four digits
151
+ })
152
+
153
+ // Valid SKUs
154
+ customSKU.validate('AB1234') // ✓ Valid
155
+ customSKU.validate('XY9999') // ✓ Valid
156
+
157
+ // Invalid SKUs
158
+ customSKU.validate('ABC123') // ✗ Wrong format
159
+ customSKU.validate('ab1234') // ✗ Lowercase letters
160
+ customSKU.validate('A1234') // ✗ Only one letter
161
+ ```
162
+
163
+ ## Reserved Words
164
+
165
+ The SKU semantic includes protection against common reserved values:
166
+
167
+ ```typescript
168
+ const skuConfig = createSKUSemantic({
169
+ validateReservedWords: true,
170
+ reservedValues: ['ADMIN', 'TEST', 'NULL', 'DEFAULT', 'SAMPLE']
171
+ })
172
+
173
+ // These will be rejected
174
+ skuConfig.validate('ADMIN') // ✗ Reserved word
175
+ skuConfig.validate('test') // ✗ Reserved word (case-insensitive)
176
+ skuConfig.validate('NULL') // ✗ Reserved word
177
+ ```
178
+
179
+ ## Auto-generation Behavior
180
+
181
+ When `autoGenerate` is enabled, the runtime automatically creates SKUs:
182
+
183
+ ```typescript
184
+ const autoSKU = createSKUSemantic({
185
+ autoGenerate: true,
186
+ autoGenerateSource: 'name',
187
+ prefix: 'PROD-',
188
+ caseMode: 'uppercase'
189
+ })
190
+
191
+ // For a product named "Blue Widget"
192
+ // Generated SKU might be: "PROD-BLUE-WIDGET" or "PROD-BLUE-WIDGET-001"
193
+ ```
194
+
195
+ ## Error Handling
196
+
197
+ ```typescript
198
+ import { validateSKUConfig, validateSKUValue } from './SKU.js'
199
+
200
+ // Validate configuration
201
+ const configErrors = validateSKUConfig({
202
+ validationMode: 'custom' // Invalid: missing customPattern
203
+ })
204
+ console.log(configErrors) // ['customPattern is required when validationMode is custom']
205
+
206
+ // Validate SKU values
207
+ const valueErrors = validateSKUValue('TEST')
208
+ console.log(valueErrors) // ['SKU cannot use reserved value: TEST']
209
+ ```
210
+
211
+ ## Integration with Domain Entities
212
+
213
+ ```typescript
214
+ // In your domain model
215
+ const productEntity = domain.addEntity({
216
+ name: 'Product',
217
+ properties: [
218
+ {
219
+ name: 'sku',
220
+ type: 'string',
221
+ semantics: [createSKUSemantic({
222
+ validationMode: 'strict',
223
+ caseMode: 'uppercase',
224
+ prefix: 'PROD-',
225
+ enforceUniqueness: true
226
+ })]
227
+ }
228
+ ]
229
+ })
230
+ ```