@waypointjs/core 0.1.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/LICENSE +21 -0
- package/dist/index.cjs +785 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +385 -0
- package/dist/index.d.ts +385 -0
- package/dist/index.js +758 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import * as zustand_vanilla from 'zustand/vanilla';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Waypoint JSON Schema — v1
|
|
6
|
+
*
|
|
7
|
+
* Auto-sufficient tree definition generated by @waypointjs/builder.
|
|
8
|
+
* Versioned to allow non-breaking evolution.
|
|
9
|
+
*/
|
|
10
|
+
type ConditionOperator = "equals" | "notEquals" | "greaterThan" | "greaterThanOrEqual" | "lessThan" | "lessThanOrEqual" | "contains" | "notContains" | "in" | "notIn" | "exists" | "notExists" | "matches";
|
|
11
|
+
/**
|
|
12
|
+
* A single condition rule.
|
|
13
|
+
* `field` is a dot-path: "stepId.fieldId" for journey data, or "$ext.varId" for external variables.
|
|
14
|
+
*/
|
|
15
|
+
interface ConditionRule {
|
|
16
|
+
field: string;
|
|
17
|
+
operator: ConditionOperator;
|
|
18
|
+
value?: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A condition group — rules combined with AND or OR.
|
|
22
|
+
* Rules within a group are combined with `combinator`.
|
|
23
|
+
* Groups can be nested via `groups`.
|
|
24
|
+
*/
|
|
25
|
+
interface ConditionGroup {
|
|
26
|
+
combinator: "and" | "or";
|
|
27
|
+
rules: ConditionRule[];
|
|
28
|
+
groups?: ConditionGroup[];
|
|
29
|
+
}
|
|
30
|
+
type ValidationRuleType = "required" | "min" | "max" | "minLength" | "maxLength" | "email" | "url" | "regex" | "custom";
|
|
31
|
+
interface ValidationRule {
|
|
32
|
+
type: ValidationRuleType;
|
|
33
|
+
/** Value for min/max/minLength/maxLength/regex rules */
|
|
34
|
+
value?: string | number;
|
|
35
|
+
/** Error message shown to the user */
|
|
36
|
+
message: string;
|
|
37
|
+
/** For "custom" type: identifier of the validator function registered at runtime */
|
|
38
|
+
customValidatorId?: string;
|
|
39
|
+
}
|
|
40
|
+
type BuiltinFieldType = "text" | "number" | "email" | "password" | "tel" | "url" | "textarea" | "select" | "multiselect" | "checkbox" | "radio" | "date" | "file";
|
|
41
|
+
/** Field type — either a builtin or a custom type id registered at runtime */
|
|
42
|
+
type FieldType = BuiltinFieldType | (string & {});
|
|
43
|
+
interface SelectOption {
|
|
44
|
+
label: string;
|
|
45
|
+
value: string | number;
|
|
46
|
+
}
|
|
47
|
+
interface FieldDefinition {
|
|
48
|
+
id: string;
|
|
49
|
+
type: FieldType;
|
|
50
|
+
label: string;
|
|
51
|
+
placeholder?: string;
|
|
52
|
+
defaultValue?: unknown;
|
|
53
|
+
/** Options for select/multiselect/radio fields */
|
|
54
|
+
options?: SelectOption[];
|
|
55
|
+
validation?: ValidationRule[];
|
|
56
|
+
/** Controls visibility of this field within its step */
|
|
57
|
+
visibleWhen?: ConditionGroup;
|
|
58
|
+
/** Data dependencies: fields/variables that must have a value before this field is accessible */
|
|
59
|
+
dependsOn?: string[];
|
|
60
|
+
}
|
|
61
|
+
interface StepDefinition$1 {
|
|
62
|
+
id: string;
|
|
63
|
+
title: string;
|
|
64
|
+
/** URL pattern for this step — supports {{PARAM}} placeholders */
|
|
65
|
+
url: string;
|
|
66
|
+
fields: FieldDefinition[];
|
|
67
|
+
/** Controls visibility/insertion of this step in the resolved tree */
|
|
68
|
+
visibleWhen?: ConditionGroup;
|
|
69
|
+
/** Whether this step can be used as a resume point */
|
|
70
|
+
enableResumeFromHere?: boolean;
|
|
71
|
+
}
|
|
72
|
+
interface ExternalVariable {
|
|
73
|
+
id: string;
|
|
74
|
+
label: string;
|
|
75
|
+
/** JavaScript type hint */
|
|
76
|
+
type: "string" | "number" | "boolean" | "object";
|
|
77
|
+
/** If true, Waypoint will throw at runtime if this variable is missing before it is needed */
|
|
78
|
+
blocking: boolean;
|
|
79
|
+
/** Steps / fields that depend on this variable — informational, used by the builder */
|
|
80
|
+
usedIn?: Array<{
|
|
81
|
+
stepId: string;
|
|
82
|
+
fieldId?: string;
|
|
83
|
+
}>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A custom field type registered in the builder.
|
|
87
|
+
* `metadata` is passed through as-is so the backend can enrich it.
|
|
88
|
+
*/
|
|
89
|
+
interface CustomTypeDefinition {
|
|
90
|
+
id: string;
|
|
91
|
+
label: string;
|
|
92
|
+
/** Icon name or URL — used by the builder UI */
|
|
93
|
+
icon?: string;
|
|
94
|
+
/** Default validation rules applied when this type is used */
|
|
95
|
+
defaultValidation?: ValidationRule[];
|
|
96
|
+
/** Arbitrary metadata — enrichable by the backend */
|
|
97
|
+
metadata?: Record<string, unknown>;
|
|
98
|
+
}
|
|
99
|
+
type PersistenceMode = "zustand" | "backend-step" | "backend-manual";
|
|
100
|
+
interface WaypointSchema {
|
|
101
|
+
/** Schema version — increment on breaking changes */
|
|
102
|
+
version: "1";
|
|
103
|
+
/** Unique identifier for this journey definition */
|
|
104
|
+
id: string;
|
|
105
|
+
/** Human-readable name */
|
|
106
|
+
name: string;
|
|
107
|
+
/** Ordered list of steps — order reflects default display order */
|
|
108
|
+
steps: StepDefinition$1[];
|
|
109
|
+
/** External variables this journey depends on */
|
|
110
|
+
externalVariables?: ExternalVariable[];
|
|
111
|
+
/** Custom field types registered for this journey */
|
|
112
|
+
customTypes?: CustomTypeDefinition[];
|
|
113
|
+
/** Default persistence mode */
|
|
114
|
+
persistenceMode?: PersistenceMode;
|
|
115
|
+
/** Arbitrary metadata */
|
|
116
|
+
metadata?: Record<string, unknown>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* All journey data, keyed by stepId then fieldId.
|
|
121
|
+
* Example: { personal: { age: 25, name: "Alice" }, billing: { plan: "pro" } }
|
|
122
|
+
*/
|
|
123
|
+
type JourneyData = Record<string, Record<string, unknown>>;
|
|
124
|
+
/**
|
|
125
|
+
* External variables injected at runtime.
|
|
126
|
+
* Example: { isPremium: true, userId: "abc-123" }
|
|
127
|
+
*/
|
|
128
|
+
type ExternalVars = Record<string, unknown>;
|
|
129
|
+
/**
|
|
130
|
+
* Resolves a field path to its value from the data context.
|
|
131
|
+
* - "stepId.fieldId" → journey data
|
|
132
|
+
* - "$ext.varId" → external variable
|
|
133
|
+
*/
|
|
134
|
+
declare function resolveFieldValue(path: string, data: JourneyData, externalVars: ExternalVars): unknown;
|
|
135
|
+
/**
|
|
136
|
+
* Evaluates a condition group against the current data context.
|
|
137
|
+
* Returns true if the group's conditions are satisfied.
|
|
138
|
+
*/
|
|
139
|
+
declare function evaluateConditionGroup(group: ConditionGroup, data: JourneyData, externalVars: ExternalVars): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Convenience: returns true if no condition is defined (always visible),
|
|
142
|
+
* or if the condition group evaluates to true.
|
|
143
|
+
*/
|
|
144
|
+
declare function isVisible(visibleWhen: ConditionGroup | undefined, data: JourneyData, externalVars: ExternalVars): boolean;
|
|
145
|
+
|
|
146
|
+
/** A field after condition evaluation */
|
|
147
|
+
interface ResolvedField {
|
|
148
|
+
definition: FieldDefinition;
|
|
149
|
+
/** Whether the field is currently visible */
|
|
150
|
+
visible: boolean;
|
|
151
|
+
/** Whether all dependsOn paths have a non-empty value */
|
|
152
|
+
dependenciesMet: boolean;
|
|
153
|
+
}
|
|
154
|
+
/** A step after condition evaluation */
|
|
155
|
+
interface ResolvedStep {
|
|
156
|
+
definition: StepDefinition$1;
|
|
157
|
+
/** Whether this step is currently in the active tree */
|
|
158
|
+
visible: boolean;
|
|
159
|
+
/** Visible fields for this step, in definition order */
|
|
160
|
+
fields: ResolvedField[];
|
|
161
|
+
}
|
|
162
|
+
/** Result returned by resolveTree */
|
|
163
|
+
interface ResolvedTree {
|
|
164
|
+
/** Ordered list of visible steps */
|
|
165
|
+
steps: ResolvedStep[];
|
|
166
|
+
/** Steps hidden by conditions — data preserved in tmp store */
|
|
167
|
+
hiddenSteps: ResolvedStep[];
|
|
168
|
+
/** Errors: external variables required but missing */
|
|
169
|
+
missingExternalVars: string[];
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Resolves the journey tree against current data and external variables.
|
|
173
|
+
*
|
|
174
|
+
* - Steps with a falsy `visibleWhen` are moved to `hiddenSteps`
|
|
175
|
+
* - Fields within each visible step are evaluated for visibility and dependencies
|
|
176
|
+
* - Missing blocking external variables are reported
|
|
177
|
+
*
|
|
178
|
+
* This function is pure: same inputs always produce same outputs.
|
|
179
|
+
*/
|
|
180
|
+
declare function resolveTree(schema: WaypointSchema, data: JourneyData, externalVars: ExternalVars): ResolvedTree;
|
|
181
|
+
/**
|
|
182
|
+
* Returns the index of the step with the given id in the resolved (visible) tree.
|
|
183
|
+
* Returns -1 if not found.
|
|
184
|
+
*/
|
|
185
|
+
declare function findStepIndex(steps: ResolvedStep[], stepId: string): number;
|
|
186
|
+
/**
|
|
187
|
+
* Returns the next visible step after the given stepId, or undefined if last.
|
|
188
|
+
*/
|
|
189
|
+
declare function getNextStep(steps: ResolvedStep[], currentStepId: string): ResolvedStep | undefined;
|
|
190
|
+
/**
|
|
191
|
+
* Returns the previous visible step before the given stepId, or undefined if first.
|
|
192
|
+
*/
|
|
193
|
+
declare function getPreviousStep(steps: ResolvedStep[], currentStepId: string): ResolvedStep | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* Calculates progress (0–100) based on the resolved visible tree.
|
|
196
|
+
* Uses the index of the current step in the visible tree.
|
|
197
|
+
*/
|
|
198
|
+
declare function calculateProgress(steps: ResolvedStep[], currentStepId: string): number;
|
|
199
|
+
/**
|
|
200
|
+
* Given journey data, finds the deepest step the user can access:
|
|
201
|
+
* the last step in the visible tree for which all visible fields
|
|
202
|
+
* have their dependencies met.
|
|
203
|
+
*/
|
|
204
|
+
declare function findLastValidStep(steps: ResolvedStep[], data: JourneyData, _externalVars: ExternalVars): ResolvedStep | undefined;
|
|
205
|
+
|
|
206
|
+
interface WaypointRuntimeState {
|
|
207
|
+
schema: WaypointSchema | null;
|
|
208
|
+
/** { stepId: { fieldId: value } } */
|
|
209
|
+
data: Record<string, Record<string, unknown>>;
|
|
210
|
+
/** { varId: value } */
|
|
211
|
+
externalVars: Record<string, unknown>;
|
|
212
|
+
currentStepId: string | null;
|
|
213
|
+
/** Step IDs visited in order */
|
|
214
|
+
history: string[];
|
|
215
|
+
isSubmitting: boolean;
|
|
216
|
+
/** True once onComplete has been called (all steps validated) */
|
|
217
|
+
completed: boolean;
|
|
218
|
+
}
|
|
219
|
+
interface WaypointRuntimeActions {
|
|
220
|
+
/**
|
|
221
|
+
* Fresh start: sets schema + data and navigates to the first step (or startStepId).
|
|
222
|
+
* Always resets navigation state (currentStepId, history).
|
|
223
|
+
*/
|
|
224
|
+
init(schema: WaypointSchema, options?: {
|
|
225
|
+
data?: Record<string, Record<string, unknown>>;
|
|
226
|
+
externalVars?: Record<string, unknown>;
|
|
227
|
+
startStepId?: string;
|
|
228
|
+
}): void;
|
|
229
|
+
/**
|
|
230
|
+
* Resume a previously-started journey.
|
|
231
|
+
* Updates schema + externalVars but preserves data, currentStepId and history
|
|
232
|
+
* as they were persisted (e.g. from localStorage).
|
|
233
|
+
*/
|
|
234
|
+
resume(schema: WaypointSchema, externalVars?: Record<string, unknown>): void;
|
|
235
|
+
setFieldValue(stepId: string, fieldId: string, value: unknown): void;
|
|
236
|
+
setStepData(stepId: string, data: Record<string, unknown>): void;
|
|
237
|
+
setExternalVar(varId: string, value: unknown): void;
|
|
238
|
+
setCurrentStep(stepId: string): void;
|
|
239
|
+
setIsSubmitting(b: boolean): void;
|
|
240
|
+
setCompleted(b: boolean): void;
|
|
241
|
+
/**
|
|
242
|
+
* Truncates history to include only steps up to and including stepId.
|
|
243
|
+
* Called before navigating forward so stale steps from a previous path are removed.
|
|
244
|
+
*/
|
|
245
|
+
truncateHistoryAt(stepId: string): void;
|
|
246
|
+
reset(): void;
|
|
247
|
+
}
|
|
248
|
+
type WaypointRuntimeStore = WaypointRuntimeState & WaypointRuntimeActions;
|
|
249
|
+
declare function getResolvedTree(state: WaypointRuntimeState): ResolvedTree;
|
|
250
|
+
declare function getCurrentStep(state: WaypointRuntimeState): ResolvedStep | undefined;
|
|
251
|
+
declare function getNextStepFromState(state: WaypointRuntimeState): ResolvedStep | undefined;
|
|
252
|
+
declare function getPreviousStepFromState(state: WaypointRuntimeState): ResolvedStep | undefined;
|
|
253
|
+
declare function calculateProgressFromState(state: WaypointRuntimeState): number;
|
|
254
|
+
declare function getMissingBlockingVars(state: WaypointRuntimeState): string[];
|
|
255
|
+
interface CreateRuntimeStoreOptions {
|
|
256
|
+
persistenceMode?: string;
|
|
257
|
+
schemaId?: string;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Creates a new runtime store instance (vanilla Zustand, no React dependency).
|
|
261
|
+
*
|
|
262
|
+
* Each schema gets its own isolated store — multiple `<WaypointRunner>` instances
|
|
263
|
+
* with different schemas can coexist simultaneously without sharing state.
|
|
264
|
+
*
|
|
265
|
+
* @param options.persistenceMode - If "zustand", activates localStorage persistence
|
|
266
|
+
* @param options.schemaId - Used to build the persistence key (and to validate resume)
|
|
267
|
+
*/
|
|
268
|
+
declare function createRuntimeStore(options?: CreateRuntimeStoreOptions): zustand_vanilla.StoreApi<WaypointRuntimeStore>;
|
|
269
|
+
/**
|
|
270
|
+
* Returns true if the store has valid persisted state for the given schema id.
|
|
271
|
+
* Used by WaypointRunner to decide whether to call `resume()` or `init()`.
|
|
272
|
+
*
|
|
273
|
+
* Relies on the fact that localStorage hydration is synchronous, so by the time
|
|
274
|
+
* the first `useEffect` runs, the persisted slice is already merged into state.
|
|
275
|
+
*/
|
|
276
|
+
declare function hasPersistedState(store: ReturnType<typeof createRuntimeStore>, schemaId: string): boolean;
|
|
277
|
+
type RuntimeStore = ReturnType<typeof createRuntimeStore>;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Register a custom validator function by id.
|
|
281
|
+
* Used for ValidationRule type="custom" with a matching customValidatorId.
|
|
282
|
+
*/
|
|
283
|
+
declare function registerCustomValidator(id: string, fn: (value: unknown) => boolean): void;
|
|
284
|
+
/**
|
|
285
|
+
* Builds a Zod object schema from a list of resolved fields.
|
|
286
|
+
*
|
|
287
|
+
* - Only visible fields are included in the schema.
|
|
288
|
+
* - Fields without a `required` validation rule are wrapped in `.optional()`.
|
|
289
|
+
* - Numeric fields use `z.coerce.number()` so string inputs are coerced.
|
|
290
|
+
*/
|
|
291
|
+
declare function buildZodSchema(fields: ResolvedField[]): z.ZodObject<z.ZodRawShape>;
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Runtime validation for WaypointSchema JSON.
|
|
295
|
+
*
|
|
296
|
+
* Validates structure and basic constraints without relying on TypeScript types.
|
|
297
|
+
* Designed to be used at import time (builder) and at boot time (runtime).
|
|
298
|
+
*/
|
|
299
|
+
|
|
300
|
+
interface SchemaValidationResult {
|
|
301
|
+
valid: boolean;
|
|
302
|
+
errors: string[];
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Validates a raw parsed JSON value as a WaypointSchema.
|
|
306
|
+
*
|
|
307
|
+
* Returns `{ valid: true, errors: [] }` when the schema is acceptable.
|
|
308
|
+
* Returns `{ valid: false, errors: [...] }` with a list of human-readable errors otherwise.
|
|
309
|
+
*/
|
|
310
|
+
declare function validateSchema(raw: unknown): SchemaValidationResult;
|
|
311
|
+
/**
|
|
312
|
+
* Convenience: assert a schema is valid, throw with all errors if not.
|
|
313
|
+
* Useful in tests or runtime boot checks.
|
|
314
|
+
*/
|
|
315
|
+
declare function assertSchema(raw: unknown): asserts raw is WaypointSchema;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* A single step within a journey tree category.
|
|
319
|
+
*/
|
|
320
|
+
interface JourneyTreeStep {
|
|
321
|
+
/**
|
|
322
|
+
* When true, automatically enables canResumeToDeepestStep when this step is reached.
|
|
323
|
+
*/
|
|
324
|
+
enableResumeFromHere?: boolean;
|
|
325
|
+
/** Unique step identifier */
|
|
326
|
+
step: string;
|
|
327
|
+
/** URL template — supports {{PARAM}} placeholders */
|
|
328
|
+
url: string;
|
|
329
|
+
}
|
|
330
|
+
/** A logical grouping of steps */
|
|
331
|
+
interface JourneyTreeCategory {
|
|
332
|
+
category: string;
|
|
333
|
+
steps: JourneyTreeStep[];
|
|
334
|
+
}
|
|
335
|
+
/** The full navigation tree for a journey, ordered list of categories */
|
|
336
|
+
type JourneyTreeType = JourneyTreeCategory[];
|
|
337
|
+
/** Generic URL parameters map — keys are placeholder names, values are strings or numbers */
|
|
338
|
+
type WaypointParams = Record<string, string | number | undefined>;
|
|
339
|
+
/** Runtime state for a single journey */
|
|
340
|
+
interface JourneyState {
|
|
341
|
+
canResumeToDeepestStep: boolean;
|
|
342
|
+
currentStep: string | null;
|
|
343
|
+
deepestStepVisited: string;
|
|
344
|
+
history: string[];
|
|
345
|
+
progress: number;
|
|
346
|
+
tree: JourneyTreeType;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
interface StepDefinition {
|
|
350
|
+
step: string;
|
|
351
|
+
url: string;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Utility class for URL template formatting and validation.
|
|
355
|
+
* Templates use `{{PARAM_NAME}}` syntax.
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* URLTemplateEngine.format("/users/{{USER_ID}}/posts/{{POST_ID}}", { USER_ID: "42", POST_ID: "hello" })
|
|
359
|
+
* // => "/users/42/posts/hello"
|
|
360
|
+
*/
|
|
361
|
+
declare class URLTemplateEngine {
|
|
362
|
+
private static readonly PLACEHOLDER_PATTERN;
|
|
363
|
+
/**
|
|
364
|
+
* Replace all `{{PARAM}}` placeholders in a template with the provided values.
|
|
365
|
+
* Missing params are left as-is.
|
|
366
|
+
*/
|
|
367
|
+
static format(template: string, params: WaypointParams): string;
|
|
368
|
+
/**
|
|
369
|
+
* Extract all placeholder names from a URL template.
|
|
370
|
+
*/
|
|
371
|
+
static extractPlaceholders(template: string): string[];
|
|
372
|
+
/**
|
|
373
|
+
* Validate that all placeholders in the template have corresponding params.
|
|
374
|
+
*/
|
|
375
|
+
static validate(template: string, params: WaypointParams): {
|
|
376
|
+
isValid: boolean;
|
|
377
|
+
missingParams: string[];
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
declare function findMatchingStep(pathname: string, allSteps: StepDefinition[]): StepDefinition | null;
|
|
381
|
+
declare function extractURLParamsFromTree(pathname: string, allSteps: StepDefinition[]): WaypointParams;
|
|
382
|
+
declare function extractOnlyMissingParams(pathname: string, allSteps: StepDefinition[], missingParamNames: string[]): WaypointParams;
|
|
383
|
+
declare function mergeContextParams(userParams: WaypointParams | undefined, pathname: string, allSteps: StepDefinition[], targetURL?: string): WaypointParams;
|
|
384
|
+
|
|
385
|
+
export { type BuiltinFieldType, type ConditionGroup, type ConditionOperator, type ConditionRule, type CreateRuntimeStoreOptions, type CustomTypeDefinition, type ExternalVariable, type ExternalVars, type FieldDefinition, type FieldType, type JourneyData, type JourneyState, type JourneyTreeStep, type JourneyTreeType, type PersistenceMode, type ResolvedField, type ResolvedStep, type ResolvedTree, type RuntimeStore, type SchemaValidationResult, type SelectOption, type StepDefinition$1 as StepDefinition, URLTemplateEngine, type ValidationRule, type ValidationRuleType, type WaypointParams, type WaypointRuntimeActions, type WaypointRuntimeState, type WaypointRuntimeStore, type WaypointSchema, assertSchema, buildZodSchema, calculateProgress, calculateProgressFromState, createRuntimeStore, evaluateConditionGroup, extractOnlyMissingParams, extractURLParamsFromTree, findLastValidStep, findMatchingStep, findStepIndex, getCurrentStep, getMissingBlockingVars, getNextStep, getNextStepFromState, getPreviousStep, getPreviousStepFromState, getResolvedTree, hasPersistedState, isVisible, mergeContextParams, registerCustomValidator, resolveFieldValue, resolveTree, validateSchema };
|