@ic-reactor/candid 3.0.14-beta.1 → 3.0.14-beta.3
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/metadata-display-reactor.d.ts +66 -11
- package/dist/metadata-display-reactor.d.ts.map +1 -1
- package/dist/metadata-display-reactor.js +48 -12
- package/dist/metadata-display-reactor.js.map +1 -1
- package/dist/visitor/arguments/helpers.d.ts +20 -5
- package/dist/visitor/arguments/helpers.d.ts.map +1 -1
- package/dist/visitor/arguments/helpers.js +39 -5
- package/dist/visitor/arguments/helpers.js.map +1 -1
- package/dist/visitor/arguments/index.d.ts.map +1 -1
- package/dist/visitor/arguments/index.js +28 -27
- package/dist/visitor/arguments/index.js.map +1 -1
- package/dist/visitor/arguments/types.d.ts +102 -18
- package/dist/visitor/arguments/types.d.ts.map +1 -1
- package/dist/visitor/arguments/types.js +25 -1
- package/dist/visitor/arguments/types.js.map +1 -1
- package/dist/visitor/returns/index.d.ts.map +1 -1
- package/dist/visitor/returns/index.js +24 -13
- package/dist/visitor/returns/index.js.map +1 -1
- package/dist/visitor/returns/types.d.ts +94 -21
- package/dist/visitor/returns/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/metadata-display-reactor.ts +86 -14
- package/src/visitor/arguments/helpers.ts +48 -6
- package/src/visitor/arguments/index.test.ts +55 -55
- package/src/visitor/arguments/index.ts +36 -27
- package/src/visitor/arguments/schema.test.ts +3 -4
- package/src/visitor/arguments/types.ts +113 -21
- package/src/visitor/returns/index.test.ts +29 -29
- package/src/visitor/returns/index.ts +52 -21
- package/src/visitor/returns/types.ts +156 -35
|
@@ -4,12 +4,32 @@ import type { VisitorDataType, TextFormat, NumberFormat } from "../types"
|
|
|
4
4
|
|
|
5
5
|
export type { VisitorDataType, TextFormat, NumberFormat }
|
|
6
6
|
|
|
7
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
8
|
+
// Custom Error Class
|
|
9
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Custom error class for metadata-related errors.
|
|
13
|
+
* Provides additional context about the field path and Candid type.
|
|
14
|
+
*/
|
|
15
|
+
export class MetadataError extends Error {
|
|
16
|
+
constructor(
|
|
17
|
+
message: string,
|
|
18
|
+
public readonly fieldPath?: string,
|
|
19
|
+
public readonly candidType?: string
|
|
20
|
+
) {
|
|
21
|
+
super(message)
|
|
22
|
+
this.name = "MetadataError"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
7
26
|
// ════════════════════════════════════════════════════════════════════════════
|
|
8
27
|
// Component & UI Types
|
|
9
28
|
// ════════════════════════════════════════════════════════════════════════════
|
|
10
29
|
|
|
11
30
|
/**
|
|
12
31
|
* Suggested component type for rendering the field.
|
|
32
|
+
* Use this to map field types to your UI components.
|
|
13
33
|
*/
|
|
14
34
|
export type FieldComponentType =
|
|
15
35
|
| "record-container"
|
|
@@ -68,121 +88,187 @@ export interface PrimitiveInputProps {
|
|
|
68
88
|
// Base Field Interface
|
|
69
89
|
// ════════════════════════════════════════════════════════════════════════════
|
|
70
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Base properties shared by all field nodes.
|
|
93
|
+
*/
|
|
71
94
|
interface FieldBase<T extends VisitorDataType = VisitorDataType> {
|
|
95
|
+
/** The Candid type category (record, variant, text, number, etc.) */
|
|
72
96
|
type: T
|
|
97
|
+
/** Raw label from Candid definition */
|
|
73
98
|
label: string
|
|
99
|
+
/** Human-readable formatted label for display */
|
|
74
100
|
displayLabel: string
|
|
101
|
+
/** Form path compatible with TanStack Form (e.g., "[0]", "[0].owner") */
|
|
75
102
|
name: string
|
|
103
|
+
/** Suggested component type for rendering */
|
|
76
104
|
component: FieldComponentType
|
|
105
|
+
/** UI rendering hints */
|
|
77
106
|
renderHint: RenderHint
|
|
107
|
+
/** Zod validation schema */
|
|
78
108
|
schema: z.ZodTypeAny
|
|
109
|
+
/** Original Candid type name */
|
|
79
110
|
candidType: string
|
|
111
|
+
/** Default value for form initialization */
|
|
80
112
|
defaultValue: unknown
|
|
81
113
|
}
|
|
82
114
|
|
|
83
115
|
// ════════════════════════════════════════════════════════════════════════════
|
|
84
|
-
// Field Extras
|
|
116
|
+
// Field Extras - Type-Specific Properties
|
|
85
117
|
// ════════════════════════════════════════════════════════════════════════════
|
|
86
118
|
|
|
119
|
+
/** Blob upload limits configuration */
|
|
87
120
|
export interface BlobLimits {
|
|
88
121
|
maxHexBytes: number
|
|
89
122
|
maxFileBytes: number
|
|
90
123
|
maxHexDisplayLength: number
|
|
91
124
|
}
|
|
92
125
|
|
|
126
|
+
/** Blob validation result */
|
|
93
127
|
export interface BlobValidationResult {
|
|
94
128
|
valid: boolean
|
|
95
129
|
error?: string
|
|
96
130
|
}
|
|
97
131
|
|
|
98
132
|
interface RecordExtras {
|
|
133
|
+
/** Child fields of the record */
|
|
99
134
|
fields: FieldNode[]
|
|
135
|
+
/** Default value as object with all field defaults */
|
|
100
136
|
defaultValue: Record<string, unknown>
|
|
101
137
|
}
|
|
102
138
|
|
|
103
139
|
interface VariantExtras {
|
|
104
|
-
fields
|
|
140
|
+
/** All variant options as fields */
|
|
141
|
+
options: FieldNode[]
|
|
142
|
+
/** The default selected option key */
|
|
105
143
|
defaultOption: string
|
|
144
|
+
/** Default value with the first option selected */
|
|
106
145
|
defaultValue: Record<string, unknown>
|
|
146
|
+
/** Get default value for a specific option */
|
|
107
147
|
getOptionDefault: (option: string) => Record<string, unknown>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
148
|
+
/** Get field descriptor for a specific option */
|
|
149
|
+
getOption: (option: string) => FieldNode
|
|
150
|
+
/** Get currently selected option key from a value */
|
|
151
|
+
getSelectedKey: (value: Record<string, unknown>) => string
|
|
152
|
+
/** Get the field for the currently selected option */
|
|
153
|
+
getSelectedOption: (value: Record<string, unknown>) => FieldNode
|
|
111
154
|
}
|
|
112
155
|
|
|
113
156
|
interface TupleExtras {
|
|
157
|
+
/** Tuple element fields */
|
|
114
158
|
fields: FieldNode[]
|
|
159
|
+
/** Default value as array of element defaults */
|
|
115
160
|
defaultValue: unknown[]
|
|
116
161
|
}
|
|
117
162
|
|
|
118
163
|
interface OptionalExtras {
|
|
164
|
+
/** The inner type field */
|
|
119
165
|
innerField: FieldNode
|
|
166
|
+
/** Default value is always null */
|
|
120
167
|
defaultValue: null
|
|
168
|
+
/** Get default value of the inner type when enabling */
|
|
121
169
|
getInnerDefault: () => unknown
|
|
170
|
+
/** Check if a value represents an enabled optional */
|
|
122
171
|
isEnabled: (value: unknown) => boolean
|
|
123
172
|
}
|
|
124
173
|
|
|
125
174
|
interface VectorExtras {
|
|
175
|
+
/** Template field for vector items */
|
|
126
176
|
itemField: FieldNode
|
|
177
|
+
/** Default value is empty array */
|
|
127
178
|
defaultValue: unknown[]
|
|
179
|
+
/** Get default value for a new item */
|
|
128
180
|
getItemDefault: () => unknown
|
|
181
|
+
/** Create a field node for an item at a specific index */
|
|
129
182
|
createItemField: (index: number, overrides?: { label?: string }) => FieldNode
|
|
130
183
|
}
|
|
131
184
|
|
|
132
185
|
interface BlobExtras {
|
|
186
|
+
/** Template field for blob bytes */
|
|
133
187
|
itemField: FieldNode
|
|
188
|
+
/** Accepted input formats */
|
|
134
189
|
acceptedFormats: ("hex" | "base64" | "file")[]
|
|
190
|
+
/** Upload limits */
|
|
135
191
|
limits: BlobLimits
|
|
192
|
+
/** Normalize hex input string */
|
|
136
193
|
normalizeHex: (input: string) => string
|
|
194
|
+
/** Validate blob input */
|
|
137
195
|
validateInput: (value: string | Uint8Array) => BlobValidationResult
|
|
196
|
+
/** Default value is empty string */
|
|
138
197
|
defaultValue: string
|
|
139
198
|
}
|
|
140
199
|
|
|
141
200
|
interface RecursiveExtras {
|
|
201
|
+
/** The recursive type name */
|
|
142
202
|
typeName: string
|
|
203
|
+
/** Lazily extract the inner type */
|
|
143
204
|
extract: () => FieldNode
|
|
205
|
+
/** Get default value of the inner type */
|
|
144
206
|
getInnerDefault: () => unknown
|
|
207
|
+
/** Default value is undefined */
|
|
145
208
|
defaultValue: undefined
|
|
146
209
|
}
|
|
147
210
|
|
|
148
211
|
interface PrincipalExtras {
|
|
212
|
+
/** Maximum Principal string length */
|
|
149
213
|
maxLength: number
|
|
214
|
+
/** Minimum Principal string length */
|
|
150
215
|
minLength: number
|
|
216
|
+
/** Detected text format */
|
|
151
217
|
format: TextFormat
|
|
218
|
+
/** Pre-computed HTML input props */
|
|
152
219
|
inputProps: PrimitiveInputProps
|
|
220
|
+
/** Default value is empty string */
|
|
153
221
|
defaultValue: string
|
|
154
222
|
}
|
|
155
223
|
|
|
156
224
|
interface NumberExtras {
|
|
225
|
+
/** Whether the number is unsigned (nat vs int) */
|
|
157
226
|
unsigned: boolean
|
|
227
|
+
/** Whether the number is a float */
|
|
158
228
|
isFloat: boolean
|
|
229
|
+
/** Bit width (8, 16, 32, 64) */
|
|
159
230
|
bits?: number
|
|
231
|
+
/** Minimum value as string */
|
|
160
232
|
min?: string
|
|
233
|
+
/** Maximum value as string */
|
|
161
234
|
max?: string
|
|
235
|
+
/** Detected number format */
|
|
162
236
|
format: NumberFormat
|
|
237
|
+
/** Pre-computed HTML input props */
|
|
163
238
|
inputProps: PrimitiveInputProps
|
|
239
|
+
/** Default value is empty string */
|
|
164
240
|
defaultValue: string
|
|
165
241
|
}
|
|
166
242
|
|
|
167
243
|
interface TextExtras {
|
|
244
|
+
/** Minimum text length */
|
|
168
245
|
minLength?: number
|
|
246
|
+
/** Maximum text length */
|
|
169
247
|
maxLength?: number
|
|
248
|
+
/** Whether to use multiline input */
|
|
170
249
|
multiline?: boolean
|
|
250
|
+
/** Detected text format */
|
|
171
251
|
format: TextFormat
|
|
252
|
+
/** Pre-computed HTML input props */
|
|
172
253
|
inputProps: PrimitiveInputProps
|
|
254
|
+
/** Default value is empty string */
|
|
173
255
|
defaultValue: string
|
|
174
256
|
}
|
|
175
257
|
|
|
176
258
|
interface BooleanExtras {
|
|
259
|
+
/** Pre-computed HTML input props */
|
|
177
260
|
inputProps: PrimitiveInputProps
|
|
261
|
+
/** Default value is false */
|
|
178
262
|
defaultValue: boolean
|
|
179
263
|
}
|
|
180
264
|
|
|
181
265
|
interface NullExtras {
|
|
266
|
+
/** Default value is null */
|
|
182
267
|
defaultValue: null
|
|
183
268
|
}
|
|
184
269
|
|
|
185
270
|
interface UnknownExtras {
|
|
271
|
+
/** Default value is undefined */
|
|
186
272
|
defaultValue: undefined
|
|
187
273
|
}
|
|
188
274
|
|
|
@@ -238,27 +324,33 @@ export type UnknownField = FieldNode<"unknown">
|
|
|
238
324
|
// Form Metadata
|
|
239
325
|
// ════════════════════════════════════════════════════════════════════════════
|
|
240
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Metadata for a single method's input arguments.
|
|
329
|
+
* Use this to generate dynamic forms for calling canister methods.
|
|
330
|
+
*/
|
|
241
331
|
export interface ArgumentsMeta<
|
|
242
332
|
A = BaseActor,
|
|
243
333
|
Name extends FunctionName<A> = FunctionName<A>,
|
|
244
334
|
> {
|
|
335
|
+
/** Whether this is a "query" or "update" call */
|
|
245
336
|
functionType: FunctionType
|
|
337
|
+
/** The method name as defined in the Candid interface */
|
|
246
338
|
functionName: Name
|
|
247
|
-
|
|
248
|
-
|
|
339
|
+
/** Array of field descriptors, one per argument */
|
|
340
|
+
args: FieldNode[]
|
|
341
|
+
/** Default values suitable for form initialization */
|
|
342
|
+
defaults: unknown[]
|
|
343
|
+
/** Zod schema for validating all arguments together */
|
|
249
344
|
schema: z.ZodTuple<[z.ZodTypeAny, ...z.ZodTypeAny[]]>
|
|
345
|
+
/** Number of arguments (0 for no-arg methods) */
|
|
250
346
|
argCount: number
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
export interface FormOptions {
|
|
255
|
-
defaultValues: unknown[]
|
|
256
|
-
validators: {
|
|
257
|
-
onChange: z.ZodTypeAny
|
|
258
|
-
onBlur: z.ZodTypeAny
|
|
259
|
-
}
|
|
347
|
+
/** True if this method takes no arguments */
|
|
348
|
+
isEmpty: boolean
|
|
260
349
|
}
|
|
261
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Service-level metadata mapping method names to their argument metadata.
|
|
353
|
+
*/
|
|
262
354
|
export type ArgumentsServiceMeta<A = BaseActor> = {
|
|
263
355
|
[K in FunctionName<A>]: ArgumentsMeta<A, K>
|
|
264
356
|
}
|
|
@@ -267,16 +359,15 @@ export type ArgumentsServiceMeta<A = BaseActor> = {
|
|
|
267
359
|
// Type Utilities
|
|
268
360
|
// ════════════════════════════════════════════════════════════════════════════
|
|
269
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Extract field type by VisitorDataType.
|
|
364
|
+
*/
|
|
270
365
|
export type FieldByType<T extends VisitorDataType> = Extract<
|
|
271
366
|
FieldNode,
|
|
272
367
|
{ type: T }
|
|
273
368
|
>
|
|
274
369
|
|
|
275
|
-
|
|
276
|
-
field: FieldByType<T>
|
|
277
|
-
renderField?: (child: FieldNode) => React.ReactNode
|
|
278
|
-
}
|
|
279
|
-
|
|
370
|
+
/** Compound field types that contain other fields */
|
|
280
371
|
export type CompoundField =
|
|
281
372
|
| RecordField
|
|
282
373
|
| VariantField
|
|
@@ -285,6 +376,7 @@ export type CompoundField =
|
|
|
285
376
|
| VectorField
|
|
286
377
|
| RecursiveField
|
|
287
378
|
|
|
379
|
+
/** Primitive field types with direct values */
|
|
288
380
|
export type PrimitiveField =
|
|
289
381
|
| PrincipalField
|
|
290
382
|
| NumberField
|
|
@@ -347,7 +347,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
347
347
|
// Validate options by resolving each option
|
|
348
348
|
const resolvedActive = field.resolve({ Active: null })
|
|
349
349
|
expect(resolvedActive.selected).toBe("Active")
|
|
350
|
-
expect(resolvedActive.
|
|
350
|
+
expect(resolvedActive.selectedValue.type).toBe("null")
|
|
351
351
|
const resolvedInactive = field.resolve({ Inactive: null })
|
|
352
352
|
expect(resolvedInactive.selected).toBe("Inactive")
|
|
353
353
|
const resolvedPending = field.resolve({ Pending: null })
|
|
@@ -396,14 +396,14 @@ describe("ResultFieldVisitor", () => {
|
|
|
396
396
|
Transfer: { from: "aaaaa-aa", to: "bbbbb-bb", amount: BigInt(1) },
|
|
397
397
|
})
|
|
398
398
|
expect(transferResolved.selected).toBe("Transfer")
|
|
399
|
-
expect(transferResolved.
|
|
399
|
+
expect(transferResolved.selectedValue.type).toBe("record")
|
|
400
400
|
expect(
|
|
401
|
-
Object.keys((transferResolved.
|
|
401
|
+
Object.keys((transferResolved.selectedValue as RecordNode).fields)
|
|
402
402
|
).toHaveLength(3)
|
|
403
403
|
|
|
404
404
|
const approveResolved = field.resolve({ Approve: BigInt(5) })
|
|
405
405
|
expect(approveResolved.selected).toBe("Approve")
|
|
406
|
-
expect(approveResolved.
|
|
406
|
+
expect(approveResolved.selectedValue.type).toBe("number")
|
|
407
407
|
})
|
|
408
408
|
|
|
409
409
|
it("should detect Result variant (Ok/Err)", () => {
|
|
@@ -425,13 +425,13 @@ describe("ResultFieldVisitor", () => {
|
|
|
425
425
|
|
|
426
426
|
const okResolved = field.resolve({ Ok: BigInt(1) })
|
|
427
427
|
expect(okResolved.selected).toBe("Ok")
|
|
428
|
-
expect(okResolved.
|
|
429
|
-
expect(okResolved.
|
|
428
|
+
expect(okResolved.selectedValue.type).toBe("number")
|
|
429
|
+
expect(okResolved.selectedValue.displayType).toBe("string")
|
|
430
430
|
|
|
431
431
|
const errResolved = field.resolve({ Err: "error" })
|
|
432
432
|
expect(errResolved.selected).toBe("Err")
|
|
433
|
-
expect(errResolved.
|
|
434
|
-
expect(errResolved.
|
|
433
|
+
expect(errResolved.selectedValue.type).toBe("text")
|
|
434
|
+
expect(errResolved.selectedValue.displayType).toBe("string")
|
|
435
435
|
})
|
|
436
436
|
|
|
437
437
|
it("should detect complex Result variant", () => {
|
|
@@ -474,11 +474,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
474
474
|
Ok: { id: BigInt(1), data: new Uint8Array([1, 2, 3]) },
|
|
475
475
|
})
|
|
476
476
|
expect(okResolved.selected).toBe("Ok")
|
|
477
|
-
expect(okResolved.
|
|
477
|
+
expect(okResolved.selectedValue.type).toBe("record")
|
|
478
478
|
|
|
479
479
|
const errResolved = field.resolve({ Err: { NotFound: null } })
|
|
480
480
|
expect(errResolved.selected).toBe("Err")
|
|
481
|
-
expect(errResolved.
|
|
481
|
+
expect(errResolved.selectedValue.type).toBe("variant")
|
|
482
482
|
})
|
|
483
483
|
|
|
484
484
|
it("should not detect non-Result variant with Ok and other options", () => {
|
|
@@ -944,18 +944,18 @@ describe("ResultFieldVisitor", () => {
|
|
|
944
944
|
expect(field.displayType).toBe("result")
|
|
945
945
|
|
|
946
946
|
const okResolved = field.resolve({ Ok: BigInt(123) })
|
|
947
|
-
if ((okResolved.
|
|
947
|
+
if ((okResolved.selectedValue as ResolvedNode).type !== "number") {
|
|
948
948
|
throw new Error("Ok field is not number")
|
|
949
949
|
}
|
|
950
|
-
expect((okResolved.
|
|
951
|
-
expect((okResolved.
|
|
950
|
+
expect((okResolved.selectedValue as ResolvedNode).candidType).toBe("nat")
|
|
951
|
+
expect((okResolved.selectedValue as ResolvedNode).displayType).toBe(
|
|
952
952
|
"string"
|
|
953
953
|
)
|
|
954
954
|
|
|
955
955
|
const errResolved = field.resolve({
|
|
956
956
|
Err: { InsufficientFunds: { balance: BigInt(0) } },
|
|
957
957
|
})
|
|
958
|
-
const innerErr = errResolved.
|
|
958
|
+
const innerErr = errResolved.selectedValue as ResolvedNode
|
|
959
959
|
expect(innerErr.type).toBe("variant")
|
|
960
960
|
const insufficient = (innerErr as any).resolve({
|
|
961
961
|
InsufficientFunds: { balance: BigInt(0) },
|
|
@@ -1269,7 +1269,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1269
1269
|
)
|
|
1270
1270
|
|
|
1271
1271
|
expect(() => field.resolve(null)).toThrow(
|
|
1272
|
-
"Expected record
|
|
1272
|
+
"Expected record, but got null"
|
|
1273
1273
|
)
|
|
1274
1274
|
})
|
|
1275
1275
|
})
|
|
@@ -1292,7 +1292,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1292
1292
|
const resolved = field.resolve({ Ok: "Success" })
|
|
1293
1293
|
expect(resolved.type).toBe(field.type)
|
|
1294
1294
|
expect(resolved.selected).toBe("Ok")
|
|
1295
|
-
const data = resolved.
|
|
1295
|
+
const data = resolved.selectedValue as ResolvedNode
|
|
1296
1296
|
expect(data.value).toBe("Success")
|
|
1297
1297
|
})
|
|
1298
1298
|
|
|
@@ -1313,7 +1313,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1313
1313
|
const resolved = field.resolve({ Err: "Something went wrong" })
|
|
1314
1314
|
|
|
1315
1315
|
expect(resolved.selected).toBe("Err")
|
|
1316
|
-
const data = resolved.
|
|
1316
|
+
const data = resolved.selectedValue as ResolvedNode
|
|
1317
1317
|
expect(data.value).toBe("Something went wrong")
|
|
1318
1318
|
})
|
|
1319
1319
|
|
|
@@ -1329,7 +1329,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1329
1329
|
)
|
|
1330
1330
|
|
|
1331
1331
|
expect(() => field.resolve(null)).toThrow(
|
|
1332
|
-
"Expected variant
|
|
1332
|
+
"Expected variant, but got null"
|
|
1333
1333
|
)
|
|
1334
1334
|
})
|
|
1335
1335
|
})
|
|
@@ -1358,7 +1358,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1358
1358
|
const field = visitor.visitTuple(tupleType, [IDL.Text, IDL.Nat], "pair")
|
|
1359
1359
|
|
|
1360
1360
|
expect(() => field.resolve(null)).toThrow(
|
|
1361
|
-
"Expected tuple
|
|
1361
|
+
"Expected tuple, but got null"
|
|
1362
1362
|
)
|
|
1363
1363
|
})
|
|
1364
1364
|
})
|
|
@@ -1416,7 +1416,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1416
1416
|
const field = visitor.visitVec(vecType, IDL.Text, "items")
|
|
1417
1417
|
|
|
1418
1418
|
expect(() => field.resolve(null)).toThrow(
|
|
1419
|
-
"Expected vector
|
|
1419
|
+
"Expected vector, but got null"
|
|
1420
1420
|
)
|
|
1421
1421
|
})
|
|
1422
1422
|
})
|
|
@@ -1612,7 +1612,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1612
1612
|
|
|
1613
1613
|
const okValue = okResult.results[0] as ResolvedNode
|
|
1614
1614
|
expect((okValue as any).selected).toBe("Ok")
|
|
1615
|
-
expect(((okValue as any).
|
|
1615
|
+
expect(((okValue as any).selectedValue as ResolvedNode).value).toBe(
|
|
1616
1616
|
"12345"
|
|
1617
1617
|
)
|
|
1618
1618
|
|
|
@@ -1622,7 +1622,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1622
1622
|
})
|
|
1623
1623
|
const errValue = errResult.results[0] as ResolvedNode
|
|
1624
1624
|
expect((errValue as any).selected).toBe("Err")
|
|
1625
|
-
expect(((errValue as any).
|
|
1625
|
+
expect(((errValue as any).selectedValue as ResolvedNode).value).toBe(
|
|
1626
1626
|
"Insufficient funds"
|
|
1627
1627
|
)
|
|
1628
1628
|
})
|
|
@@ -1727,7 +1727,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1727
1727
|
|
|
1728
1728
|
const successValue = successResult.results[0] as ResolvedNode
|
|
1729
1729
|
expect((successValue as any).selected).toBe("Ok")
|
|
1730
|
-
expect(((successValue as any).
|
|
1730
|
+
expect(((successValue as any).selectedValue as ResolvedNode).value).toBe(
|
|
1731
1731
|
"1000"
|
|
1732
1732
|
)
|
|
1733
1733
|
|
|
@@ -1738,7 +1738,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1738
1738
|
const errorValue = errorResult.results[0] as ResolvedNode
|
|
1739
1739
|
expect((errorValue as any).selected).toBe("Err")
|
|
1740
1740
|
|
|
1741
|
-
const val = (errorValue as any).
|
|
1741
|
+
const val = (errorValue as any).selectedValue as ResolvedNode
|
|
1742
1742
|
if (typeof val !== "object" || val === null || !("selected" in val)) {
|
|
1743
1743
|
throw new Error("Expected variant value object")
|
|
1744
1744
|
}
|
|
@@ -1876,7 +1876,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1876
1876
|
|
|
1877
1877
|
const variantValue = result.results[0] as ResolvedNode
|
|
1878
1878
|
expect((variantValue as any).selected).toBe("Ok")
|
|
1879
|
-
const innerVal = (variantValue as any).
|
|
1879
|
+
const innerVal = (variantValue as any).selectedValue as ResolvedNode
|
|
1880
1880
|
expect(innerVal.value).toBe("12345")
|
|
1881
1881
|
})
|
|
1882
1882
|
|
|
@@ -2042,7 +2042,7 @@ describe("ResultFieldVisitor Reproduction - User reported issue", () => {
|
|
|
2042
2042
|
const resolved = field.resolve(transformedData)
|
|
2043
2043
|
|
|
2044
2044
|
expect(resolved.selected).toBe("Quorum")
|
|
2045
|
-
expect(resolved.
|
|
2045
|
+
expect(resolved.selectedValue.value).toBe("some text")
|
|
2046
2046
|
})
|
|
2047
2047
|
|
|
2048
2048
|
it("should handle already transformed optional data (unwrapped)", () => {
|
|
@@ -2071,7 +2071,7 @@ describe("ResultFieldVisitor Reproduction - User reported issue", () => {
|
|
|
2071
2071
|
)
|
|
2072
2072
|
|
|
2073
2073
|
expect(() => field.resolve({ C: null })).toThrow(
|
|
2074
|
-
/Option C not found
|
|
2074
|
+
/Option "C" not found. Available: A, B/
|
|
2075
2075
|
)
|
|
2076
2076
|
})
|
|
2077
2077
|
|
|
@@ -2101,7 +2101,7 @@ describe("ResultFieldVisitor Reproduction - User reported issue", () => {
|
|
|
2101
2101
|
const variantNode = resolved.inner as VariantNode
|
|
2102
2102
|
|
|
2103
2103
|
expect(variantNode.selected).toBe("Quorum")
|
|
2104
|
-
expect(variantNode.
|
|
2104
|
+
expect(variantNode.selectedValue.type).toBe("record")
|
|
2105
2105
|
})
|
|
2106
2106
|
|
|
2107
2107
|
it("should handle deeply nested recursive variant with transformed data", () => {
|
|
@@ -2130,7 +2130,7 @@ describe("ResultFieldVisitor Reproduction - User reported issue", () => {
|
|
|
2130
2130
|
const variantNode = resolved.inner as VariantNode
|
|
2131
2131
|
expect(variantNode.selected).toBe("Nested")
|
|
2132
2132
|
|
|
2133
|
-
const nestedResolved = variantNode.
|
|
2133
|
+
const nestedResolved = variantNode.selectedValue as RecursiveNode
|
|
2134
2134
|
const innerVariant = nestedResolved.inner as VariantNode
|
|
2135
2135
|
expect(innerVariant.selected).toBe("Quorum")
|
|
2136
2136
|
})
|