@ic-reactor/candid 3.0.14-beta.0 → 3.0.14-beta.1
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/visitor/arguments/helpers.d.ts +2 -2
- package/dist/visitor/arguments/helpers.d.ts.map +1 -1
- package/dist/visitor/arguments/index.d.ts.map +1 -1
- package/dist/visitor/arguments/index.js +4 -13
- package/dist/visitor/arguments/index.js.map +1 -1
- package/dist/visitor/arguments/types.d.ts +32 -128
- package/dist/visitor/arguments/types.d.ts.map +1 -1
- package/dist/visitor/constants.d.ts.map +1 -1
- package/dist/visitor/constants.js +19 -17
- package/dist/visitor/constants.js.map +1 -1
- package/package.json +2 -2
- package/src/visitor/arguments/helpers.ts +2 -2
- package/src/visitor/arguments/index.test.ts +61 -17
- package/src/visitor/arguments/index.ts +7 -14
- package/src/visitor/arguments/types.ts +113 -214
- package/src/visitor/constants.ts +24 -15
- package/src/visitor/returns/index.test.ts +1 -1
|
@@ -2,21 +2,14 @@ import type { BaseActor, FunctionName, FunctionType } from "@ic-reactor/core"
|
|
|
2
2
|
import * as z from "zod"
|
|
3
3
|
import type { VisitorDataType, TextFormat, NumberFormat } from "../types"
|
|
4
4
|
|
|
5
|
-
export type { TextFormat, NumberFormat }
|
|
5
|
+
export type { VisitorDataType, TextFormat, NumberFormat }
|
|
6
6
|
|
|
7
7
|
// ════════════════════════════════════════════════════════════════════════════
|
|
8
|
-
//
|
|
9
|
-
// ════════════════════════════════════════════════════════════════════════════
|
|
10
|
-
|
|
11
|
-
export type ArgumentFieldType = VisitorDataType
|
|
12
|
-
|
|
13
|
-
// ════════════════════════════════════════════════════════════════════════════
|
|
14
|
-
// Component Type Hints
|
|
8
|
+
// Component & UI Types
|
|
15
9
|
// ════════════════════════════════════════════════════════════════════════════
|
|
16
10
|
|
|
17
11
|
/**
|
|
18
12
|
* Suggested component type for rendering the field.
|
|
19
|
-
* This eliminates the need for switch statements in the frontend.
|
|
20
13
|
*/
|
|
21
14
|
export type FieldComponentType =
|
|
22
15
|
| "record-container"
|
|
@@ -33,13 +26,8 @@ export type FieldComponentType =
|
|
|
33
26
|
| "recursive-lazy"
|
|
34
27
|
| "unknown-fallback"
|
|
35
28
|
|
|
36
|
-
// ════════════════════════════════════════════════════════════════════════════
|
|
37
|
-
// Render Hints for UI Rendering Strategy
|
|
38
|
-
// ════════════════════════════════════════════════════════════════════════════
|
|
39
|
-
|
|
40
29
|
/**
|
|
41
30
|
* Input type hints for HTML input elements.
|
|
42
|
-
* Used by primitive fields to suggest the appropriate input type.
|
|
43
31
|
*/
|
|
44
32
|
export type InputType =
|
|
45
33
|
| "text"
|
|
@@ -51,49 +39,28 @@ export type InputType =
|
|
|
51
39
|
|
|
52
40
|
/**
|
|
53
41
|
* Rendering hints for the UI.
|
|
54
|
-
* Eliminates the need for frontend to maintain COMPLEX_TYPES arrays.
|
|
55
42
|
*/
|
|
56
43
|
export interface RenderHint {
|
|
57
|
-
/** Whether this field has its own container/card styling (compound types) */
|
|
58
44
|
isCompound: boolean
|
|
59
|
-
/** Whether this is a leaf input (primitive types) */
|
|
60
45
|
isPrimitive: boolean
|
|
61
|
-
/** Suggested input type for HTML input elements */
|
|
62
46
|
inputType?: InputType
|
|
63
|
-
/** Description or help text for the field (derived from Candid) */
|
|
64
47
|
description?: string
|
|
65
48
|
}
|
|
66
49
|
|
|
67
|
-
// ════════════════════════════════════════════════════════════════════════════
|
|
68
|
-
// Primitive Input Props
|
|
69
|
-
// ════════════════════════════════════════════════════════════════════════════
|
|
70
|
-
|
|
71
50
|
/**
|
|
72
51
|
* Pre-computed HTML input props for primitive fields.
|
|
73
|
-
* Can be spread directly onto an input element.
|
|
74
52
|
*/
|
|
75
53
|
export interface PrimitiveInputProps {
|
|
76
|
-
/** HTML input type - includes format-specific types */
|
|
77
54
|
type?: "text" | "number" | "checkbox" | "email" | "url" | "tel"
|
|
78
|
-
/** Placeholder text */
|
|
79
55
|
placeholder?: string
|
|
80
|
-
/** Minimum value for number inputs */
|
|
81
56
|
min?: string | number
|
|
82
|
-
/** Maximum value for number inputs */
|
|
83
57
|
max?: string | number
|
|
84
|
-
/** Step value for number inputs */
|
|
85
58
|
step?: string | number
|
|
86
|
-
/** Pattern for text inputs (e.g., phone numbers) */
|
|
87
59
|
pattern?: string
|
|
88
|
-
/** Input mode for virtual keyboards */
|
|
89
60
|
inputMode?: "text" | "numeric" | "decimal" | "email" | "tel" | "url"
|
|
90
|
-
/** Autocomplete hint */
|
|
91
61
|
autoComplete?: string
|
|
92
|
-
/** Whether to check spelling */
|
|
93
62
|
spellCheck?: boolean
|
|
94
|
-
/** Minimum length for text inputs */
|
|
95
63
|
minLength?: number
|
|
96
|
-
/** Maximum length for text inputs */
|
|
97
64
|
maxLength?: number
|
|
98
65
|
}
|
|
99
66
|
|
|
@@ -102,196 +69,156 @@ export interface PrimitiveInputProps {
|
|
|
102
69
|
// ════════════════════════════════════════════════════════════════════════════
|
|
103
70
|
|
|
104
71
|
interface FieldBase<T extends VisitorDataType = VisitorDataType> {
|
|
105
|
-
/** The field type */
|
|
106
72
|
type: T
|
|
107
|
-
/** Raw label from Candid: "__arg0", "_0_" */
|
|
108
73
|
label: string
|
|
109
|
-
/** Pre-formatted display label for UI rendering */
|
|
110
74
|
displayLabel: string
|
|
111
|
-
/** Form field name path for binding */
|
|
112
75
|
name: string
|
|
113
|
-
/** Suggested component type for rendering this field */
|
|
114
76
|
component: FieldComponentType
|
|
115
|
-
/** Rendering hints for UI strategy */
|
|
116
77
|
renderHint: RenderHint
|
|
117
|
-
/** Zod schema for field validation */
|
|
118
78
|
schema: z.ZodTypeAny
|
|
119
|
-
/** Original Candid type name for reference */
|
|
120
79
|
candidType: string
|
|
80
|
+
defaultValue: unknown
|
|
121
81
|
}
|
|
122
82
|
|
|
123
83
|
// ════════════════════════════════════════════════════════════════════════════
|
|
124
|
-
//
|
|
84
|
+
// Field Extras
|
|
125
85
|
// ════════════════════════════════════════════════════════════════════════════
|
|
126
86
|
|
|
127
|
-
/**
|
|
128
|
-
* Blob field size limits.
|
|
129
|
-
*/
|
|
130
87
|
export interface BlobLimits {
|
|
131
|
-
/** Maximum bytes when entering as hex (e.g., 512 bytes) */
|
|
132
88
|
maxHexBytes: number
|
|
133
|
-
/** Maximum file size in bytes (e.g., 2MB ICP limit) */
|
|
134
89
|
maxFileBytes: number
|
|
135
|
-
/** Maximum hex display length before truncation */
|
|
136
90
|
maxHexDisplayLength: number
|
|
137
91
|
}
|
|
138
92
|
|
|
139
|
-
/**
|
|
140
|
-
* Validation result for blob input.
|
|
141
|
-
*/
|
|
142
93
|
export interface BlobValidationResult {
|
|
143
|
-
/** Whether the input is valid */
|
|
144
94
|
valid: boolean
|
|
145
|
-
/** Error message if invalid */
|
|
146
95
|
error?: string
|
|
147
96
|
}
|
|
148
97
|
|
|
98
|
+
interface RecordExtras {
|
|
99
|
+
fields: FieldNode[]
|
|
100
|
+
defaultValue: Record<string, unknown>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface VariantExtras {
|
|
104
|
+
fields: FieldNode[]
|
|
105
|
+
defaultOption: string
|
|
106
|
+
defaultValue: Record<string, unknown>
|
|
107
|
+
getOptionDefault: (option: string) => Record<string, unknown>
|
|
108
|
+
getField: (option: string) => FieldNode
|
|
109
|
+
getSelectedOption: (value: Record<string, unknown>) => string
|
|
110
|
+
getSelectedField: (value: Record<string, unknown>) => FieldNode
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface TupleExtras {
|
|
114
|
+
fields: FieldNode[]
|
|
115
|
+
defaultValue: unknown[]
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface OptionalExtras {
|
|
119
|
+
innerField: FieldNode
|
|
120
|
+
defaultValue: null
|
|
121
|
+
getInnerDefault: () => unknown
|
|
122
|
+
isEnabled: (value: unknown) => boolean
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
interface VectorExtras {
|
|
126
|
+
itemField: FieldNode
|
|
127
|
+
defaultValue: unknown[]
|
|
128
|
+
getItemDefault: () => unknown
|
|
129
|
+
createItemField: (index: number, overrides?: { label?: string }) => FieldNode
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
interface BlobExtras {
|
|
133
|
+
itemField: FieldNode
|
|
134
|
+
acceptedFormats: ("hex" | "base64" | "file")[]
|
|
135
|
+
limits: BlobLimits
|
|
136
|
+
normalizeHex: (input: string) => string
|
|
137
|
+
validateInput: (value: string | Uint8Array) => BlobValidationResult
|
|
138
|
+
defaultValue: string
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
interface RecursiveExtras {
|
|
142
|
+
typeName: string
|
|
143
|
+
extract: () => FieldNode
|
|
144
|
+
getInnerDefault: () => unknown
|
|
145
|
+
defaultValue: undefined
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
interface PrincipalExtras {
|
|
149
|
+
maxLength: number
|
|
150
|
+
minLength: number
|
|
151
|
+
format: TextFormat
|
|
152
|
+
inputProps: PrimitiveInputProps
|
|
153
|
+
defaultValue: string
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
interface NumberExtras {
|
|
157
|
+
unsigned: boolean
|
|
158
|
+
isFloat: boolean
|
|
159
|
+
bits?: number
|
|
160
|
+
min?: string
|
|
161
|
+
max?: string
|
|
162
|
+
format: NumberFormat
|
|
163
|
+
inputProps: PrimitiveInputProps
|
|
164
|
+
defaultValue: string
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface TextExtras {
|
|
168
|
+
minLength?: number
|
|
169
|
+
maxLength?: number
|
|
170
|
+
multiline?: boolean
|
|
171
|
+
format: TextFormat
|
|
172
|
+
inputProps: PrimitiveInputProps
|
|
173
|
+
defaultValue: string
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
interface BooleanExtras {
|
|
177
|
+
inputProps: PrimitiveInputProps
|
|
178
|
+
defaultValue: boolean
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
interface NullExtras {
|
|
182
|
+
defaultValue: null
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface UnknownExtras {
|
|
186
|
+
defaultValue: undefined
|
|
187
|
+
}
|
|
188
|
+
|
|
149
189
|
type FieldExtras<T extends VisitorDataType> = T extends "record"
|
|
150
|
-
?
|
|
151
|
-
/** Child fields in the record */
|
|
152
|
-
fields: FieldNode[]
|
|
153
|
-
/** Map of field label to its metadata for quick lookup */
|
|
154
|
-
fieldMap: Map<string, FieldNode>
|
|
155
|
-
defaultValue: Record<string, unknown>
|
|
156
|
-
}
|
|
190
|
+
? RecordExtras
|
|
157
191
|
: T extends "variant"
|
|
158
|
-
?
|
|
159
|
-
/** All variant option fields */
|
|
160
|
-
fields: FieldNode[]
|
|
161
|
-
/** List of variant option names */
|
|
162
|
-
options: string[]
|
|
163
|
-
/** Default selected option */
|
|
164
|
-
defaultOption: string
|
|
165
|
-
/** Map of option name to its field metadata */
|
|
166
|
-
optionMap: Map<string, FieldNode>
|
|
167
|
-
defaultValue: Record<string, unknown>
|
|
168
|
-
/** Get default value for a specific option */
|
|
169
|
-
getOptionDefault: (option: string) => Record<string, unknown>
|
|
170
|
-
/** Get the field for a specific option */
|
|
171
|
-
getField: (option: string) => FieldNode
|
|
172
|
-
/** Get the currently selected option from a value */
|
|
173
|
-
getSelectedOption: (value: Record<string, unknown>) => string
|
|
174
|
-
/** Get the selected field from a value */
|
|
175
|
-
getSelectedField: (value: Record<string, unknown>) => FieldNode
|
|
176
|
-
}
|
|
192
|
+
? VariantExtras
|
|
177
193
|
: T extends "tuple"
|
|
178
|
-
?
|
|
179
|
-
/** Tuple element fields in order */
|
|
180
|
-
fields: FieldNode[]
|
|
181
|
-
defaultValue: unknown[]
|
|
182
|
-
}
|
|
194
|
+
? TupleExtras
|
|
183
195
|
: T extends "optional"
|
|
184
|
-
?
|
|
185
|
-
/** The inner field when value is present */
|
|
186
|
-
innerField: FieldNode
|
|
187
|
-
defaultValue: null
|
|
188
|
-
/** Get default value when enabling the optional */
|
|
189
|
-
getInnerDefault: () => unknown
|
|
190
|
-
/** Check if a value represents an enabled optional */
|
|
191
|
-
isEnabled: (value: unknown) => boolean
|
|
192
|
-
}
|
|
196
|
+
? OptionalExtras
|
|
193
197
|
: T extends "vector"
|
|
194
|
-
?
|
|
195
|
-
/** Template field for vector items */
|
|
196
|
-
itemField: FieldNode
|
|
197
|
-
defaultValue: unknown[]
|
|
198
|
-
/** Get a new item with default values */
|
|
199
|
-
getItemDefault: () => unknown
|
|
200
|
-
/** Create a properly configured item field for a specific index */
|
|
201
|
-
createItemField: (
|
|
202
|
-
index: number,
|
|
203
|
-
overrides?: { label?: string }
|
|
204
|
-
) => FieldNode
|
|
205
|
-
}
|
|
198
|
+
? VectorExtras
|
|
206
199
|
: T extends "blob"
|
|
207
|
-
?
|
|
208
|
-
/** Item field for individual bytes (nat8) */
|
|
209
|
-
itemField: FieldNode
|
|
210
|
-
/** Accepted input formats */
|
|
211
|
-
acceptedFormats: ("hex" | "base64" | "file")[]
|
|
212
|
-
/** Size limits for blob input */
|
|
213
|
-
limits: BlobLimits
|
|
214
|
-
/** Normalize hex input */
|
|
215
|
-
normalizeHex: (input: string) => string
|
|
216
|
-
/** Validate blob input value */
|
|
217
|
-
validateInput: (
|
|
218
|
-
value: string | Uint8Array
|
|
219
|
-
) => BlobValidationResult
|
|
220
|
-
defaultValue: string
|
|
221
|
-
}
|
|
200
|
+
? BlobExtras
|
|
222
201
|
: T extends "recursive"
|
|
223
|
-
?
|
|
224
|
-
/** Type name for the recursive type */
|
|
225
|
-
typeName: string
|
|
226
|
-
/** Lazily extract the inner field to prevent infinite loops */
|
|
227
|
-
extract: () => FieldNode
|
|
228
|
-
/** Get default value for the recursive type (evaluates lazily) */
|
|
229
|
-
getInnerDefault: () => unknown
|
|
230
|
-
defaultValue: undefined
|
|
231
|
-
}
|
|
202
|
+
? RecursiveExtras
|
|
232
203
|
: T extends "principal"
|
|
233
|
-
?
|
|
234
|
-
maxLength: number
|
|
235
|
-
minLength: number
|
|
236
|
-
/** Detected format based on label heuristics */
|
|
237
|
-
format: TextFormat
|
|
238
|
-
/** Pre-computed HTML input props */
|
|
239
|
-
inputProps: PrimitiveInputProps
|
|
240
|
-
defaultValue: string
|
|
241
|
-
}
|
|
204
|
+
? PrincipalExtras
|
|
242
205
|
: T extends "number"
|
|
243
|
-
?
|
|
244
|
-
/** Whether this is an unsigned type */
|
|
245
|
-
unsigned: boolean
|
|
246
|
-
/** Whether this is a floating point type */
|
|
247
|
-
isFloat: boolean
|
|
248
|
-
/** Bit width if applicable (8, 16, 32, 64, or undefined for unbounded) */
|
|
249
|
-
bits?: number
|
|
250
|
-
/** Minimum value constraint (for bounded types) */
|
|
251
|
-
min?: string
|
|
252
|
-
/** Maximum value constraint (for bounded types) */
|
|
253
|
-
max?: string
|
|
254
|
-
/** Detected format based on label heuristics */
|
|
255
|
-
format: NumberFormat
|
|
256
|
-
/** Pre-computed HTML input props */
|
|
257
|
-
inputProps: PrimitiveInputProps
|
|
258
|
-
defaultValue: string
|
|
259
|
-
}
|
|
206
|
+
? NumberExtras
|
|
260
207
|
: T extends "text"
|
|
261
|
-
?
|
|
262
|
-
/** Minimum length constraint */
|
|
263
|
-
minLength?: number
|
|
264
|
-
/** Maximum length constraint */
|
|
265
|
-
maxLength?: number
|
|
266
|
-
/** Whether to render as multiline textarea */
|
|
267
|
-
multiline?: boolean
|
|
268
|
-
/** Detected format based on label heuristics */
|
|
269
|
-
format: TextFormat
|
|
270
|
-
/** Pre-computed HTML input props */
|
|
271
|
-
inputProps: PrimitiveInputProps
|
|
272
|
-
defaultValue: string
|
|
273
|
-
}
|
|
208
|
+
? TextExtras
|
|
274
209
|
: T extends "boolean"
|
|
275
|
-
?
|
|
276
|
-
/** Pre-computed HTML input props */
|
|
277
|
-
inputProps: PrimitiveInputProps
|
|
278
|
-
defaultValue: boolean
|
|
279
|
-
}
|
|
210
|
+
? BooleanExtras
|
|
280
211
|
: T extends "null"
|
|
281
|
-
?
|
|
282
|
-
defaultValue: null
|
|
283
|
-
}
|
|
212
|
+
? NullExtras
|
|
284
213
|
: T extends "unknown"
|
|
285
|
-
?
|
|
286
|
-
defaultValue: undefined
|
|
287
|
-
}
|
|
214
|
+
? UnknownExtras
|
|
288
215
|
: {}
|
|
289
216
|
|
|
290
217
|
/**
|
|
291
218
|
* A unified field node that contains all metadata needed for rendering.
|
|
292
219
|
*/
|
|
293
220
|
export type FieldNode<T extends VisitorDataType = VisitorDataType> =
|
|
294
|
-
FieldBase<T> & FieldExtras<T>
|
|
221
|
+
T extends any ? FieldBase<T> & FieldExtras<T> : never
|
|
295
222
|
|
|
296
223
|
export type RecordField = FieldNode<"record">
|
|
297
224
|
export type VariantField = FieldNode<"variant">
|
|
@@ -308,75 +235,48 @@ export type NullField = FieldNode<"null">
|
|
|
308
235
|
export type UnknownField = FieldNode<"unknown">
|
|
309
236
|
|
|
310
237
|
// ════════════════════════════════════════════════════════════════════════════
|
|
311
|
-
// Form Metadata
|
|
238
|
+
// Form Metadata
|
|
312
239
|
// ════════════════════════════════════════════════════════════════════════════
|
|
313
240
|
|
|
314
|
-
/**
|
|
315
|
-
* Form metadata for a Candid method.
|
|
316
|
-
* Contains all information needed to create a TanStack Form instance.
|
|
317
|
-
*/
|
|
318
241
|
export interface ArgumentsMeta<
|
|
319
242
|
A = BaseActor,
|
|
320
243
|
Name extends FunctionName<A> = FunctionName<A>,
|
|
321
244
|
> {
|
|
322
|
-
/** Whether this is a "query" or "update" function */
|
|
323
245
|
functionType: FunctionType
|
|
324
|
-
/** The function name */
|
|
325
246
|
functionName: Name
|
|
326
|
-
/** Argument field definitions for rendering */
|
|
327
247
|
fields: FieldNode[]
|
|
328
|
-
/** Default values for all arguments (as a tuple) */
|
|
329
248
|
defaultValues: unknown[]
|
|
330
|
-
/** Combined Zod schema for all arguments */
|
|
331
249
|
schema: z.ZodTuple<[z.ZodTypeAny, ...z.ZodTypeAny[]]>
|
|
332
|
-
/** Number of arguments */
|
|
333
250
|
argCount: number
|
|
334
|
-
/** Whether the function takes no arguments */
|
|
335
251
|
isNoArgs: boolean
|
|
336
252
|
}
|
|
337
253
|
|
|
338
|
-
/**
|
|
339
|
-
* Options that can be spread into useForm().
|
|
340
|
-
* Pre-configured with defaultValues and validators.
|
|
341
|
-
*/
|
|
342
254
|
export interface FormOptions {
|
|
343
|
-
/** Initial form values */
|
|
344
255
|
defaultValues: unknown[]
|
|
345
|
-
/** Validators using the Zod schema */
|
|
346
256
|
validators: {
|
|
347
257
|
onChange: z.ZodTypeAny
|
|
348
258
|
onBlur: z.ZodTypeAny
|
|
349
259
|
}
|
|
350
260
|
}
|
|
351
261
|
|
|
352
|
-
/**
|
|
353
|
-
* Service-level form metadata.
|
|
354
|
-
* Maps each method name to its FormMeta.
|
|
355
|
-
*/
|
|
356
262
|
export type ArgumentsServiceMeta<A = BaseActor> = {
|
|
357
263
|
[K in FunctionName<A>]: ArgumentsMeta<A, K>
|
|
358
264
|
}
|
|
359
265
|
|
|
360
266
|
// ════════════════════════════════════════════════════════════════════════════
|
|
361
|
-
// Type Utilities
|
|
267
|
+
// Type Utilities
|
|
362
268
|
// ════════════════════════════════════════════════════════════════════════════
|
|
363
269
|
|
|
364
|
-
|
|
365
|
-
export type FieldByType<T extends ArgumentFieldType> = Extract<
|
|
270
|
+
export type FieldByType<T extends VisitorDataType> = Extract<
|
|
366
271
|
FieldNode,
|
|
367
272
|
{ type: T }
|
|
368
273
|
>
|
|
369
274
|
|
|
370
|
-
|
|
371
|
-
* Props type helper for field components.
|
|
372
|
-
* Use this to type your field components for better DX.
|
|
373
|
-
*/
|
|
374
|
-
export type FieldProps<T extends ArgumentFieldType> = {
|
|
275
|
+
export type FieldProps<T extends VisitorDataType> = {
|
|
375
276
|
field: FieldByType<T>
|
|
376
277
|
renderField?: (child: FieldNode) => React.ReactNode
|
|
377
278
|
}
|
|
378
279
|
|
|
379
|
-
/** Compound field types that contain other fields */
|
|
380
280
|
export type CompoundField =
|
|
381
281
|
| RecordField
|
|
382
282
|
| VariantField
|
|
@@ -385,7 +285,6 @@ export type CompoundField =
|
|
|
385
285
|
| VectorField
|
|
386
286
|
| RecursiveField
|
|
387
287
|
|
|
388
|
-
/** Primitive field types */
|
|
389
288
|
export type PrimitiveField =
|
|
390
289
|
| PrincipalField
|
|
391
290
|
| NumberField
|
package/src/visitor/constants.ts
CHANGED
|
@@ -30,27 +30,36 @@ const CYCLE_KEYS_REGEX = new RegExp(
|
|
|
30
30
|
"i"
|
|
31
31
|
)
|
|
32
32
|
|
|
33
|
-
const EMAIL_KEYS_REGEX = /email|mail/i
|
|
34
|
-
const PHONE_KEYS_REGEX = /phone|tel|mobile/i
|
|
35
|
-
const URL_KEYS_REGEX = /url|link|website/i
|
|
36
|
-
const UUID_KEYS_REGEX = /uuid|guid/i
|
|
37
|
-
const BITCOIN_KEYS_REGEX = /bitcoin|btc/i
|
|
38
|
-
const ETHEREUM_KEYS_REGEX = /ethereum|eth/i
|
|
39
33
|
const ACCOUNT_ID_KEYS_REGEX =
|
|
40
|
-
/
|
|
41
|
-
|
|
34
|
+
/account_identifier|ledger_account|block_hash|transaction_hash|tx_hash/i
|
|
35
|
+
|
|
36
|
+
const tokenize = (label: string): Set<string> => {
|
|
37
|
+
const parts = label
|
|
38
|
+
.replace(/_/g, " ")
|
|
39
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
40
|
+
.toLowerCase()
|
|
41
|
+
.split(/[\s-]+/)
|
|
42
|
+
return new Set(parts)
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
export const checkTextFormat = (label?: string): TextFormat => {
|
|
44
46
|
if (!label) return "plain"
|
|
47
|
+
|
|
45
48
|
if (TAMESTAMP_KEYS_REGEX.test(label)) return "timestamp"
|
|
46
|
-
if (EMAIL_KEYS_REGEX.test(label)) return "email"
|
|
47
|
-
if (PHONE_KEYS_REGEX.test(label)) return "phone"
|
|
48
|
-
if (URL_KEYS_REGEX.test(label)) return "url"
|
|
49
|
-
if (UUID_KEYS_REGEX.test(label)) return "uuid"
|
|
50
|
-
if (BITCOIN_KEYS_REGEX.test(label)) return "btc"
|
|
51
|
-
if (ETHEREUM_KEYS_REGEX.test(label)) return "eth"
|
|
52
49
|
if (ACCOUNT_ID_KEYS_REGEX.test(label)) return "account-id"
|
|
53
|
-
|
|
50
|
+
|
|
51
|
+
const tokens = tokenize(label)
|
|
52
|
+
|
|
53
|
+
if (tokens.has("email") || tokens.has("mail")) return "email"
|
|
54
|
+
if (tokens.has("phone") || tokens.has("tel") || tokens.has("mobile"))
|
|
55
|
+
return "phone"
|
|
56
|
+
if (tokens.has("url") || tokens.has("link") || tokens.has("website"))
|
|
57
|
+
return "url"
|
|
58
|
+
if (tokens.has("uuid") || tokens.has("guid")) return "uuid"
|
|
59
|
+
if (tokens.has("btc") || tokens.has("bitcoin")) return "btc"
|
|
60
|
+
if (tokens.has("eth") || tokens.has("ethereum")) return "eth"
|
|
61
|
+
if (tokens.has("principal") || tokens.has("canister")) return "principal"
|
|
62
|
+
|
|
54
63
|
return "plain"
|
|
55
64
|
}
|
|
56
65
|
|
|
@@ -58,7 +58,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
58
58
|
const ethField = visitor.visitText(IDL.Text, "ethereum_address")
|
|
59
59
|
expect(ethField.format).toBe("eth")
|
|
60
60
|
|
|
61
|
-
const accountIdField = visitor.visitText(IDL.Text, "
|
|
61
|
+
const accountIdField = visitor.visitText(IDL.Text, "account_identifier")
|
|
62
62
|
expect(accountIdField.format).toBe("account-id")
|
|
63
63
|
|
|
64
64
|
const principalField = visitor.visitText(IDL.Text, "canister_id")
|