@api-client/core 0.15.1 → 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.
- package/TESTING_READY.md +114 -0
- package/TESTING_SETUP.md +198 -0
- package/build/src/modeling/Semantics.d.ts +126 -2
- package/build/src/modeling/Semantics.d.ts.map +1 -1
- package/build/src/modeling/Semantics.js +281 -13
- package/build/src/modeling/Semantics.js.map +1 -1
- package/build/src/modeling/definitions/Calculated.d.ts +54 -0
- package/build/src/modeling/definitions/Calculated.d.ts.map +1 -0
- package/build/src/modeling/definitions/Calculated.js +31 -0
- package/build/src/modeling/definitions/Calculated.js.map +1 -0
- package/build/src/modeling/definitions/Categories.d.ts +60 -0
- package/build/src/modeling/definitions/Categories.d.ts.map +1 -0
- package/build/src/modeling/definitions/Categories.js +33 -0
- package/build/src/modeling/definitions/Categories.js.map +1 -0
- package/build/src/modeling/definitions/Derived.d.ts +54 -0
- package/build/src/modeling/definitions/Derived.d.ts.map +1 -0
- package/build/src/modeling/definitions/Derived.js +31 -0
- package/build/src/modeling/definitions/Derived.js.map +1 -0
- package/build/src/modeling/definitions/Description.d.ts +36 -0
- package/build/src/modeling/definitions/Description.d.ts.map +1 -0
- package/build/src/modeling/definitions/Description.js +28 -0
- package/build/src/modeling/definitions/Description.js.map +1 -0
- package/build/src/modeling/definitions/Email.d.ts +66 -0
- package/build/src/modeling/definitions/Email.d.ts.map +1 -0
- package/build/src/modeling/definitions/Email.js +33 -0
- package/build/src/modeling/definitions/Email.js.map +1 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.d.ts +212 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.d.ts.map +1 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.js +129 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.js.map +1 -0
- package/build/src/modeling/definitions/HTML.d.ts +88 -0
- package/build/src/modeling/definitions/HTML.d.ts.map +1 -0
- package/build/src/modeling/definitions/HTML.js +42 -0
- package/build/src/modeling/definitions/HTML.js.map +1 -0
- package/build/src/modeling/definitions/Markdown.d.ts +84 -0
- package/build/src/modeling/definitions/Markdown.d.ts.map +1 -0
- package/build/src/modeling/definitions/Markdown.js +41 -0
- package/build/src/modeling/definitions/Markdown.js.map +1 -0
- package/build/src/modeling/definitions/Password.d.ts +112 -0
- package/build/src/modeling/definitions/Password.d.ts.map +1 -0
- package/build/src/modeling/definitions/Password.js +57 -0
- package/build/src/modeling/definitions/Password.js.map +1 -0
- package/build/src/modeling/definitions/Phone.d.ts +83 -0
- package/build/src/modeling/definitions/Phone.d.ts.map +1 -0
- package/build/src/modeling/definitions/Phone.js +39 -0
- package/build/src/modeling/definitions/Phone.js.map +1 -0
- package/build/src/modeling/definitions/Price.d.ts +102 -0
- package/build/src/modeling/definitions/Price.d.ts.map +1 -0
- package/build/src/modeling/definitions/Price.js +99 -0
- package/build/src/modeling/definitions/Price.js.map +1 -0
- package/build/src/modeling/definitions/PublicUniqueName.d.ts +69 -0
- package/build/src/modeling/definitions/PublicUniqueName.d.ts.map +1 -0
- package/build/src/modeling/definitions/PublicUniqueName.js +34 -0
- package/build/src/modeling/definitions/PublicUniqueName.js.map +1 -0
- package/build/src/modeling/definitions/SKU.d.ts +127 -0
- package/build/src/modeling/definitions/SKU.d.ts.map +1 -0
- package/build/src/modeling/definitions/SKU.js +142 -0
- package/build/src/modeling/definitions/SKU.js.map +1 -0
- package/build/src/modeling/definitions/Status.d.ts +150 -0
- package/build/src/modeling/definitions/Status.d.ts.map +1 -0
- package/build/src/modeling/definitions/Status.js +60 -0
- package/build/src/modeling/definitions/Status.js.map +1 -0
- package/build/src/modeling/definitions/Summary.d.ts +53 -0
- package/build/src/modeling/definitions/Summary.d.ts.map +1 -0
- package/build/src/modeling/definitions/Summary.js +50 -0
- package/build/src/modeling/definitions/Summary.js.map +1 -0
- package/build/src/modeling/definitions/Tags.d.ts +52 -0
- package/build/src/modeling/definitions/Tags.d.ts.map +1 -0
- package/build/src/modeling/definitions/Tags.js +32 -0
- package/build/src/modeling/definitions/Tags.js.map +1 -0
- package/build/src/modeling/definitions/URL.d.ts +68 -0
- package/build/src/modeling/definitions/URL.d.ts.map +1 -0
- package/build/src/modeling/definitions/URL.js +37 -0
- package/build/src/modeling/definitions/URL.js.map +1 -0
- package/build/src/modeling/validation/semantic_validation.d.ts +4 -0
- package/build/src/modeling/validation/semantic_validation.d.ts.map +1 -1
- package/build/src/modeling/validation/semantic_validation.js +32 -1
- package/build/src/modeling/validation/semantic_validation.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +11 -11
- package/package.json +1 -1
- package/src/modeling/Semantics.ts +297 -14
- package/src/modeling/definitions/Calculated.ts +76 -0
- package/src/modeling/definitions/Categories.ts +84 -0
- package/src/modeling/definitions/Derived.ts +76 -0
- package/src/modeling/definitions/Description.ts +55 -0
- package/src/modeling/definitions/Email.ts +90 -0
- package/src/modeling/definitions/GeospatialCoordinates.ts +274 -0
- package/src/modeling/definitions/HTML.ts +121 -0
- package/src/modeling/definitions/Markdown.ts +116 -0
- package/src/modeling/definitions/Password.ts +156 -0
- package/src/modeling/definitions/Phone.ts +116 -0
- package/src/modeling/definitions/Price.examples.md +158 -0
- package/src/modeling/definitions/Price.ts +180 -0
- package/src/modeling/definitions/PublicUniqueName.ts +98 -0
- package/src/modeling/definitions/SKU.examples.md +230 -0
- package/src/modeling/definitions/SKU.ts +254 -0
- package/src/modeling/definitions/Status.ts +227 -0
- package/src/modeling/definitions/Summary.ts +73 -0
- package/src/modeling/definitions/Tags.ts +75 -0
- package/src/modeling/definitions/URL.ts +96 -0
- package/src/modeling/validation/semantic_validation.ts +35 -1
- package/tests/example-test-setup.ts +133 -0
- package/tests/template-node.spec.ts +75 -0
- package/tests/test-utils.ts +293 -0
- package/tests/unit/modeling/definitions/calculated.spec.ts +33 -0
- package/tests/unit/modeling/definitions/categories.spec.ts +38 -0
- package/tests/unit/modeling/definitions/derived.spec.ts +34 -0
- package/tests/unit/modeling/definitions/description.spec.ts +38 -0
- package/tests/unit/modeling/definitions/email.spec.ts +38 -0
- package/tests/unit/modeling/definitions/geospatial-coordinates.spec.ts +41 -0
- package/tests/unit/modeling/definitions/html.spec.ts +38 -0
- package/tests/unit/modeling/definitions/markdown.spec.ts +38 -0
- package/tests/unit/modeling/definitions/password.spec.ts +347 -0
- package/tests/unit/modeling/definitions/phone.spec.ts +38 -0
- package/tests/unit/modeling/definitions/price.spec.ts +465 -0
- package/tests/unit/modeling/definitions/public-unique-name.spec.ts +38 -0
- package/tests/unit/modeling/definitions/sku.spec.ts +240 -0
- package/tests/unit/modeling/definitions/status.spec.ts +37 -0
- package/tests/unit/modeling/definitions/summary.spec.ts +36 -0
- package/tests/unit/modeling/definitions/tags.spec.ts +38 -0
- package/tests/unit/modeling/definitions/url.spec.ts +38 -0
- package/tests/unit/modeling/domain_property.spec.ts +106 -0
- package/tests/unit/modeling/domain_validation.spec.ts +5 -5
- package/tests/unit/modeling/semantic-configs.spec.ts +569 -0
- package/tests/unit/modeling/semantics.spec.ts +52 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { AppliedDataSemantic } from '../Semantics.js'
|
|
2
|
+
import { SemanticType } from '../Semantics.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the Markdown semantic.
|
|
6
|
+
* Controls rendering, sanitization, and allowed features.
|
|
7
|
+
*/
|
|
8
|
+
export interface MarkdownConfig {
|
|
9
|
+
/**
|
|
10
|
+
* List of allowed HTML tags in the rendered output.
|
|
11
|
+
*/
|
|
12
|
+
allowedTags?: string[]
|
|
13
|
+
/**
|
|
14
|
+
* Maximum length of the markdown content.
|
|
15
|
+
*/
|
|
16
|
+
maxLength?: number
|
|
17
|
+
/**
|
|
18
|
+
* Render mode: 'html', 'text', or 'both'.
|
|
19
|
+
*/
|
|
20
|
+
renderMode?: 'html' | 'text' | 'both'
|
|
21
|
+
/**
|
|
22
|
+
* Sanitization level: 'strict', 'moderate', or 'none'.
|
|
23
|
+
*/
|
|
24
|
+
sanitizeLevel?: 'strict' | 'moderate' | 'none'
|
|
25
|
+
/**
|
|
26
|
+
* Whether to allow images in markdown.
|
|
27
|
+
*/
|
|
28
|
+
allowImages?: boolean
|
|
29
|
+
/**
|
|
30
|
+
* Whether to allow links in markdown.
|
|
31
|
+
*/
|
|
32
|
+
allowLinks?: boolean
|
|
33
|
+
/**
|
|
34
|
+
* Whether to allow tables in markdown.
|
|
35
|
+
*/
|
|
36
|
+
allowTables?: boolean
|
|
37
|
+
/**
|
|
38
|
+
* Whether to allow raw HTML in markdown.
|
|
39
|
+
*/
|
|
40
|
+
allowHtml?: boolean
|
|
41
|
+
/**
|
|
42
|
+
* Whether to allow footnotes in markdown.
|
|
43
|
+
*/
|
|
44
|
+
allowFootnotes?: boolean
|
|
45
|
+
/**
|
|
46
|
+
* Whether to allow GitHub-style task lists.
|
|
47
|
+
*/
|
|
48
|
+
allowTaskLists?: boolean
|
|
49
|
+
/**
|
|
50
|
+
* Whether to allow strikethrough formatting.
|
|
51
|
+
*/
|
|
52
|
+
allowStrikethrough?: boolean
|
|
53
|
+
/**
|
|
54
|
+
* Whether to allow math expressions (e.g., LaTeX).
|
|
55
|
+
*/
|
|
56
|
+
allowMath?: boolean
|
|
57
|
+
/**
|
|
58
|
+
* Custom metadata for the markdown field.
|
|
59
|
+
*/
|
|
60
|
+
metadata?: Record<string, unknown>
|
|
61
|
+
/**
|
|
62
|
+
* Index signature to allow additional properties.
|
|
63
|
+
*/
|
|
64
|
+
[key: string]: unknown
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Type-safe configuration for Markdown semantic.
|
|
69
|
+
*/
|
|
70
|
+
export interface AppliedMarkdownSemantic extends AppliedDataSemantic {
|
|
71
|
+
id: SemanticType.Markdown
|
|
72
|
+
config?: MarkdownConfig
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Type guard to check if a semantic is a Markdown semantic.
|
|
77
|
+
*/
|
|
78
|
+
export const isMarkdownSemantic = (semantic: AppliedDataSemantic): semantic is AppliedMarkdownSemantic => {
|
|
79
|
+
return semantic.id === SemanticType.Markdown
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Helper function to create a Markdown semantic with configuration.
|
|
84
|
+
*/
|
|
85
|
+
export const createMarkdownSemantic = (config: MarkdownConfig = {}): AppliedMarkdownSemantic => {
|
|
86
|
+
const mergedConfig = {
|
|
87
|
+
...DEFAULT_MARKDOWN_CONFIG,
|
|
88
|
+
...config,
|
|
89
|
+
}
|
|
90
|
+
if (config.metadata) {
|
|
91
|
+
mergedConfig.metadata = { ...config.metadata }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
id: SemanticType.Markdown,
|
|
96
|
+
config: mergedConfig,
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Default configuration for Markdown semantic.
|
|
102
|
+
*/
|
|
103
|
+
export const DEFAULT_MARKDOWN_CONFIG: MarkdownConfig = {
|
|
104
|
+
allowedTags: ['b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li', 'p', 'br', 'pre', 'code'],
|
|
105
|
+
maxLength: 10000,
|
|
106
|
+
renderMode: 'html',
|
|
107
|
+
sanitizeLevel: 'strict',
|
|
108
|
+
allowImages: true,
|
|
109
|
+
allowLinks: true,
|
|
110
|
+
allowTables: true,
|
|
111
|
+
allowHtml: false,
|
|
112
|
+
allowFootnotes: false,
|
|
113
|
+
allowTaskLists: false,
|
|
114
|
+
allowStrikethrough: true,
|
|
115
|
+
allowMath: false,
|
|
116
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { AppliedDataSemantic } from '../Semantics.js'
|
|
2
|
+
import { SemanticType } from '../Semantics.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Supported encryption algorithms for password hashing.
|
|
6
|
+
*/
|
|
7
|
+
export enum PasswordEncryptionAlgorithm {
|
|
8
|
+
/**
|
|
9
|
+
* bcrypt - Industry standard, secure, and widely supported
|
|
10
|
+
*/
|
|
11
|
+
Bcrypt = 'bcrypt',
|
|
12
|
+
/**
|
|
13
|
+
* Argon2 - Winner of the Password Hashing Competition, very secure
|
|
14
|
+
*/
|
|
15
|
+
Argon2 = 'argon2',
|
|
16
|
+
/**
|
|
17
|
+
* scrypt - Memory-hard function, good for high-security applications
|
|
18
|
+
*/
|
|
19
|
+
Scrypt = 'scrypt',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Configuration options for the Password semantic.
|
|
24
|
+
* These options control password validation and encryption behavior.
|
|
25
|
+
*/
|
|
26
|
+
export interface PasswordConfig {
|
|
27
|
+
/**
|
|
28
|
+
* Whether to require special characters.
|
|
29
|
+
* Defaults to false if not specified.
|
|
30
|
+
*/
|
|
31
|
+
requireSpecialChars?: boolean
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether to require numbers.
|
|
35
|
+
* Defaults to false if not specified.
|
|
36
|
+
*/
|
|
37
|
+
requireNumbers?: boolean
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Whether to require uppercase letters.
|
|
41
|
+
* Defaults to false if not specified.
|
|
42
|
+
*/
|
|
43
|
+
requireUppercase?: boolean
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether to require lowercase letters.
|
|
47
|
+
* Defaults to false if not specified.
|
|
48
|
+
*/
|
|
49
|
+
requireLowercase?: boolean
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Encryption algorithm to use for password hashing.
|
|
53
|
+
* Defaults to 'bcrypt' if not specified.
|
|
54
|
+
*/
|
|
55
|
+
encryptionAlgorithm?: PasswordEncryptionAlgorithm
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Number of salt rounds for bcrypt.
|
|
59
|
+
* Defaults to 12 if not specified.
|
|
60
|
+
*/
|
|
61
|
+
saltRounds?: number
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Maximum age of password in days before requiring change.
|
|
65
|
+
* Defaults to null (no expiration) if not specified.
|
|
66
|
+
*/
|
|
67
|
+
maxAge?: number
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether to prevent reuse of recent passwords.
|
|
71
|
+
* Defaults to false if not specified.
|
|
72
|
+
*/
|
|
73
|
+
preventReuse?: boolean
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Number of recent passwords to prevent reuse.
|
|
77
|
+
* Defaults to 5 if preventReuse is true.
|
|
78
|
+
*/
|
|
79
|
+
preventReuseCount?: number
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Custom password validation regex pattern.
|
|
83
|
+
* If specified, overrides other validation rules.
|
|
84
|
+
*/
|
|
85
|
+
customPattern?: string
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Custom error message for validation failures.
|
|
89
|
+
*/
|
|
90
|
+
customErrorMessage?: string
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether to allow common passwords.
|
|
94
|
+
* Defaults to false if not specified.
|
|
95
|
+
*/
|
|
96
|
+
allowCommonPasswords?: boolean
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Custom metadata for the password field.
|
|
100
|
+
*/
|
|
101
|
+
metadata?: Record<string, unknown>
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Index signature to allow additional properties.
|
|
105
|
+
*/
|
|
106
|
+
[key: string]: unknown
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Type-safe configuration for Password semantic.
|
|
111
|
+
*/
|
|
112
|
+
export interface AppliedPasswordSemantic extends AppliedDataSemantic {
|
|
113
|
+
id: SemanticType.Password
|
|
114
|
+
config?: PasswordConfig
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Type guard to check if a semantic is a Password semantic.
|
|
119
|
+
*/
|
|
120
|
+
export const isPasswordSemantic = (semantic: AppliedDataSemantic): semantic is AppliedPasswordSemantic => {
|
|
121
|
+
return semantic.id === SemanticType.Password
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Helper function to create a Password semantic with configuration.
|
|
126
|
+
*/
|
|
127
|
+
export const createPasswordSemantic = (config: PasswordConfig = {}): AppliedPasswordSemantic => {
|
|
128
|
+
const mergedConfig = {
|
|
129
|
+
...DEFAULT_PASSWORD_CONFIG,
|
|
130
|
+
...config,
|
|
131
|
+
}
|
|
132
|
+
if (config.metadata) {
|
|
133
|
+
mergedConfig.metadata = { ...config.metadata }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
id: SemanticType.Password,
|
|
138
|
+
config: mergedConfig,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Default configuration for Password semantic.
|
|
144
|
+
*/
|
|
145
|
+
export const DEFAULT_PASSWORD_CONFIG: PasswordConfig = {
|
|
146
|
+
requireSpecialChars: true,
|
|
147
|
+
requireNumbers: true,
|
|
148
|
+
requireUppercase: true,
|
|
149
|
+
requireLowercase: true,
|
|
150
|
+
encryptionAlgorithm: PasswordEncryptionAlgorithm.Bcrypt,
|
|
151
|
+
saltRounds: 12,
|
|
152
|
+
maxAge: undefined,
|
|
153
|
+
preventReuse: false,
|
|
154
|
+
preventReuseCount: 5,
|
|
155
|
+
allowCommonPasswords: false,
|
|
156
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { AppliedDataSemantic } from '../Semantics.js'
|
|
2
|
+
import { SemanticType } from '../Semantics.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the Phone semantic.
|
|
6
|
+
* Controls validation, formatting, and verification of phone numbers.
|
|
7
|
+
*/
|
|
8
|
+
export interface PhoneConfig {
|
|
9
|
+
/**
|
|
10
|
+
* List of allowed country codes (ISO 3166-1 alpha-2 format).
|
|
11
|
+
* If not specified, all countries are allowed.
|
|
12
|
+
* Examples: ['US', 'CA', 'GB', 'DE']
|
|
13
|
+
*/
|
|
14
|
+
allowedCountries?: string[]
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Whether the phone number must include a country code.
|
|
18
|
+
* Defaults to true for E.164 format.
|
|
19
|
+
*/
|
|
20
|
+
requireCountryCode?: boolean
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Format for phone number validation and display.
|
|
24
|
+
* - 'E.164': International format with + prefix (e.g., +1234567890)
|
|
25
|
+
* - 'national': Country-specific format without country code
|
|
26
|
+
* - 'international': International format with country code
|
|
27
|
+
* - 'custom': Use customFormat pattern
|
|
28
|
+
*/
|
|
29
|
+
format?: 'E.164' | 'national' | 'international' | 'custom'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Custom format pattern for phone number validation.
|
|
33
|
+
* Only used when format is set to 'custom'.
|
|
34
|
+
* Examples: '###-###-####', '(###) ###-####'
|
|
35
|
+
*/
|
|
36
|
+
customFormat?: string
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Whether to allow phone extensions (e.g., +1234567890 ext 123).
|
|
40
|
+
* Defaults to false.
|
|
41
|
+
*/
|
|
42
|
+
allowExtension?: boolean
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Whether phone number verification is required.
|
|
46
|
+
* Defaults to false.
|
|
47
|
+
*/
|
|
48
|
+
requireVerification?: boolean
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Method to use for phone verification.
|
|
52
|
+
* - 'sms': Send verification code via SMS
|
|
53
|
+
* - 'call': Make verification call
|
|
54
|
+
* - 'none': No verification required
|
|
55
|
+
*/
|
|
56
|
+
verificationMethod?: 'sms' | 'call' | 'none'
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Custom metadata for the phone field.
|
|
60
|
+
*/
|
|
61
|
+
metadata?: Record<string, unknown>
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Index signature to allow additional properties.
|
|
65
|
+
*/
|
|
66
|
+
[key: string]: unknown
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Type-safe configuration for Phone semantic.
|
|
71
|
+
*/
|
|
72
|
+
export interface AppliedPhoneSemantic extends AppliedDataSemantic {
|
|
73
|
+
id: SemanticType.Phone
|
|
74
|
+
config?: PhoneConfig
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Type guard to check if a semantic is a Phone semantic.
|
|
79
|
+
* @param semantic - The semantic to check
|
|
80
|
+
* @returns True if the semantic is a Phone semantic
|
|
81
|
+
*/
|
|
82
|
+
export const isPhoneSemantic = (semantic: AppliedDataSemantic): semantic is AppliedPhoneSemantic => {
|
|
83
|
+
return semantic.id === SemanticType.Phone
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Helper function to create a Phone semantic with configuration.
|
|
88
|
+
* @param config - Configuration options for the phone semantic
|
|
89
|
+
* @returns AppliedPhoneSemantic with the specified configuration
|
|
90
|
+
*/
|
|
91
|
+
export const createPhoneSemantic = (config: PhoneConfig = {}): AppliedPhoneSemantic => {
|
|
92
|
+
const mergedConfig = {
|
|
93
|
+
...DEFAULT_PHONE_CONFIG,
|
|
94
|
+
...config,
|
|
95
|
+
}
|
|
96
|
+
if (config.metadata) {
|
|
97
|
+
mergedConfig.metadata = { ...config.metadata }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
id: SemanticType.Phone,
|
|
102
|
+
config: mergedConfig,
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Default configuration for Phone semantic.
|
|
108
|
+
* Uses E.164 format with country code required and SMS verification.
|
|
109
|
+
*/
|
|
110
|
+
export const DEFAULT_PHONE_CONFIG: PhoneConfig = {
|
|
111
|
+
requireCountryCode: true,
|
|
112
|
+
format: 'E.164',
|
|
113
|
+
allowExtension: false,
|
|
114
|
+
requireVerification: false,
|
|
115
|
+
verificationMethod: 'sms',
|
|
116
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Price Semantic Examples
|
|
2
|
+
|
|
3
|
+
This document provides examples of how to use the Price semantic with different configurations.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { createPriceSemantic, PRICE_PRESETS } from './Price.js'
|
|
9
|
+
|
|
10
|
+
// Simple USD decimal storage
|
|
11
|
+
const basicPrice = createPriceSemantic({
|
|
12
|
+
storageFormat: 'decimal',
|
|
13
|
+
defaultCurrency: 'USD',
|
|
14
|
+
decimalPlaces: 2,
|
|
15
|
+
allowNegative: false,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
// Using a preset
|
|
19
|
+
const usdDecimal = PRICE_PRESETS.USD_DECIMAL
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Configuration Examples
|
|
23
|
+
|
|
24
|
+
### 1. Simple E-commerce Store (USD only)
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
const ecommercePrice = createPriceSemantic({
|
|
28
|
+
storageFormat: 'decimal',
|
|
29
|
+
defaultCurrency: 'USD',
|
|
30
|
+
decimalPlaces: 2,
|
|
31
|
+
allowNegative: false,
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. International E-commerce (Multi-currency)
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const internationalPrice = createPriceSemantic({
|
|
39
|
+
storageFormat: 'complex_object',
|
|
40
|
+
allowedCurrencies: ['USD', 'EUR', 'GBP', 'JPY', 'CAD', 'AUD'],
|
|
41
|
+
decimalPlaces: 2,
|
|
42
|
+
allowNegative: false,
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. Financial System (High precision, allows negatives)
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
const financialPrice = createPriceSemantic({
|
|
50
|
+
storageFormat: 'integer_cents',
|
|
51
|
+
defaultCurrency: 'USD',
|
|
52
|
+
decimalPlaces: 4,
|
|
53
|
+
allowNegative: true,
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 4. Cryptocurrency Trading
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const cryptoPrice = createPriceSemantic({
|
|
61
|
+
storageFormat: 'decimal',
|
|
62
|
+
defaultCurrency: 'BTC',
|
|
63
|
+
decimalPlaces: 8,
|
|
64
|
+
allowNegative: false,
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Storage Format Details
|
|
69
|
+
|
|
70
|
+
### Decimal Format
|
|
71
|
+
|
|
72
|
+
- **Best for**: Simple single-currency applications
|
|
73
|
+
- **PostgreSQL Type**: DECIMAL(precision, scale)
|
|
74
|
+
- **Example Value**: 19.99
|
|
75
|
+
- **Pros**: Human-readable, direct calculations
|
|
76
|
+
- **Cons**: Currency must be stored separately if needed
|
|
77
|
+
|
|
78
|
+
### Integer Cents Format
|
|
79
|
+
|
|
80
|
+
- **Best for**: Financial calculations requiring precision
|
|
81
|
+
- **PostgreSQL Type**: BIGINT
|
|
82
|
+
- **Example Value**: 1999 (represents $19.99)
|
|
83
|
+
- **Pros**: No floating-point errors, efficient storage
|
|
84
|
+
- **Cons**: Requires conversion for display
|
|
85
|
+
|
|
86
|
+
### Complex Object Format
|
|
87
|
+
|
|
88
|
+
- **Best for**: Multi-currency applications
|
|
89
|
+
- **PostgreSQL Type**: JSONB
|
|
90
|
+
- **Example Value**: {"amount": 1999, "currency": "USD"}
|
|
91
|
+
- **Pros**: Stores amount and currency together, flexible
|
|
92
|
+
- **Cons**: More complex queries, larger storage
|
|
93
|
+
|
|
94
|
+
## Database Schema Generation Examples
|
|
95
|
+
|
|
96
|
+
The runtime will generate appropriate PostgreSQL schemas based on the semantic configuration:
|
|
97
|
+
|
|
98
|
+
### For Decimal Format
|
|
99
|
+
|
|
100
|
+
Based on `storageFormat: 'decimal'` configuration, the runtime should generate:
|
|
101
|
+
|
|
102
|
+
```sql
|
|
103
|
+
CREATE TABLE products (
|
|
104
|
+
id SERIAL PRIMARY KEY,
|
|
105
|
+
name VARCHAR(255),
|
|
106
|
+
price DECIMAL(19, 2) NOT NULL,
|
|
107
|
+
currency CHAR(3) DEFAULT 'USD'
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
CREATE INDEX idx_products_price ON products(price);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### For Integer Cents Format
|
|
114
|
+
|
|
115
|
+
Based on `storageFormat: 'integer_cents'` configuration, the runtime should generate:
|
|
116
|
+
|
|
117
|
+
```sql
|
|
118
|
+
CREATE TABLE products (
|
|
119
|
+
id SERIAL PRIMARY KEY,
|
|
120
|
+
name VARCHAR(255),
|
|
121
|
+
price_cents BIGINT NOT NULL,
|
|
122
|
+
currency CHAR(3) DEFAULT 'USD'
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
CREATE INDEX idx_products_price_cents ON products(price_cents);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### For Complex Object Format
|
|
129
|
+
|
|
130
|
+
Based on `storageFormat: 'complex_object'` configuration, the runtime should generate:
|
|
131
|
+
|
|
132
|
+
```sql
|
|
133
|
+
CREATE TABLE products (
|
|
134
|
+
id SERIAL PRIMARY KEY,
|
|
135
|
+
name VARCHAR(255),
|
|
136
|
+
price JSONB NOT NULL
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
CREATE INDEX idx_products_price_amount ON products USING GIN ((price->>'amount'));
|
|
140
|
+
CREATE INDEX idx_products_price_currency ON products USING GIN ((price->>'currency'));
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Validation Examples
|
|
144
|
+
|
|
145
|
+
The Price semantic includes built-in validation:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { validatePriceConfig } from './Price.js'
|
|
149
|
+
|
|
150
|
+
const config = {
|
|
151
|
+
storageFormat: 'decimal' as const,
|
|
152
|
+
// Missing defaultCurrency - this will cause an error
|
|
153
|
+
decimalPlaces: 2,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const errors = validatePriceConfig(config)
|
|
157
|
+
console.log(errors) // ['defaultCurrency is required when storageFormat is not complex_object']
|
|
158
|
+
```
|