@wildo-ai/zod-decorators 1.0.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/dist/esm/__mocks__/mime.d.ts +12 -0
- package/dist/esm/__mocks__/mime.d.ts.map +1 -0
- package/dist/esm/__mocks__/mime.js +75 -0
- package/dist/esm/__mocks__/mime.js.map +1 -0
- package/dist/esm/commons.d.ts +26 -0
- package/dist/esm/commons.d.ts.map +1 -0
- package/dist/esm/commons.js +41 -0
- package/dist/esm/commons.js.map +1 -0
- package/dist/esm/currencies.shared.schemas.d.ts +208 -0
- package/dist/esm/currencies.shared.schemas.d.ts.map +1 -0
- package/dist/esm/currencies.shared.schemas.js +228 -0
- package/dist/esm/currencies.shared.schemas.js.map +1 -0
- package/dist/esm/files/agent-file-formats.d.ts +99 -0
- package/dist/esm/files/agent-file-formats.d.ts.map +1 -0
- package/dist/esm/files/agent-file-formats.js +163 -0
- package/dist/esm/files/agent-file-formats.js.map +1 -0
- package/dist/esm/files/extension-nature-map.d.ts +12 -0
- package/dist/esm/files/extension-nature-map.d.ts.map +1 -0
- package/dist/esm/files/extension-nature-map.js +63 -0
- package/dist/esm/files/extension-nature-map.js.map +1 -0
- package/dist/esm/files/file-extensions.enum.d.ts +58 -0
- package/dist/esm/files/file-extensions.enum.d.ts.map +1 -0
- package/dist/esm/files/file-extensions.enum.js +65 -0
- package/dist/esm/files/file-extensions.enum.js.map +1 -0
- package/dist/esm/files/mime-registry.d.ts +72 -0
- package/dist/esm/files/mime-registry.d.ts.map +1 -0
- package/dist/esm/files/mime-registry.js +174 -0
- package/dist/esm/files/mime-registry.js.map +1 -0
- package/dist/esm/files/unified-registry.d.ts +112 -0
- package/dist/esm/files/unified-registry.d.ts.map +1 -0
- package/dist/esm/files/unified-registry.js +190 -0
- package/dist/esm/files/unified-registry.js.map +1 -0
- package/dist/esm/index.d.ts +29 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +36 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/testing/decorated-test-schemas.d.ts +27 -0
- package/dist/esm/testing/decorated-test-schemas.d.ts.map +1 -0
- package/dist/esm/testing/decorated-test-schemas.js +26 -0
- package/dist/esm/testing/decorated-test-schemas.js.map +1 -0
- package/dist/esm/testing.d.ts +6 -0
- package/dist/esm/testing.d.ts.map +1 -0
- package/dist/esm/testing.js +6 -0
- package/dist/esm/testing.js.map +1 -0
- package/dist/esm/zod-bigdecimal.d.ts +193 -0
- package/dist/esm/zod-bigdecimal.d.ts.map +1 -0
- package/dist/esm/zod-bigdecimal.js +274 -0
- package/dist/esm/zod-bigdecimal.js.map +1 -0
- package/dist/esm/zod-code.d.ts +95 -0
- package/dist/esm/zod-code.d.ts.map +1 -0
- package/dist/esm/zod-code.js +160 -0
- package/dist/esm/zod-code.js.map +1 -0
- package/dist/esm/zod-color.d.ts +8 -0
- package/dist/esm/zod-color.d.ts.map +1 -0
- package/dist/esm/zod-color.js +88 -0
- package/dist/esm/zod-color.js.map +1 -0
- package/dist/esm/zod-decorators.types.d.ts +2207 -0
- package/dist/esm/zod-decorators.types.d.ts.map +1 -0
- package/dist/esm/zod-decorators.types.js +771 -0
- package/dist/esm/zod-decorators.types.js.map +1 -0
- package/dist/esm/zod-duration.d.ts +128 -0
- package/dist/esm/zod-duration.d.ts.map +1 -0
- package/dist/esm/zod-duration.js +174 -0
- package/dist/esm/zod-duration.js.map +1 -0
- package/dist/esm/zod-file.d.ts +219 -0
- package/dist/esm/zod-file.d.ts.map +1 -0
- package/dist/esm/zod-file.js +469 -0
- package/dist/esm/zod-file.js.map +1 -0
- package/dist/esm/zod-money.d.ts +223 -0
- package/dist/esm/zod-money.d.ts.map +1 -0
- package/dist/esm/zod-money.js +293 -0
- package/dist/esm/zod-money.js.map +1 -0
- package/dist/esm/zod-phone.d.ts +75 -0
- package/dist/esm/zod-phone.d.ts.map +1 -0
- package/dist/esm/zod-phone.js +116 -0
- package/dist/esm/zod-phone.js.map +1 -0
- package/dist/esm/zod-range.d.ts +87 -0
- package/dist/esm/zod-range.d.ts.map +1 -0
- package/dist/esm/zod-range.js +138 -0
- package/dist/esm/zod-range.js.map +1 -0
- package/dist/esm/zod-utils.shared.d.ts +783 -0
- package/dist/esm/zod-utils.shared.d.ts.map +1 -0
- package/dist/esm/zod-utils.shared.js +2647 -0
- package/dist/esm/zod-utils.shared.js.map +1 -0
- package/dist/esm/zod-versioned.d.ts +150 -0
- package/dist/esm/zod-versioned.d.ts.map +1 -0
- package/dist/esm/zod-versioned.js +172 -0
- package/dist/esm/zod-versioned.js.map +1 -0
- package/dist/esm/zod.module-override.d.ts +413 -0
- package/dist/esm/zod.module-override.d.ts.map +1 -0
- package/dist/esm/zod.module-override.js +1093 -0
- package/dist/esm/zod.module-override.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { DecoratorInput, MoneySchemaOptions, SummaryFieldParams, ZodDecorator, ZodDecorator_ParamsType } from "./zod-decorators.types.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { CurrencySchema } from "./currencies.shared.schemas.js";
|
|
4
|
+
/**
|
|
5
|
+
* Money value type - represents a monetary amount with bigint storage.
|
|
6
|
+
*
|
|
7
|
+
* The amount is stored as a bigint in the smallest unit (e.g., cents for USD).
|
|
8
|
+
* Using bigint ensures no precision loss for arbitrarily large amounts.
|
|
9
|
+
* The decimals field indicates how to convert to the display value:
|
|
10
|
+
* - displayValue = Number(amount) / (10 ** decimals)
|
|
11
|
+
*
|
|
12
|
+
* Example: { amount: 1999n, currency: 'USD', decimals: 2 } = $19.99
|
|
13
|
+
*/
|
|
14
|
+
export interface MoneyValue {
|
|
15
|
+
/** Amount in smallest unit (e.g., cents). BigInt to avoid precision issues with large amounts. */
|
|
16
|
+
amount: bigint;
|
|
17
|
+
/** ISO 4217 currency code (e.g., 'USD', 'EUR', 'BTC') */
|
|
18
|
+
currency: string;
|
|
19
|
+
/** Number of decimal places for display (e.g., 2 for USD, 8 for BTC) */
|
|
20
|
+
decimals: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Zod schema for MoneyValue.
|
|
24
|
+
*/
|
|
25
|
+
export declare const MoneyValueSchema: z.ZodObject<{
|
|
26
|
+
amount: z.ZodBigInt;
|
|
27
|
+
currency: typeof CurrencySchema;
|
|
28
|
+
decimals: z.ZodNumber;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* z_money() - Creates money schemas for financial amounts.
|
|
32
|
+
*
|
|
33
|
+
* Money values are stored as integers to avoid floating-point precision issues.
|
|
34
|
+
* The schema creates an object with: { amount, currency, decimals }
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* import { z_money } from '@wildo-ai/zod-decorators';
|
|
39
|
+
*
|
|
40
|
+
* const price = z_money();
|
|
41
|
+
* const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });
|
|
42
|
+
* const usdPrice = z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } });
|
|
43
|
+
*
|
|
44
|
+
* // With decorators (chainable)
|
|
45
|
+
* z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } })
|
|
46
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR] }).isHidden({ edit: true })
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Creates a money schema with metadata for detection and form component rendering.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Configuration options for money field
|
|
53
|
+
* @returns A Zod object schema with metadata for money detection
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* // Simple money (all currencies)
|
|
58
|
+
* const price = z_money();
|
|
59
|
+
* // Infers: { amount: bigint, currency: string, decimals: number }
|
|
60
|
+
*
|
|
61
|
+
* // Fiat only (no crypto)
|
|
62
|
+
* const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });
|
|
63
|
+
*
|
|
64
|
+
* // Fixed currency with amount constraints
|
|
65
|
+
* const usdPrice = z_money({
|
|
66
|
+
* allowCurrencyChange: false,
|
|
67
|
+
* minAmount: 0n,
|
|
68
|
+
* maxAmount: 100000000n // $1,000,000.00 in cents
|
|
69
|
+
* }).moneyUI({ edit: { defaultCurrency: 'USD' } });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function createMoneySchema(options?: MoneySchemaOptions): DecoratedMoneySchema;
|
|
73
|
+
/**
|
|
74
|
+
* Return type for money schemas - includes decorator methods.
|
|
75
|
+
* Note: IS_FOREIGN_KEY is not applicable to money objects.
|
|
76
|
+
* IS_DB_INDEXED will index internal fields (amount, currency) for query optimization.
|
|
77
|
+
*
|
|
78
|
+
* This type must list all decorators applicable to ZodObject (per ApplyableTypeAllTypes).
|
|
79
|
+
* Missing entries here cause TS errors when chaining decorators on z_money() fields.
|
|
80
|
+
*/
|
|
81
|
+
export type DecoratedMoneySchema = z.ZodObject<{
|
|
82
|
+
amount: z.ZodBigInt;
|
|
83
|
+
currency: typeof CurrencySchema;
|
|
84
|
+
decimals: z.ZodNumber;
|
|
85
|
+
}> & {
|
|
86
|
+
[ZodDecorator.IS_DB_INDEXED](): DecoratedMoneySchema;
|
|
87
|
+
[ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedMoneySchema;
|
|
88
|
+
[ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedMoneySchema;
|
|
89
|
+
[ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedMoneySchema;
|
|
90
|
+
[ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedMoneySchema;
|
|
91
|
+
[ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedMoneySchema;
|
|
92
|
+
[ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedMoneySchema;
|
|
93
|
+
addDecorators(decorators: DecoratorInput[]): DecoratedMoneySchema;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Creates a money schema for financial amounts with integer storage.
|
|
97
|
+
* Named z_money to indicate it's a Zod helper function exported standalone.
|
|
98
|
+
*
|
|
99
|
+
* Money values are stored as: { amount: int, currency: string, decimals: int }
|
|
100
|
+
* - amount: Value in smallest unit (e.g., cents for USD, satoshis for BTC)
|
|
101
|
+
* - currency: ISO 4217 code (e.g., 'USD', 'EUR', 'BTC')
|
|
102
|
+
* - decimals: Decimal places for display conversion (e.g., 2 for USD, 8 for BTC)
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* import { z_money } from '@wildo-ai/zod-decorators';
|
|
107
|
+
*
|
|
108
|
+
* // Simple usage
|
|
109
|
+
* z_money() // All currencies
|
|
110
|
+
*
|
|
111
|
+
* // With options
|
|
112
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] })
|
|
113
|
+
* z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } })
|
|
114
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR], minAmount: 0n })
|
|
115
|
+
*
|
|
116
|
+
* // With decorators (chainable)
|
|
117
|
+
* z_money().moneyUI({ edit: { defaultCurrency: 'USD' } })
|
|
118
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] }).isHidden({ edit: true })
|
|
119
|
+
*
|
|
120
|
+
* // Usage example
|
|
121
|
+
* const price: MoneyValue = { amount: 1999n, currency: 'USD', decimals: 2 };
|
|
122
|
+
* // Represents $19.99
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare function z_money(options?: MoneySchemaOptions): DecoratedMoneySchema;
|
|
126
|
+
/**
|
|
127
|
+
* Convert a decimal amount to bigint representation.
|
|
128
|
+
*
|
|
129
|
+
* **Precision caveat:** This uses floating-point arithmetic internally
|
|
130
|
+
* (`Math.round(decimalAmount * 10^decimals)`), which can produce rounding
|
|
131
|
+
* errors for certain values. Prefer `parseDecimalStringToAmount` when working
|
|
132
|
+
* with user input strings to avoid float precision issues entirely.
|
|
133
|
+
*
|
|
134
|
+
* @param decimalAmount - The decimal amount (e.g., 19.99)
|
|
135
|
+
* @param decimals - Number of decimal places (e.g., 2)
|
|
136
|
+
* @returns BigInt amount (e.g., 1999n)
|
|
137
|
+
*/
|
|
138
|
+
export declare function toMoneyAmount(decimalAmount: number, decimals: number): bigint;
|
|
139
|
+
/**
|
|
140
|
+
* Convert a bigint amount to decimal representation.
|
|
141
|
+
* @param amount - The bigint amount (e.g., 1999n)
|
|
142
|
+
* @param decimals - Number of decimal places (e.g., 2)
|
|
143
|
+
* @returns Decimal amount (e.g., 19.99)
|
|
144
|
+
*/
|
|
145
|
+
export declare function fromMoneyAmount(amount: bigint, decimals: number): number;
|
|
146
|
+
/**
|
|
147
|
+
* Convert a string or number to bigint safely.
|
|
148
|
+
* Useful for parsing user input or JSON values.
|
|
149
|
+
* @param value - String, number, or bigint to convert
|
|
150
|
+
* @returns BigInt amount
|
|
151
|
+
*/
|
|
152
|
+
export declare function toBigIntAmount(value: string | number | bigint): bigint;
|
|
153
|
+
/**
|
|
154
|
+
* Parse a decimal string directly to a bigint amount, avoiding floating-point
|
|
155
|
+
* precision issues entirely.
|
|
156
|
+
*
|
|
157
|
+
* This is the preferred way to convert user input (e.g., from an HTML input
|
|
158
|
+
* element) to a money amount. It works by splitting the string at the decimal
|
|
159
|
+
* point and manipulating integer/fractional parts as strings, so no float
|
|
160
|
+
* arithmetic is ever involved.
|
|
161
|
+
*
|
|
162
|
+
* - Extra fractional digits beyond `decimals` are **truncated** (not rounded).
|
|
163
|
+
* - Missing fractional digits are **zero-padded**.
|
|
164
|
+
*
|
|
165
|
+
* @param input - A decimal string (e.g., "19.99", "5", ".50", "-12.345")
|
|
166
|
+
* @param decimals - Number of decimal places for the target currency
|
|
167
|
+
* @returns BigInt amount, or `null` if the input is not a valid decimal string
|
|
168
|
+
*
|
|
169
|
+
* **Note:** Scientific notation strings (e.g., `"1e+10"`) are rejected (returns
|
|
170
|
+
* `null`) since they are not valid monetary input. This is correct behavior when
|
|
171
|
+
* reading from `<input type="number">`, which may produce such strings for very
|
|
172
|
+
* large values — those inputs should be constrained via `min`/`max` attributes.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* parseDecimalStringToAmount("19.99", 2) // → 1999n
|
|
177
|
+
* parseDecimalStringToAmount("19.999", 2) // → 1999n (truncates, not rounds)
|
|
178
|
+
* parseDecimalStringToAmount("19.9", 2) // → 1990n (pads missing decimals)
|
|
179
|
+
* parseDecimalStringToAmount("5", 2) // → 500n
|
|
180
|
+
* parseDecimalStringToAmount(".50", 2) // → 50n
|
|
181
|
+
* parseDecimalStringToAmount("-12.34", 2) // → -1234n
|
|
182
|
+
* parseDecimalStringToAmount("abc", 2) // → null
|
|
183
|
+
* parseDecimalStringToAmount("1e+10", 2) // → null (scientific notation rejected)
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export declare function parseDecimalStringToAmount(input: string, decimals: number): bigint | null;
|
|
187
|
+
/**
|
|
188
|
+
* Convert a money amount from one decimal precision to another using pure
|
|
189
|
+
* bigint arithmetic (no floating-point involved).
|
|
190
|
+
*
|
|
191
|
+
* Use this when changing a currency (which may have different decimal places)
|
|
192
|
+
* instead of the float roundtrip `fromMoneyAmount` → `toMoneyAmount`.
|
|
193
|
+
*
|
|
194
|
+
* - When increasing decimals (e.g., 2 → 8): multiplies by 10^(diff)
|
|
195
|
+
* - When decreasing decimals (e.g., 8 → 2): divides with half-away-from-zero rounding
|
|
196
|
+
*
|
|
197
|
+
* @param amount - The bigint amount in the source precision
|
|
198
|
+
* @param fromDecimals - Source decimal places
|
|
199
|
+
* @param toDecimals - Target decimal places
|
|
200
|
+
* @returns BigInt amount in the target precision
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* convertMoneyDecimals(1999n, 2, 2) // → 1999n (same decimals, no-op)
|
|
205
|
+
* convertMoneyDecimals(1999n, 2, 4) // → 199900n (scale up)
|
|
206
|
+
* convertMoneyDecimals(199900n, 4, 2) // → 1999n (scale down)
|
|
207
|
+
* convertMoneyDecimals(12345678n, 8, 2) // → 12n (BTC satoshis to 2-decimal)
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
export declare function convertMoneyDecimals(amount: bigint, fromDecimals: number, toDecimals: number): bigint;
|
|
211
|
+
/**
|
|
212
|
+
* Format a money value for display.
|
|
213
|
+
* @param money - The money value
|
|
214
|
+
* @param options - Formatting options
|
|
215
|
+
* @returns Formatted string (e.g., "$19.99" or "19.99 USD")
|
|
216
|
+
*/
|
|
217
|
+
export declare function formatMoney(money: MoneyValue, options?: {
|
|
218
|
+
showSymbol?: boolean;
|
|
219
|
+
symbolPosition?: 'before' | 'after';
|
|
220
|
+
thousandsSeparator?: string;
|
|
221
|
+
decimalSeparator?: string;
|
|
222
|
+
}): string;
|
|
223
|
+
//# sourceMappingURL=zod-money.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-money.d.ts","sourceRoot":"","sources":["../../src/zod-money.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// MONEY SCHEMA HELPER
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { SCHEMA_METADATA, ZodDecorator } from "./zod-decorators.types.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { addChainableMethods } from "./zod.module-override.js";
|
|
7
|
+
import { CurrencySchema } from "./currencies.shared.schemas.js";
|
|
8
|
+
/**
|
|
9
|
+
* Zod schema for MoneyValue.
|
|
10
|
+
*/
|
|
11
|
+
export const MoneyValueSchema = z.object({
|
|
12
|
+
amount: z.bigint(),
|
|
13
|
+
currency: CurrencySchema,
|
|
14
|
+
decimals: z.number().int().min(0).max(18),
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* z_money() - Creates money schemas for financial amounts.
|
|
18
|
+
*
|
|
19
|
+
* Money values are stored as integers to avoid floating-point precision issues.
|
|
20
|
+
* The schema creates an object with: { amount, currency, decimals }
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { z_money } from '@wildo-ai/zod-decorators';
|
|
25
|
+
*
|
|
26
|
+
* const price = z_money();
|
|
27
|
+
* const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });
|
|
28
|
+
* const usdPrice = z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } });
|
|
29
|
+
*
|
|
30
|
+
* // With decorators (chainable)
|
|
31
|
+
* z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } })
|
|
32
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR] }).isHidden({ edit: true })
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Creates a money schema with metadata for detection and form component rendering.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Configuration options for money field
|
|
39
|
+
* @returns A Zod object schema with metadata for money detection
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // Simple money (all currencies)
|
|
44
|
+
* const price = z_money();
|
|
45
|
+
* // Infers: { amount: bigint, currency: string, decimals: number }
|
|
46
|
+
*
|
|
47
|
+
* // Fiat only (no crypto)
|
|
48
|
+
* const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });
|
|
49
|
+
*
|
|
50
|
+
* // Fixed currency with amount constraints
|
|
51
|
+
* const usdPrice = z_money({
|
|
52
|
+
* allowCurrencyChange: false,
|
|
53
|
+
* minAmount: 0n,
|
|
54
|
+
* maxAmount: 100000000n // $1,000,000.00 in cents
|
|
55
|
+
* }).moneyUI({ edit: { defaultCurrency: 'USD' } });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function createMoneySchema(options = {}) {
|
|
59
|
+
const { currenciesAllowed, appEnabledOnly = true, allowCurrencyChange = true, minAmount, maxAmount, } = options;
|
|
60
|
+
// Create the amount schema with optional min/max constraints
|
|
61
|
+
// Using bigint for amount to avoid precision issues with large financial amounts
|
|
62
|
+
let amountSchema = z.bigint();
|
|
63
|
+
if (minAmount !== undefined) {
|
|
64
|
+
amountSchema = amountSchema.min(minAmount);
|
|
65
|
+
}
|
|
66
|
+
if (maxAmount !== undefined) {
|
|
67
|
+
amountSchema = amountSchema.max(maxAmount);
|
|
68
|
+
}
|
|
69
|
+
// Create the money object schema
|
|
70
|
+
const moneySchema = z.object({
|
|
71
|
+
amount: amountSchema,
|
|
72
|
+
currency: CurrencySchema,
|
|
73
|
+
decimals: z.number().int().min(0).max(18),
|
|
74
|
+
});
|
|
75
|
+
const moneyMetadata = {
|
|
76
|
+
isMoney: true,
|
|
77
|
+
...(currenciesAllowed && currenciesAllowed.length > 0 && { currenciesAllowed }),
|
|
78
|
+
appEnabledOnly,
|
|
79
|
+
allowCurrencyChange,
|
|
80
|
+
...(minAmount !== undefined && { minAmount }),
|
|
81
|
+
...(maxAmount !== undefined && { maxAmount }),
|
|
82
|
+
};
|
|
83
|
+
// Initialize or extend SCHEMA_METADATA with money config
|
|
84
|
+
const existingMetadata = moneySchema[SCHEMA_METADATA] || {};
|
|
85
|
+
moneySchema[SCHEMA_METADATA] = {
|
|
86
|
+
...existingMetadata,
|
|
87
|
+
moneyConfig: moneyMetadata,
|
|
88
|
+
};
|
|
89
|
+
// Add chainable decorator methods to the money schema instance
|
|
90
|
+
// This allows: z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } }).isHidden()
|
|
91
|
+
addChainableMethods(moneySchema);
|
|
92
|
+
return moneySchema;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates a money schema for financial amounts with integer storage.
|
|
96
|
+
* Named z_money to indicate it's a Zod helper function exported standalone.
|
|
97
|
+
*
|
|
98
|
+
* Money values are stored as: { amount: int, currency: string, decimals: int }
|
|
99
|
+
* - amount: Value in smallest unit (e.g., cents for USD, satoshis for BTC)
|
|
100
|
+
* - currency: ISO 4217 code (e.g., 'USD', 'EUR', 'BTC')
|
|
101
|
+
* - decimals: Decimal places for display conversion (e.g., 2 for USD, 8 for BTC)
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* import { z_money } from '@wildo-ai/zod-decorators';
|
|
106
|
+
*
|
|
107
|
+
* // Simple usage
|
|
108
|
+
* z_money() // All currencies
|
|
109
|
+
*
|
|
110
|
+
* // With options
|
|
111
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] })
|
|
112
|
+
* z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } })
|
|
113
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR], minAmount: 0n })
|
|
114
|
+
*
|
|
115
|
+
* // With decorators (chainable)
|
|
116
|
+
* z_money().moneyUI({ edit: { defaultCurrency: 'USD' } })
|
|
117
|
+
* z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] }).isHidden({ edit: true })
|
|
118
|
+
*
|
|
119
|
+
* // Usage example
|
|
120
|
+
* const price: MoneyValue = { amount: 1999n, currency: 'USD', decimals: 2 };
|
|
121
|
+
* // Represents $19.99
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export function z_money(options) {
|
|
125
|
+
return createMoneySchema(options);
|
|
126
|
+
}
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// MONEY UTILITY FUNCTIONS
|
|
129
|
+
// ============================================================================
|
|
130
|
+
/**
|
|
131
|
+
* Convert a decimal amount to bigint representation.
|
|
132
|
+
*
|
|
133
|
+
* **Precision caveat:** This uses floating-point arithmetic internally
|
|
134
|
+
* (`Math.round(decimalAmount * 10^decimals)`), which can produce rounding
|
|
135
|
+
* errors for certain values. Prefer `parseDecimalStringToAmount` when working
|
|
136
|
+
* with user input strings to avoid float precision issues entirely.
|
|
137
|
+
*
|
|
138
|
+
* @param decimalAmount - The decimal amount (e.g., 19.99)
|
|
139
|
+
* @param decimals - Number of decimal places (e.g., 2)
|
|
140
|
+
* @returns BigInt amount (e.g., 1999n)
|
|
141
|
+
*/
|
|
142
|
+
export function toMoneyAmount(decimalAmount, decimals) {
|
|
143
|
+
return BigInt(Math.round(decimalAmount * Math.pow(10, decimals)));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Convert a bigint amount to decimal representation.
|
|
147
|
+
* @param amount - The bigint amount (e.g., 1999n)
|
|
148
|
+
* @param decimals - Number of decimal places (e.g., 2)
|
|
149
|
+
* @returns Decimal amount (e.g., 19.99)
|
|
150
|
+
*/
|
|
151
|
+
export function fromMoneyAmount(amount, decimals) {
|
|
152
|
+
return Number(amount) / Math.pow(10, decimals);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Convert a string or number to bigint safely.
|
|
156
|
+
* Useful for parsing user input or JSON values.
|
|
157
|
+
* @param value - String, number, or bigint to convert
|
|
158
|
+
* @returns BigInt amount
|
|
159
|
+
*/
|
|
160
|
+
export function toBigIntAmount(value) {
|
|
161
|
+
if (typeof value === 'bigint')
|
|
162
|
+
return value;
|
|
163
|
+
if (typeof value === 'number')
|
|
164
|
+
return BigInt(Math.round(value));
|
|
165
|
+
return BigInt(value);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Parse a decimal string directly to a bigint amount, avoiding floating-point
|
|
169
|
+
* precision issues entirely.
|
|
170
|
+
*
|
|
171
|
+
* This is the preferred way to convert user input (e.g., from an HTML input
|
|
172
|
+
* element) to a money amount. It works by splitting the string at the decimal
|
|
173
|
+
* point and manipulating integer/fractional parts as strings, so no float
|
|
174
|
+
* arithmetic is ever involved.
|
|
175
|
+
*
|
|
176
|
+
* - Extra fractional digits beyond `decimals` are **truncated** (not rounded).
|
|
177
|
+
* - Missing fractional digits are **zero-padded**.
|
|
178
|
+
*
|
|
179
|
+
* @param input - A decimal string (e.g., "19.99", "5", ".50", "-12.345")
|
|
180
|
+
* @param decimals - Number of decimal places for the target currency
|
|
181
|
+
* @returns BigInt amount, or `null` if the input is not a valid decimal string
|
|
182
|
+
*
|
|
183
|
+
* **Note:** Scientific notation strings (e.g., `"1e+10"`) are rejected (returns
|
|
184
|
+
* `null`) since they are not valid monetary input. This is correct behavior when
|
|
185
|
+
* reading from `<input type="number">`, which may produce such strings for very
|
|
186
|
+
* large values — those inputs should be constrained via `min`/`max` attributes.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* parseDecimalStringToAmount("19.99", 2) // → 1999n
|
|
191
|
+
* parseDecimalStringToAmount("19.999", 2) // → 1999n (truncates, not rounds)
|
|
192
|
+
* parseDecimalStringToAmount("19.9", 2) // → 1990n (pads missing decimals)
|
|
193
|
+
* parseDecimalStringToAmount("5", 2) // → 500n
|
|
194
|
+
* parseDecimalStringToAmount(".50", 2) // → 50n
|
|
195
|
+
* parseDecimalStringToAmount("-12.34", 2) // → -1234n
|
|
196
|
+
* parseDecimalStringToAmount("abc", 2) // → null
|
|
197
|
+
* parseDecimalStringToAmount("1e+10", 2) // → null (scientific notation rejected)
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export function parseDecimalStringToAmount(input, decimals) {
|
|
201
|
+
const trimmed = input.trim();
|
|
202
|
+
if (trimmed === '' || trimmed === '.' || trimmed === '-' || trimmed === '-.')
|
|
203
|
+
return null;
|
|
204
|
+
// Handle sign
|
|
205
|
+
const isNegative = trimmed.startsWith('-');
|
|
206
|
+
const unsigned = isNegative ? trimmed.slice(1) : trimmed;
|
|
207
|
+
// Validate: only digits and at most one decimal point
|
|
208
|
+
if (!/^\d*\.?\d*$/.test(unsigned))
|
|
209
|
+
return null;
|
|
210
|
+
const dotIndex = unsigned.indexOf('.');
|
|
211
|
+
const integerPart = dotIndex === -1 ? unsigned : (unsigned.slice(0, dotIndex) || '0');
|
|
212
|
+
const fractionalRaw = dotIndex === -1 ? '' : unsigned.slice(dotIndex + 1);
|
|
213
|
+
// Pad or truncate fractional part to exactly `decimals` digits
|
|
214
|
+
const fractionalPart = decimals === 0
|
|
215
|
+
? ''
|
|
216
|
+
: fractionalRaw.padEnd(decimals, '0').slice(0, decimals);
|
|
217
|
+
// Build the combined string and convert to bigint
|
|
218
|
+
const combined = integerPart + fractionalPart;
|
|
219
|
+
// Guard against empty combined (shouldn't happen after validation, but be safe)
|
|
220
|
+
if (combined === '')
|
|
221
|
+
return 0n;
|
|
222
|
+
try {
|
|
223
|
+
const result = BigInt(combined);
|
|
224
|
+
return isNegative ? -result : result;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Convert a money amount from one decimal precision to another using pure
|
|
232
|
+
* bigint arithmetic (no floating-point involved).
|
|
233
|
+
*
|
|
234
|
+
* Use this when changing a currency (which may have different decimal places)
|
|
235
|
+
* instead of the float roundtrip `fromMoneyAmount` → `toMoneyAmount`.
|
|
236
|
+
*
|
|
237
|
+
* - When increasing decimals (e.g., 2 → 8): multiplies by 10^(diff)
|
|
238
|
+
* - When decreasing decimals (e.g., 8 → 2): divides with half-away-from-zero rounding
|
|
239
|
+
*
|
|
240
|
+
* @param amount - The bigint amount in the source precision
|
|
241
|
+
* @param fromDecimals - Source decimal places
|
|
242
|
+
* @param toDecimals - Target decimal places
|
|
243
|
+
* @returns BigInt amount in the target precision
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```typescript
|
|
247
|
+
* convertMoneyDecimals(1999n, 2, 2) // → 1999n (same decimals, no-op)
|
|
248
|
+
* convertMoneyDecimals(1999n, 2, 4) // → 199900n (scale up)
|
|
249
|
+
* convertMoneyDecimals(199900n, 4, 2) // → 1999n (scale down)
|
|
250
|
+
* convertMoneyDecimals(12345678n, 8, 2) // → 12n (BTC satoshis to 2-decimal)
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
export function convertMoneyDecimals(amount, fromDecimals, toDecimals) {
|
|
254
|
+
if (fromDecimals === toDecimals)
|
|
255
|
+
return amount;
|
|
256
|
+
const diff = toDecimals - fromDecimals;
|
|
257
|
+
if (diff > 0) {
|
|
258
|
+
// Scale up: multiply
|
|
259
|
+
return amount * (10n ** BigInt(diff));
|
|
260
|
+
}
|
|
261
|
+
// Scale down: divide with rounding (half-away-from-zero)
|
|
262
|
+
const divisor = 10n ** BigInt(-diff);
|
|
263
|
+
const isNegative = amount < 0n;
|
|
264
|
+
const absAmount = isNegative ? -amount : amount;
|
|
265
|
+
const rounded = (absAmount + divisor / 2n) / divisor;
|
|
266
|
+
return isNegative ? -rounded : rounded;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Format a money value for display.
|
|
270
|
+
* @param money - The money value
|
|
271
|
+
* @param options - Formatting options
|
|
272
|
+
* @returns Formatted string (e.g., "$19.99" or "19.99 USD")
|
|
273
|
+
*/
|
|
274
|
+
export function formatMoney(money, options = {}) {
|
|
275
|
+
const { showSymbol = true, symbolPosition = 'before', thousandsSeparator = ',', decimalSeparator = '.', } = options;
|
|
276
|
+
const decimalValue = fromMoneyAmount(money.amount, money.decimals);
|
|
277
|
+
// Format with proper decimal places
|
|
278
|
+
const [integerPart, decimalPart] = decimalValue.toFixed(money.decimals).split('.');
|
|
279
|
+
// Add thousands separator
|
|
280
|
+
const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
|
|
281
|
+
const formattedNumber = decimalPart
|
|
282
|
+
? `${formattedInteger}${decimalSeparator}${decimalPart}`
|
|
283
|
+
: formattedInteger;
|
|
284
|
+
if (!showSymbol) {
|
|
285
|
+
return formattedNumber;
|
|
286
|
+
}
|
|
287
|
+
// For now, use currency code as symbol (can be enhanced with CURRENCY_INFO_MAP)
|
|
288
|
+
const symbol = money.currency;
|
|
289
|
+
return symbolPosition === 'before'
|
|
290
|
+
? `${symbol} ${formattedNumber}`
|
|
291
|
+
: `${formattedNumber} ${symbol}`;
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=zod-money.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-money.js","sourceRoot":"","sources":["../../src/zod-money.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { DecoratorInput, PhoneSchemaOptions, SummaryFieldParams, ZodDecorator, ZodDecorator_ParamsType } from './zod-decorators.types.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { parsePhoneNumberFromString } from 'libphonenumber-js';
|
|
4
|
+
/** Returns country codes (e.g. "US", "FR") for form components. */
|
|
5
|
+
export declare function getCountries(): string[];
|
|
6
|
+
/**
|
|
7
|
+
* Phone value type — E.164 string (e.g., "+33123456789").
|
|
8
|
+
* Use formatPhoneNumber() for display, parsePhoneNumber() for parsing.
|
|
9
|
+
*/
|
|
10
|
+
export type PhoneValue = string;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a phone string to PhoneNumber or undefined.
|
|
13
|
+
*
|
|
14
|
+
* @param value - Raw input (E.164, national, or partial)
|
|
15
|
+
* @param defaultCountry - Country code (e.g. "US", "FR") for numbers without +prefix
|
|
16
|
+
* @returns PhoneNumber or undefined if invalid
|
|
17
|
+
*/
|
|
18
|
+
export declare function parsePhone(value: string, defaultCountry?: string): ReturnType<typeof parsePhoneNumberFromString>;
|
|
19
|
+
/**
|
|
20
|
+
* Validate a phone number string.
|
|
21
|
+
*
|
|
22
|
+
* @param value - Phone string to validate
|
|
23
|
+
* @param defaultCountry - Country code (e.g. "US", "FR") for numbers without +prefix
|
|
24
|
+
* @returns true if valid
|
|
25
|
+
*/
|
|
26
|
+
export declare function isValidPhone(value: string, defaultCountry?: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Format a phone number for display.
|
|
29
|
+
*
|
|
30
|
+
* @param value - E.164 or parseable phone string
|
|
31
|
+
* @param defaultCountry - Country code (e.g. "US", "FR") for numbers without +prefix
|
|
32
|
+
* @param format - 'international' | 'national' (default: international)
|
|
33
|
+
* @returns Formatted string or original if unparseable
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatPhoneNumber(value: string, defaultCountry?: string, format?: 'international' | 'national'): string;
|
|
36
|
+
/**
|
|
37
|
+
* Get country calling code (e.g., "1" for US).
|
|
38
|
+
*
|
|
39
|
+
* @param country - Country code (e.g. "US", "FR")
|
|
40
|
+
*/
|
|
41
|
+
export declare function getPhoneCountryCode(country: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a phone schema with metadata for detection and form component rendering.
|
|
44
|
+
* Values are stored as E.164 strings. Empty string passes validation.
|
|
45
|
+
*
|
|
46
|
+
* @param options - Configuration options for phone field
|
|
47
|
+
* @returns A Zod string schema with metadata for phone detection
|
|
48
|
+
*/
|
|
49
|
+
export declare function createPhoneSchema(options?: PhoneSchemaOptions): DecoratedPhoneSchema;
|
|
50
|
+
/**
|
|
51
|
+
* Return type for phone schemas - includes decorator methods.
|
|
52
|
+
*/
|
|
53
|
+
export type DecoratedPhoneSchema = z.ZodString & {
|
|
54
|
+
[ZodDecorator.IS_DB_INDEXED](): DecoratedPhoneSchema;
|
|
55
|
+
[ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedPhoneSchema;
|
|
56
|
+
[ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedPhoneSchema;
|
|
57
|
+
[ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedPhoneSchema;
|
|
58
|
+
[ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedPhoneSchema;
|
|
59
|
+
[ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedPhoneSchema;
|
|
60
|
+
[ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedPhoneSchema;
|
|
61
|
+
addDecorators(decorators: DecoratorInput[]): DecoratedPhoneSchema;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Creates a phone schema for E.164 phone numbers.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* import { z_phone } from '@wildo-ai/zod-decorators';
|
|
69
|
+
*
|
|
70
|
+
* z_phone()
|
|
71
|
+
* z_phone({ defaultCountry: 'FR' })
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function z_phone(options?: PhoneSchemaOptions): DecoratedPhoneSchema;
|
|
75
|
+
//# sourceMappingURL=zod-phone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-phone.d.ts","sourceRoot":"","sources":["../../src/zod-phone.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAGd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,0BAA0B,EAK3B,MAAM,mBAAmB,CAAC;AAE3B,mEAAmE;AACnE,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAKhC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAMhH;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAM5E;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE,eAAe,GAAG,UAA4B,GACrD,MAAM,CAIR;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,oBAAoB,CA8BxF;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,SAAS,GAAG;IAC/C,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,oBAAoB,CAAC;IACrD,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,oBAAoB,CAAC;IACzG,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,eAAe,CAAC,GAAG,oBAAoB,CAAC;IACrH,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,oBAAoB,CAAC;IACnF,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,eAAe,CAAC,GAAG,oBAAoB,CAAC;IACrH,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,oBAAoB,CAAC;IAC3D,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,oBAAoB,CAAC;IAC3D,aAAa,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,oBAAoB,CAAC;CACnE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,oBAAoB,CAE1E"}
|