@jfdevelops/multi-step-form-core 1.0.0-alpha.22 → 1.0.0-alpha.24
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/_internals.cjs +0 -4
- package/dist/_internals.d.cts +2 -3
- package/dist/_internals.d.mts +2 -3
- package/dist/_internals.mjs +1 -2
- package/dist/index.cjs +17 -17
- package/dist/index.d.cts +12 -11
- package/dist/index.d.mts +12 -11
- package/dist/index.mjs +8 -10
- package/dist/internals/step-schema.cjs +120 -71
- package/dist/internals/step-schema.cjs.map +1 -1
- package/dist/internals/step-schema.d.cts +47 -29
- package/dist/internals/step-schema.d.cts.map +1 -1
- package/dist/internals/step-schema.d.mts +47 -29
- package/dist/internals/step-schema.d.mts.map +1 -1
- package/dist/internals/step-schema.mjs +120 -71
- package/dist/internals/step-schema.mjs.map +1 -1
- package/dist/schema.cjs +14 -10
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +11 -13
- package/dist/schema.d.cts.map +1 -1
- package/dist/schema.d.mts +11 -13
- package/dist/schema.d.mts.map +1 -1
- package/dist/schema.mjs +14 -10
- package/dist/schema.mjs.map +1 -1
- package/dist/steps/fields.cjs +80 -0
- package/dist/steps/fields.cjs.map +1 -1
- package/dist/steps/fields.d.cts +117 -9
- package/dist/steps/fields.d.cts.map +1 -1
- package/dist/steps/fields.d.mts +117 -9
- package/dist/steps/fields.d.mts.map +1 -1
- package/dist/steps/fields.mjs +80 -0
- package/dist/steps/fields.mjs.map +1 -1
- package/dist/steps/fn-utils/helper-fn/index.cjs +81 -0
- package/dist/steps/fn-utils/helper-fn/index.cjs.map +1 -0
- package/dist/steps/fn-utils/helper-fn/index.d.cts +146 -0
- package/dist/steps/fn-utils/helper-fn/index.d.cts.map +1 -0
- package/dist/steps/fn-utils/helper-fn/index.d.mts +146 -0
- package/dist/steps/fn-utils/helper-fn/index.d.mts.map +1 -0
- package/dist/steps/fn-utils/helper-fn/index.mjs +75 -0
- package/dist/steps/fn-utils/helper-fn/index.mjs.map +1 -0
- package/dist/steps/fn-utils/helper-fn/utils.d.cts +81 -0
- package/dist/steps/fn-utils/helper-fn/utils.d.cts.map +1 -0
- package/dist/steps/fn-utils/helper-fn/utils.d.mts +81 -0
- package/dist/steps/fn-utils/helper-fn/utils.d.mts.map +1 -0
- package/dist/steps/fn-utils/index.cjs +1 -0
- package/dist/steps/fn-utils/index.mjs +3 -0
- package/dist/steps/fn-utils/reset-fn.d.cts +30 -0
- package/dist/steps/fn-utils/reset-fn.d.cts.map +1 -0
- package/dist/steps/fn-utils/reset-fn.d.mts +30 -0
- package/dist/steps/fn-utils/reset-fn.d.mts.map +1 -0
- package/dist/steps/fn-utils/update-fn.d.cts +121 -0
- package/dist/steps/fn-utils/update-fn.d.cts.map +1 -0
- package/dist/steps/fn-utils/update-fn.d.mts +121 -0
- package/dist/steps/fn-utils/update-fn.d.mts.map +1 -0
- package/dist/steps/index.cjs +4 -2
- package/dist/steps/index.mjs +5 -3
- package/dist/steps/schema.cjs +61 -84
- package/dist/steps/schema.cjs.map +1 -1
- package/dist/steps/schema.d.cts +66 -67
- package/dist/steps/schema.d.cts.map +1 -1
- package/dist/steps/schema.d.mts +66 -67
- package/dist/steps/schema.d.mts.map +1 -1
- package/dist/steps/schema.mjs +62 -86
- package/dist/steps/schema.mjs.map +1 -1
- package/dist/steps/steps.cjs +83 -0
- package/dist/steps/steps.cjs.map +1 -0
- package/dist/steps/steps.d.cts +81 -0
- package/dist/steps/steps.d.cts.map +1 -0
- package/dist/steps/steps.d.mts +81 -0
- package/dist/steps/steps.d.mts.map +1 -0
- package/dist/steps/steps.mjs +76 -0
- package/dist/steps/steps.mjs.map +1 -0
- package/dist/steps/utils.cjs +40 -30
- package/dist/steps/utils.cjs.map +1 -1
- package/dist/steps/utils.d.cts +8 -5
- package/dist/steps/utils.d.cts.map +1 -1
- package/dist/steps/utils.d.mts +8 -5
- package/dist/steps/utils.d.mts.map +1 -1
- package/dist/steps/utils.mjs +40 -31
- package/dist/steps/utils.mjs.map +1 -1
- package/dist/storage.cjs +1 -1
- package/dist/storage.cjs.map +1 -1
- package/dist/storage.d.cts +9 -7
- package/dist/storage.d.cts.map +1 -1
- package/dist/storage.d.mts +9 -7
- package/dist/storage.d.mts.map +1 -1
- package/dist/storage.mjs +1 -1
- package/dist/storage.mjs.map +1 -1
- package/dist/utils/casing.cjs +1 -1
- package/dist/utils/casing.cjs.map +1 -1
- package/dist/utils/casing.d.cts +27 -11
- package/dist/utils/casing.d.cts.map +1 -1
- package/dist/utils/casing.d.mts +27 -11
- package/dist/utils/casing.d.mts.map +1 -1
- package/dist/utils/casing.mjs +1 -1
- package/dist/utils/casing.mjs.map +1 -1
- package/dist/utils/helpers.cjs +8 -0
- package/dist/utils/helpers.cjs.map +1 -1
- package/dist/utils/helpers.mjs +7 -1
- package/dist/utils/helpers.mjs.map +1 -1
- package/dist/utils/index.cjs +3 -0
- package/dist/utils/index.mjs +5 -0
- package/dist/utils/invariant.cjs +28 -8
- package/dist/utils/invariant.cjs.map +1 -1
- package/dist/utils/invariant.d.cts +12 -2
- package/dist/utils/invariant.d.cts.map +1 -1
- package/dist/utils/invariant.d.mts +12 -2
- package/dist/utils/invariant.d.mts.map +1 -1
- package/dist/utils/invariant.mjs +28 -9
- package/dist/utils/invariant.mjs.map +1 -1
- package/dist/utils/types.d.cts +15 -3
- package/dist/utils/types.d.cts.map +1 -1
- package/dist/utils/types.d.mts +15 -3
- package/dist/utils/types.d.mts.map +1 -1
- package/dist/utils/validator.d.cts.map +1 -1
- package/dist/utils/validator.d.mts.map +1 -1
- package/package.json +1 -1
- package/dist/internals/utils.cjs +0 -94
- package/dist/internals/utils.cjs.map +0 -1
- package/dist/internals/utils.d.cts +0 -33
- package/dist/internals/utils.d.cts.map +0 -1
- package/dist/internals/utils.d.mts +0 -33
- package/dist/internals/utils.d.mts.map +0 -1
- package/dist/internals/utils.mjs +0 -91
- package/dist/internals/utils.mjs.map +0 -1
- package/dist/observable.cjs +0 -44
- package/dist/observable.cjs.map +0 -1
- package/dist/observable.d.cts +0 -26
- package/dist/observable.d.cts.map +0 -1
- package/dist/observable.d.mts +0 -26
- package/dist/observable.d.mts.map +0 -1
- package/dist/observable.mjs +0 -44
- package/dist/observable.mjs.map +0 -1
- package/dist/steps/types.cjs +0 -33
- package/dist/steps/types.cjs.map +0 -1
- package/dist/steps/types.d.cts +0 -354
- package/dist/steps/types.d.cts.map +0 -1
- package/dist/steps/types.d.mts +0 -354
- package/dist/steps/types.d.mts.map +0 -1
- package/dist/steps/types.mjs +0 -27
- package/dist/steps/types.mjs.map +0 -1
- package/dist/utils/field-types.cjs +0 -23
- package/dist/utils/field-types.cjs.map +0 -1
- package/dist/utils/field-types.d.cts +0 -39
- package/dist/utils/field-types.d.cts.map +0 -1
- package/dist/utils/field-types.d.mts +0 -39
- package/dist/utils/field-types.d.mts.map +0 -1
- package/dist/utils/field-types.mjs +0 -20
- package/dist/utils/field-types.mjs.map +0 -1
package/dist/steps/schema.mjs
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { setCasingType } from "../utils/casing.mjs";
|
|
2
|
+
import { createInvariant, invariant } from "../utils/invariant.mjs";
|
|
3
|
+
import "../utils/index.mjs";
|
|
4
|
+
import { fields } from "./fields.mjs";
|
|
5
|
+
import { instantiateSteps, steps } from "./steps.mjs";
|
|
6
|
+
import { addToTuple, mapToTuple } from "../utils/helpers.mjs";
|
|
2
7
|
import { getStep } from "./utils.mjs";
|
|
3
|
-
import { isCasingValid, setCasingType } from "../utils/casing.mjs";
|
|
4
|
-
import { isFieldType } from "../utils/field-types.mjs";
|
|
5
|
-
import { createStep, isValidStepKey } from "../internals/utils.mjs";
|
|
6
8
|
import { MultiStepFormStepSchemaInternal } from "../internals/step-schema.mjs";
|
|
7
9
|
import { DEFAULT_STORAGE_KEY, MultiStepFormStorage } from "../storage.mjs";
|
|
8
10
|
import { Subscribable } from "../subscribable.mjs";
|
|
9
|
-
import { fields } from "./fields.mjs";
|
|
10
11
|
|
|
11
12
|
//#region src/steps/schema.ts
|
|
13
|
+
const STRING_KEYS = ["string", "string.keys"];
|
|
14
|
+
const NUMBER_KEYS = ["number"];
|
|
15
|
+
const ARRAY_STRING_KEYS = addToTuple(mapToTuple(STRING_KEYS, (key) => `array.${key}`), "array.string.untyped");
|
|
16
|
+
const ARRAY_NUMBER_KEYS = mapToTuple(NUMBER_KEYS, (key) => `array.${key}`);
|
|
12
17
|
/**
|
|
13
18
|
* Available transformation types for the step numbers.
|
|
14
19
|
*/
|
|
15
20
|
const AS_TYPES = [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
...STRING_KEYS,
|
|
22
|
+
...NUMBER_KEYS,
|
|
23
|
+
...ARRAY_STRING_KEYS,
|
|
24
|
+
...ARRAY_NUMBER_KEYS
|
|
20
25
|
];
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
function createIsValidStepFn(stepNumbers) {
|
|
27
|
+
function isValidStep(value) {
|
|
28
|
+
createInvariant("[isValidStep]")(typeof value === "string" || typeof value === "number", `The value must be a string or a number, was ${typeof value}`);
|
|
29
|
+
if (typeof value === "string") {
|
|
30
|
+
if (!value.includes("step")) return false;
|
|
31
|
+
return stepNumbers.includes(Number.parseInt(value.replace("step", "")));
|
|
32
|
+
}
|
|
33
|
+
if (typeof value === "number") return stepNumbers.includes(value);
|
|
34
|
+
return false;
|
|
28
35
|
}
|
|
29
|
-
return
|
|
36
|
+
return isValidStep;
|
|
30
37
|
}
|
|
31
38
|
var MultiStepFormStepSchema = class extends Subscribable {
|
|
32
39
|
/**
|
|
@@ -39,45 +46,43 @@ var MultiStepFormStepSchema = class extends Subscribable {
|
|
|
39
46
|
value;
|
|
40
47
|
steps;
|
|
41
48
|
defaultNameTransformationCasing;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
stepNumbers;
|
|
45
|
-
storage;
|
|
49
|
+
#stepNumbers;
|
|
50
|
+
#storage;
|
|
46
51
|
#internal;
|
|
47
52
|
constructor(config) {
|
|
48
53
|
super();
|
|
49
|
-
const { steps, nameTransformCasing, storage } = config;
|
|
54
|
+
const { steps: steps$1, nameTransformCasing, storage } = config;
|
|
50
55
|
this.defaultNameTransformationCasing = setCasingType(nameTransformCasing);
|
|
51
|
-
this.original = steps;
|
|
52
|
-
this.value =
|
|
53
|
-
this.storage = new MultiStepFormStorage({
|
|
54
|
-
data: this.value,
|
|
55
|
-
key: storage?.key ?? DEFAULT_STORAGE_KEY,
|
|
56
|
-
store: storage?.store,
|
|
57
|
-
throwWhenUndefined: storage?.throwWhenUndefined ?? false
|
|
58
|
-
});
|
|
56
|
+
this.original = steps$1;
|
|
57
|
+
this.value = instantiateSteps({ steps: steps$1 });
|
|
59
58
|
this.#internal = new MultiStepFormStepSchemaInternal({
|
|
60
59
|
originalValue: this.original,
|
|
61
60
|
getValue: () => this.value,
|
|
62
61
|
setValue: (next) => this.handlePostUpdate(next)
|
|
63
62
|
});
|
|
64
63
|
this.value = this.#internal.enrichValues(this.value);
|
|
65
|
-
this
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
this.#storage = new MultiStepFormStorage({
|
|
65
|
+
data: this.value,
|
|
66
|
+
key: storage?.key ?? DEFAULT_STORAGE_KEY,
|
|
67
|
+
store: storage?.store,
|
|
68
|
+
throwWhenUndefined: storage?.throwWhenUndefined
|
|
69
|
+
});
|
|
70
|
+
this.#stepNumbers = Object.keys(this.value).map((key) => Number.parseInt(key.replace("step", "")));
|
|
68
71
|
this.steps = {
|
|
69
|
-
|
|
70
|
-
last: this.lastStep.step,
|
|
71
|
-
value: this.stepNumbers,
|
|
72
|
+
value: this.#stepNumbers,
|
|
72
73
|
as: (asType) => {
|
|
73
74
|
invariant(typeof asType === "string", `The type of the target transformation type must be a string, was ${typeof asType}`);
|
|
74
|
-
if (asType === "string") return this
|
|
75
|
-
if (asType === "
|
|
76
|
-
if (asType
|
|
75
|
+
if (asType === "string") return this.#stepNumbers.map((value) => `'${value}'`).join(" | ");
|
|
76
|
+
if (asType === "string.keys") return this.#stepNumbers.map((value) => `'step${value}'`).join(" | ");
|
|
77
|
+
if (asType === "number") return this.#stepNumbers.join(" | ");
|
|
78
|
+
if (asType.includes("array.string")) {
|
|
79
|
+
if (asType.includes("keys")) return this.#stepNumbers.map((value) => `step${value}`);
|
|
80
|
+
return this.#stepNumbers.map((value) => `${value}`);
|
|
81
|
+
}
|
|
82
|
+
if (asType.includes("array.number")) return this.#stepNumbers;
|
|
77
83
|
throw new Error(`Transformation type "${asType}" is not supported. Available transformations include: ${AS_TYPES.map((value) => `"${value}"`).join(", ")}`);
|
|
78
84
|
},
|
|
79
|
-
|
|
80
|
-
isValidStepKey: (value) => isValidStepKey(this.value, value)
|
|
85
|
+
isValidStep: createIsValidStepFn(this.#stepNumbers)
|
|
81
86
|
};
|
|
82
87
|
this.sync();
|
|
83
88
|
}
|
|
@@ -85,7 +90,7 @@ var MultiStepFormStepSchema = class extends Subscribable {
|
|
|
85
90
|
* @internal
|
|
86
91
|
*/
|
|
87
92
|
__getStorage() {
|
|
88
|
-
return this
|
|
93
|
+
return this.#storage;
|
|
89
94
|
}
|
|
90
95
|
getSnapshot() {
|
|
91
96
|
return this;
|
|
@@ -113,28 +118,17 @@ var MultiStepFormStepSchema = class extends Subscribable {
|
|
|
113
118
|
get(options) {
|
|
114
119
|
return getStep(this.value)(options);
|
|
115
120
|
}
|
|
116
|
-
/**
|
|
117
|
-
* Gets the data for the first step.
|
|
118
|
-
* @returns The data for the first step.
|
|
119
|
-
*/
|
|
120
|
-
first() {
|
|
121
|
-
const firstStep = Math.min(...this.stepNumbers);
|
|
122
|
-
return this.get({ step: firstStep });
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Gets the data for the last step.
|
|
126
|
-
* @returns The data for the last step.
|
|
127
|
-
*/
|
|
128
|
-
last() {
|
|
129
|
-
const lastStep = Math.max(...this.stepNumbers);
|
|
130
|
-
return this.get({ step: lastStep });
|
|
131
|
-
}
|
|
132
121
|
handlePostUpdate(next) {
|
|
133
122
|
this.value = { ...next };
|
|
134
123
|
this.__getStorage().add(this.value);
|
|
135
124
|
this.sync();
|
|
136
125
|
this.notify();
|
|
137
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Updates the step with the given options.
|
|
129
|
+
* @param options The options for updating the step.
|
|
130
|
+
* @returns The return value of the updater function.
|
|
131
|
+
*/
|
|
138
132
|
update(options) {
|
|
139
133
|
this.#internal.update(options);
|
|
140
134
|
}
|
|
@@ -149,29 +143,8 @@ var MultiStepFormStepSchema = class extends Subscribable {
|
|
|
149
143
|
* Validates that a given object is the proper shape for step data.
|
|
150
144
|
* @param value
|
|
151
145
|
*/
|
|
152
|
-
static hasData(value
|
|
153
|
-
|
|
154
|
-
return assertObjectFields(value, {
|
|
155
|
-
title: (v) => typeof v === "string",
|
|
156
|
-
fields: (v) => {
|
|
157
|
-
if (v === null || typeof v !== "object") return false;
|
|
158
|
-
for (const key of Object.keys(v)) {
|
|
159
|
-
if (typeof key !== "string" || !(key in v)) return false;
|
|
160
|
-
const current = v[key];
|
|
161
|
-
if (current === null || typeof current !== "object") return false;
|
|
162
|
-
if (!assertObjectFields(current, {
|
|
163
|
-
defaultValue: (v$1) => v$1 !== "undefined" && v$1 !== null,
|
|
164
|
-
label: (v$1) => typeof v$1 === "string" || typeof v$1 === "boolean" && !v$1,
|
|
165
|
-
nameTransformCasing: isCasingValid,
|
|
166
|
-
type: isFieldType
|
|
167
|
-
})) return false;
|
|
168
|
-
}
|
|
169
|
-
return true;
|
|
170
|
-
},
|
|
171
|
-
createHelperFn: (v) => typeof v === "function",
|
|
172
|
-
nameTransformCasing: isCasingValid,
|
|
173
|
-
...options?.optionalKeysToCheck
|
|
174
|
-
});
|
|
146
|
+
static hasData(value) {
|
|
147
|
+
return steps.isValidSteps(value);
|
|
175
148
|
}
|
|
176
149
|
/**
|
|
177
150
|
* Gets the value of a given field for a given step.
|
|
@@ -181,14 +154,17 @@ var MultiStepFormStepSchema = class extends Subscribable {
|
|
|
181
154
|
*/
|
|
182
155
|
getValue(step, field) {
|
|
183
156
|
const stepData = this.value[step];
|
|
157
|
+
const invariant$1 = createInvariant("[getValue]");
|
|
184
158
|
const baseErrorMessage = `Unable to get the value for "${String(step)}.fields.${String(field)}"`;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
159
|
+
const errorSuffix = "This shouldn't be the case, so please open an issue";
|
|
160
|
+
const createErrorMessage = (reason) => `${baseErrorMessage} because ${reason}. ${errorSuffix}`;
|
|
161
|
+
invariant$1(typeof stepData === "object" && stepData !== null, createErrorMessage("the step data is not an object"));
|
|
162
|
+
invariant$1("fields" in stepData, createErrorMessage("the step data does not have a \"fields\" property"));
|
|
163
|
+
invariant$1(typeof stepData.fields === "object", createErrorMessage("\"fields\" is not an object"));
|
|
164
|
+
return fields.resolvedDeepPath(field, stepData.fields);
|
|
189
165
|
}
|
|
190
166
|
};
|
|
191
167
|
|
|
192
168
|
//#endregion
|
|
193
|
-
export { MultiStepFormStepSchema };
|
|
169
|
+
export { MultiStepFormStepSchema, createIsValidStepFn };
|
|
194
170
|
//# sourceMappingURL=schema.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.mjs","names":["#internal","v","fields","fieldsUtils"],"sources":["../../src/steps/schema.ts"],"sourcesContent":["import { MultiStepFormStepSchemaInternal } from '@/internals/step-schema';\nimport {\n DEFAULT_STORAGE_KEY,\n DefaultStorageKey,\n MultiStepFormStorage,\n} from '@/storage';\nimport {\n isCasingValid,\n isFieldType,\n setCasingType,\n type CasingType,\n type Constrain,\n type DefaultCasing,\n type Expand,\n type Join,\n} from '@/utils';\nimport { invariant } from '@/utils/invariant';\nimport { Subscribable } from '../subscribable';\nimport { fields as fieldsUtils } from './fields';\nimport {\n AnyResolvedStep,\n AnyStepField,\n AnyStepFieldOption,\n CreateHelperFunctionOptionsWithCustomCtxOptions,\n CreateHelperFunctionOptionsWithValidator,\n CreateHelperFunctionOptionsWithoutValidator,\n CreateStepHelperFn,\n CreatedHelperFnWithInput,\n CreatedHelperFnWithoutInput,\n ExtractStepFromKey,\n FirstStep,\n GetCurrentStep,\n HelperFnChosenSteps,\n HelperFnWithValidator,\n HelperFnWithoutValidator,\n InferStepOptions,\n LastStep,\n MultiStepFormSchemaStepConfig,\n ResolvedFields,\n ResolvedStep,\n Step,\n StepData,\n StepNumbers,\n StepOptions,\n UnionToTuple,\n UpdateFn,\n ValidStepKey,\n type ResetFn,\n} from './types';\nimport { getStep, type GetStepOptions } from './utils';\nimport { createStep, isValidStepKey } from '@/internals/utils';\n\nexport interface MultiStepFormStepSchemaFunctions<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>\n> {\n update: UpdateFn.general<TResolvedStep, TStepNumbers>;\n createHelperFn: CreateStepHelperFn<TResolvedStep, TStepNumbers>;\n}\nexport type AsType = (typeof AS_TYPES)[number];\ntype Quote<T extends string[]> = {\n [K in keyof T]: T[K] extends string ? `'${T[K]}'` : never;\n};\nexport type AsTypeMap<\n resolvedStep extends AnyResolvedStep,\n stepNumbers extends ExtractStepFromKey<Constrain<keyof resolvedStep, string>>\n> = {\n // Exclude is needed due to all the Constrains\n string: Exclude<\n Join<\n Constrain<\n Quote<Constrain<UnionToTuple<`${stepNumbers}`>, string[]>>,\n string[]\n >,\n ' | '\n >,\n ''\n >;\n number: Exclude<\n Join<Constrain<UnionToTuple<`${stepNumbers}`>, string[]>, ' | '>,\n ''\n >;\n 'array.string': UnionToTuple<`${stepNumbers}`>;\n 'array.string.untyped': string[];\n};\nexport type AsFunctionReturn<\n resolvedStep extends AnyResolvedStep,\n stepNumbers extends ExtractStepFromKey<Constrain<keyof resolvedStep, string>>,\n asType extends AsType\n> = AsTypeMap<resolvedStep, stepNumbers>[asType];\nexport type AsFunction<\n resolvedStep extends AnyResolvedStep,\n stepNumbers extends ExtractStepFromKey<Constrain<keyof resolvedStep, string>>\n> = <asType extends AsType>(\n asType: asType\n) => AsFunctionReturn<resolvedStep, stepNumbers, asType>;\nexport type MultiStepFormStepStepsConfig<\n TStep extends Step<TCasing>,\n TCasing extends CasingType,\n TResolvedStep extends ResolvedStep<TStep, TCasing> = ResolvedStep<\n TStep,\n TCasing\n >,\n TStepNumbers extends StepNumbers<TResolvedStep> = StepNumbers<TResolvedStep>\n> = {\n first: FirstStep<TResolvedStep>;\n last: LastStep<TResolvedStep>;\n value: ReadonlyArray<TStepNumbers>;\n as: AsFunction<TResolvedStep, TStepNumbers>;\n isValidStepNumber: (stepNumber: number) => stepNumber is TStepNumbers;\n isValidStepKey: (\n value: string\n ) => value is Constrain<keyof TResolvedStep, string>;\n};\nexport type MultiStepFormStepSchemaListener<\n TStep extends Step<TCasing>,\n TCasing extends CasingType\n> = (data: {\n original: InferStepOptions<TStep>;\n value: ResolvedStep<TStep, TCasing>;\n steps: MultiStepFormStepStepsConfig<TStep, TCasing>;\n defaultNameTransformationCasing: TCasing;\n}) => void;\n\n/**\n * Available transformation types for the step numbers.\n */\nconst AS_TYPES = [\n 'string',\n 'number',\n 'array.string',\n 'array.string.untyped',\n] as const;\n\ntype ValueCheck<T> = (v: unknown) => v is T;\n\ntype FieldChecks<T extends object> = {\n [K in keyof T]: ValueCheck<T[K]>;\n};\n\nfunction assertObjectFields<T extends object>(\n obj: unknown,\n checks: FieldChecks<T>\n): obj is T {\n if (typeof obj !== 'object' || obj === null) return false;\n\n for (const key of Object.keys(checks) as (keyof T)[]) {\n // Check that the property exists\n if (!(key in obj)) return false;\n\n // Now check the type\n const checkFn = checks[key];\n const value = (obj as any)[key];\n if (!checkFn(value)) return false;\n }\n\n return true;\n}\n\nexport class MultiStepFormStepSchema<\n step extends Step<casing>,\n casing extends CasingType = DefaultCasing,\n resolvedStep extends ResolvedStep<step, casing> = ResolvedStep<\n step,\n casing\n >,\n stepNumbers extends StepNumbers<resolvedStep> = StepNumbers<resolvedStep>,\n storageKey extends string = DefaultStorageKey\n >\n extends Subscribable<MultiStepFormStepSchemaListener<step, casing>>\n implements MultiStepFormStepSchemaFunctions<resolvedStep, stepNumbers>\n{\n /**\n * The original config before any validation or transformations have been applied.\n */\n readonly original: InferStepOptions<step>;\n /**\n * The resolved step values.\n */\n value: resolvedStep;\n readonly steps: MultiStepFormStepStepsConfig<step, casing>;\n readonly defaultNameTransformationCasing: casing;\n //@ts-ignore\n private readonly firstStep: StepData<resolvedStep, FirstStep<resolvedStep>>;\n private readonly lastStep: StepData<resolvedStep, LastStep<resolvedStep>>;\n private readonly stepNumbers: Array<number>;\n private readonly storage: MultiStepFormStorage<resolvedStep, storageKey>;\n readonly #internal: MultiStepFormStepSchemaInternal<\n step,\n casing,\n resolvedStep,\n stepNumbers\n >;\n\n constructor(\n config: MultiStepFormSchemaStepConfig<\n step,\n Constrain<casing, CasingType>,\n storageKey\n >\n ) {\n super();\n\n const { steps, nameTransformCasing, storage } = config;\n\n this.defaultNameTransformationCasing = setCasingType(\n nameTransformCasing\n ) as casing;\n\n this.original = steps;\n\n this.value = createStep<step, casing>(this.original) as resolvedStep;\n this.storage = new MultiStepFormStorage<resolvedStep, storageKey>({\n data: this.value,\n key: (storage?.key ?? DEFAULT_STORAGE_KEY) as storageKey,\n store: storage?.store,\n throwWhenUndefined: storage?.throwWhenUndefined ?? false,\n });\n this.#internal = new MultiStepFormStepSchemaInternal<\n step,\n casing,\n resolvedStep,\n stepNumbers\n >({\n originalValue: this.original,\n getValue: () => this.value,\n setValue: (next) => this.handlePostUpdate(next),\n });\n\n this.value = this.#internal.enrichValues(this.value);\n this.stepNumbers = Object.keys(this.value).map((key) =>\n Number.parseInt(key.replace('step', ''))\n );\n\n this.firstStep = this.first();\n this.lastStep = this.last();\n this.steps = {\n first: this.firstStep.step,\n last: this.lastStep.step,\n value: this.stepNumbers as unknown as ReadonlyArray<stepNumbers>,\n as: (asType): any => {\n invariant(\n typeof asType === 'string',\n `The type of the target transformation type must be a string, was ${typeof asType}`\n );\n\n if (asType === 'string') {\n return this.stepNumbers.map((value) => `'${value}'`).join(' | ');\n }\n\n if (asType === 'number') {\n return this.stepNumbers.join(' | ');\n }\n\n if (asType.includes('array.string')) {\n return this.stepNumbers.map((value) => `${value}`);\n }\n\n throw new Error(\n `Transformation type \"${asType}\" is not supported. Available transformations include: ${AS_TYPES.map(\n (value) => `\"${value}\"`\n ).join(', ')}`\n );\n },\n isValidStepNumber: (stepNumber): stepNumber is stepNumbers =>\n this.stepNumbers.includes(stepNumber),\n isValidStepKey: (value) =>\n isValidStepKey<resolvedStep>(this.value, value),\n };\n\n this.sync();\n }\n\n /**\n * @internal\n */\n __getStorage() {\n return this.storage;\n }\n\n getSnapshot() {\n return this;\n }\n\n /**\n * Syncs the values from storage to {@linkcode value}.\n */\n sync() {\n // TODO add \"syncOptions\" so caller can chose where to sync from ('storage' | 'instance')\n const storageValues = this.__getStorage().get();\n\n if (storageValues) {\n const enrichedValues = this.#internal.enrichValues(storageValues);\n\n this.value = { ...enrichedValues };\n }\n }\n\n protected notify() {\n for (const listener of this.listeners) {\n listener({\n defaultNameTransformationCasing: this.defaultNameTransformationCasing,\n original: this.original,\n steps: this.steps,\n value: this.value,\n });\n }\n }\n\n /**\n * Gets the data for a specific step.\n * @param options The options for getting the step data.\n * @returns The step data for the target step.\n */\n get<stepNumber extends stepNumbers>(\n options: GetStepOptions<resolvedStep, stepNumbers, stepNumber>\n ) {\n return getStep(this.value)(options);\n }\n\n /**\n * Gets the data for the first step.\n * @returns The data for the first step.\n */\n first() {\n const firstStep = Math.min(...this.stepNumbers) as FirstStep<resolvedStep>;\n\n return this.get({ step: firstStep });\n }\n\n /**\n * Gets the data for the last step.\n * @returns The data for the last step.\n */\n last() {\n const lastStep = Math.max(...this.stepNumbers);\n\n return this.get<LastStep<resolvedStep>>({ step: lastStep as never });\n }\n\n protected handlePostUpdate(next: resolvedStep) {\n this.value = { ...next };\n\n this.__getStorage().add(this.value);\n this.sync();\n this.notify();\n }\n\n update<\n targetStep extends ValidStepKey<stepNumbers>,\n field extends UpdateFn.chosenFields<\n UpdateFn.resolvedStep<resolvedStep, stepNumbers, targetStep>\n > = 'all',\n strict extends boolean = true,\n partial extends boolean = false,\n additionalCtx extends Record<string, unknown> = {},\n additionalUpdaterData extends UpdateFn.additionalUpdaterData = never\n >(\n options: UpdateFn.options<\n resolvedStep,\n stepNumbers,\n targetStep,\n field,\n strict,\n partial,\n additionalCtx,\n additionalUpdaterData\n >\n ) {\n this.#internal.update(options);\n }\n\n reset<\n targetStep extends ValidStepKey<stepNumbers>,\n fields extends UpdateFn.chosenFields<currentStep>,\n currentStep extends UpdateFn.resolvedStep<\n resolvedStep,\n stepNumbers,\n targetStep\n >\n >(\n options: ResetFn.Options<\n resolvedStep,\n stepNumbers,\n targetStep,\n fields,\n currentStep\n >\n ) {\n this.#internal.reset(options);\n }\n\n /**\n * Create a helper function with validated input.\n */\n createHelperFn<\n const chosenSteps extends HelperFnChosenSteps<resolvedStep, stepNumbers>,\n validator,\n additionalCtx extends Record<string, unknown>,\n response\n >(\n options: CreateHelperFunctionOptionsWithValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n validator,\n additionalCtx\n >,\n fn: HelperFnWithValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n validator,\n additionalCtx,\n response\n >\n ): CreatedHelperFnWithInput<validator, response>;\n /**\n * Create a helper function without input.\n */\n createHelperFn<\n const chosenSteps extends HelperFnChosenSteps<resolvedStep, stepNumbers>,\n additionalCtx extends Record<string, unknown>,\n response\n >(\n options: CreateHelperFunctionOptionsWithoutValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps\n > &\n CreateHelperFunctionOptionsWithCustomCtxOptions<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n additionalCtx\n >,\n fn: HelperFnWithoutValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n additionalCtx,\n response\n >\n ): CreatedHelperFnWithoutInput<response>;\n // Implementation\n createHelperFn<\n const chosenSteps extends HelperFnChosenSteps<resolvedStep, stepNumbers>,\n response,\n additionalCtx extends Record<string, unknown>,\n validator = never\n >(\n options:\n | CreateHelperFunctionOptionsWithValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n validator,\n additionalCtx\n >\n | CreateHelperFunctionOptionsWithoutValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps\n >,\n fn:\n | HelperFnWithValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n validator,\n additionalCtx,\n response\n >\n | HelperFnWithoutValidator<\n resolvedStep,\n stepNumbers,\n chosenSteps,\n additionalCtx,\n response\n >\n ) {\n const { stepData, ...rest } = options;\n\n return this.#internal.createStepHelperFn(stepData)(rest, fn);\n }\n\n /**\n * Validates that a given object is the proper shape for step data.\n * @param value\n */\n static hasData<\n step extends Step<casing>,\n resolvedStep extends ResolvedStep<step, casing>,\n stepNumbers extends StepNumbers<resolvedStep>,\n casing extends CasingType = DefaultCasing\n >(\n value: unknown,\n options?: {\n optionalKeysToCheck?: FieldChecks<\n Pick<StepOptions, 'description' | 'validateFields'>\n >;\n }\n ): value is GetCurrentStep<resolvedStep, stepNumbers> {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n\n return assertObjectFields<\n | GetCurrentStep<resolvedStep, stepNumbers>\n | (Omit<StepOptions, 'fields'> & {\n fields: Expand<\n ResolvedFields<InferStepOptions<step>, keyof InferStepOptions<step>>\n >;\n })\n >(value, {\n title: (v) => typeof v === 'string',\n fields: (\n v\n ): v is Expand<\n ResolvedFields<InferStepOptions<step>, keyof InferStepOptions<step>>\n > => {\n if (v === null || typeof v !== 'object') {\n return false;\n }\n\n for (const key of Object.keys(v)) {\n if (typeof key !== 'string' || !(key in v)) {\n return false;\n }\n\n const current = (v as Record<string, unknown>)[key];\n\n if (current === null || typeof current !== 'object') {\n return false;\n }\n\n const hasField = assertObjectFields<AnyStepFieldOption>(current, {\n defaultValue: (v): v is {} => v !== 'undefined' && v !== null,\n label: (v) =>\n typeof v === 'string' || (typeof v === 'boolean' && !v),\n nameTransformCasing: isCasingValid,\n type: isFieldType,\n });\n\n if (!hasField) {\n return false;\n }\n }\n\n return true;\n },\n createHelperFn: (\n v\n ): v is GetCurrentStep<resolvedStep, stepNumbers>['createHelperFn'] =>\n typeof v === 'function',\n // update: (v): v is GetCurrentStep<resolvedStep, stepNumbers>['update'] =>\n // typeof v === 'function',\n nameTransformCasing: isCasingValid,\n ...options?.optionalKeysToCheck,\n });\n }\n\n /**\n * Gets the value of a given field for a given step.\n * @param step The step to get the value from.\n * @param field The field to get the value from.\n * @returns The value of the {@linkcode field}.\n */\n getValue<\n step extends keyof resolvedStep,\n field extends fieldsUtils.getDeepFields<resolvedStep, step>\n >(step: step, field: field) {\n const stepData = this.value[step];\n const baseErrorMessage = `Unable to get the value for \"${String(\n step\n )}.fields.${String(field)}\"`;\n\n invariant('fields' in stepData, baseErrorMessage);\n invariant(\n typeof stepData.fields === 'object',\n `${baseErrorMessage} because \"fields\" is not an object. This shouldn't be the case, so please open an issue`\n );\n\n const fields = stepData.fields as AnyStepField;\n\n const defaultValue = fieldsUtils.resolvedDeepPath<\n resolvedStep,\n step,\n fieldsUtils.get<resolvedStep, step>,\n field\n >(field, fields as fieldsUtils.get<resolvedStep, step>);\n\n return defaultValue;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":["#stepNumbers","#storage","#internal","steps","invariant: Invariant"],"sources":["../../src/steps/schema.ts"],"sourcesContent":["import {\n MultiStepFormStepSchemaInternal,\n type StepSchema,\n} from '@/internals/step-schema';\nimport { DEFAULT_STORAGE_KEY, MultiStepFormStorage } from '@/storage';\nimport {\n setCasingType,\n type Constrain,\n type Join,\n type UnionToTuple,\n} from '@/utils';\nimport { addToTuple, mapToTuple } from '@/utils/helpers';\nimport { createInvariant, invariant, type Invariant } from '@/utils/invariant';\nimport { Subscribable } from '../subscribable';\nimport { fields } from './fields';\nimport type { HelperFnChosenSteps } from './fn-utils/helper-fn';\nimport type {\n GeneralHelperFn,\n HelperFnInput,\n HelperFnOptions,\n HelperFnOutput,\n} from './fn-utils/helper-fn/utils';\nimport type { ResetFn } from './fn-utils/reset-fn';\nimport type { UpdateFn } from './fn-utils/update-fn';\nimport { instantiateSteps, steps } from './steps';\nimport { getStep, type ExtractStepFromKey, type GetStepOptions } from './utils';\n\nexport interface MultiStepFormStepSchemaFunctions<\n value extends steps.instantiateSteps,\n> {\n update: UpdateFn.general<value>;\n reset: ResetFn.general<value>;\n createHelperFn: GeneralHelperFn<value>;\n}\nexport type AsType = (typeof AS_TYPES)[number];\ntype Quote<T extends string[]> = {\n [K in keyof T]: T[K] extends string ? `'${T[K]}'` : never;\n};\nexport type AsTypeMap<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n stepNumbers extends steps.StepNumbers<value> = steps.StepNumbers<value>,\n> = {\n // Exclude is needed due to all the Constrains\n string: Exclude<\n Join<\n Constrain<\n Quote<\n Constrain<\n UnionToTuple<`${ExtractStepFromKey<stepNumbers>}`>,\n string[]\n >\n >,\n string[]\n >,\n ' | '\n >,\n ''\n >;\n 'string.keys': Exclude<\n Join<\n Constrain<UnionToTuple<`${ExtractStepFromKey<stepNumbers>}`>, string[]>,\n ' | '\n >,\n ''\n >;\n number: Exclude<\n Join<Constrain<UnionToTuple<`${stepNumbers}`>, string[]>, ' | '>,\n ''\n >;\n 'array.number': UnionToTuple<ExtractStepFromKey<stepNumbers>>;\n 'array.string': UnionToTuple<`${ExtractStepFromKey<stepNumbers>}`>;\n 'array.string.keys': UnionToTuple<`${stepNumbers}`>;\n 'array.string.untyped': string[];\n};\nexport type AsFunctionReturn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n asType extends AsType,\n> = AsTypeMap<def, value>[asType];\nexport type AsFunction<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = <asType extends AsType>(\n asType: asType\n) => AsFunctionReturn<def, value, asType>;\n\nexport type IsValidStepFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = {\n /**\n * Checks if a given string is a valid step key.\n */\n (value: string): value is steps.StepNumbers<value>;\n /**\n * Checks if a given number is a valid step number.\n */\n (value: number): value is ExtractStepFromKey<steps.StepNumbers<value>>;\n};\nexport type MultiStepFormStepStepsConfig<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = {\n value: ReadonlyArray<steps.StepNumbers<value>>;\n as: AsFunction<def, value>;\n isValidStep: IsValidStepFn<def, value>;\n};\n\nconst STRING_KEYS = ['string', 'string.keys'] as const;\nconst NUMBER_KEYS = ['number'] as const;\nconst ARRAY_STRING_KEYS = addToTuple(\n mapToTuple(STRING_KEYS, (key) => `array.${key}` as const),\n 'array.string.untyped'\n);\nconst ARRAY_NUMBER_KEYS = mapToTuple(\n NUMBER_KEYS,\n (key) => `array.${key}` as const\n);\n\n/**\n * Available transformation types for the step numbers.\n */\nconst AS_TYPES = [\n ...STRING_KEYS,\n ...NUMBER_KEYS,\n ...ARRAY_STRING_KEYS,\n ...ARRAY_NUMBER_KEYS,\n] as const;\n\nexport function createIsValidStepFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(stepNumbers: Array<number>): IsValidStepFn<def, value> {\n function isValidStep(value: string): value is steps.StepNumbers<value>;\n function isValidStep(\n value: number\n ): value is ExtractStepFromKey<steps.StepNumbers<value>>;\n function isValidStep(value: string | number) {\n const invariant: Invariant = createInvariant('[isValidStep]');\n\n invariant(\n typeof value === 'string' || typeof value === 'number',\n `The value must be a string or a number, was ${typeof value}`\n );\n\n if (typeof value === 'string') {\n if (!value.includes('step')) {\n return false;\n }\n\n return stepNumbers.includes(Number.parseInt(value.replace('step', '')));\n }\n\n if (typeof value === 'number') {\n return stepNumbers.includes(value);\n }\n\n return false;\n }\n\n return isValidStep;\n}\n\nexport namespace MultiStepFormStepSchema {\n export type ListenerOptions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = {\n original: def['steps'];\n value: value;\n steps: MultiStepFormStepStepsConfig<def, value>;\n defaultNameTransformationCasing: def['nameTransformCasing'];\n };\n export type Listener<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = (data: ListenerOptions<def, value>) => void;\n}\n\nexport class MultiStepFormStepSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends Subscribable<MultiStepFormStepSchema.Listener<def, value>>\n implements MultiStepFormStepSchemaFunctions<value>\n{\n /**\n * The original config before any validation or transformations have been applied.\n */\n readonly original: def['steps'];\n /**\n * The resolved step values.\n */\n value: value;\n readonly steps: MultiStepFormStepStepsConfig<def, value>;\n readonly defaultNameTransformationCasing: def['nameTransformCasing'];\n readonly #stepNumbers: Array<number>;\n readonly #storage: MultiStepFormStorage<\n value,\n StepSchema.inferStorageKey<def>\n >;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n\n constructor(config: def) {\n super();\n\n const { steps, nameTransformCasing, storage } = config;\n\n this.defaultNameTransformationCasing = setCasingType(\n nameTransformCasing\n ) as def['nameTransformCasing'];\n\n this.original = steps;\n\n this.value = instantiateSteps({ steps });\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.original,\n getValue: () => this.value,\n setValue: (next) => this.handlePostUpdate(next),\n });\n\n this.value = this.#internal.enrichValues(this.value);\n this.#storage = new MultiStepFormStorage({\n data: this.value,\n key: (storage?.key ??\n DEFAULT_STORAGE_KEY) as StepSchema.inferStorageKey<def>,\n store: storage?.store,\n throwWhenUndefined: storage?.throwWhenUndefined,\n });\n this.#stepNumbers = Object.keys(this.value).map((key) =>\n Number.parseInt(key.replace('step', ''))\n );\n\n this.steps = {\n value: this.#stepNumbers as unknown as ReadonlyArray<\n steps.StepNumbers<value>\n >,\n as: (asType): any => {\n invariant(\n typeof asType === 'string',\n `The type of the target transformation type must be a string, was ${typeof asType}`\n );\n\n if (asType === 'string') {\n return this.#stepNumbers.map((value) => `'${value}'`).join(' | ');\n }\n\n if (asType === 'string.keys') {\n return this.#stepNumbers.map((value) => `'step${value}'`).join(' | ');\n }\n\n if (asType === 'number') {\n return this.#stepNumbers.join(' | ');\n }\n\n if (asType.includes('array.string')) {\n if (asType.includes('keys')) {\n return this.#stepNumbers.map((value) => `step${value}`);\n }\n\n return this.#stepNumbers.map((value) => `${value}`);\n }\n\n if (asType.includes('array.number')) {\n return this.#stepNumbers;\n }\n\n throw new Error(\n `Transformation type \"${asType}\" is not supported. Available transformations include: ${AS_TYPES.map(\n (value) => `\"${value}\"`\n ).join(', ')}`\n );\n },\n isValidStep: createIsValidStepFn(this.#stepNumbers),\n };\n\n this.sync();\n }\n\n /**\n * @internal\n */\n __getStorage() {\n return this.#storage;\n }\n\n getSnapshot() {\n return this;\n }\n\n /**\n * Syncs the values from storage to {@linkcode value}.\n */\n sync() {\n // TODO add \"syncOptions\" so caller can chose where to sync from ('storage' | 'instance')\n const storageValues = this.__getStorage().get();\n\n if (storageValues) {\n const enrichedValues = this.#internal.enrichValues(storageValues);\n\n this.value = { ...enrichedValues };\n }\n }\n\n protected notify() {\n for (const listener of this.listeners) {\n listener({\n defaultNameTransformationCasing: this.defaultNameTransformationCasing,\n original: this.original,\n steps: this.steps,\n value: this.value,\n });\n }\n }\n\n /**\n * Gets the data for a specific step.\n * @param options The options for getting the step data.\n * @returns The step data for the target step.\n */\n get<stepNumber extends steps.StepNumbers<value>>(\n options: GetStepOptions<value, steps.StepNumbers<value>, stepNumber>\n ) {\n return getStep(this.value)(options);\n }\n\n protected handlePostUpdate(next: value) {\n this.value = { ...next };\n\n this.__getStorage().add(this.value);\n this.sync();\n this.notify();\n }\n\n /**\n * Updates the step with the given options.\n * @param options The options for updating the step.\n * @returns The return value of the updater function.\n */\n update<\n targetStep extends steps.StepNumbers<value>,\n field extends UpdateFn.chosenFields<\n UpdateFn.resolvedStep<value, targetStep>\n > = 'all',\n strict extends boolean = true,\n partial extends boolean = false,\n additionalCtx extends Record<string, unknown> = {},\n additionalUpdaterData extends UpdateFn.additionalUpdaterData = never,\n >(\n options: UpdateFn.options<\n value,\n targetStep,\n field,\n strict,\n partial,\n additionalCtx,\n additionalUpdaterData\n >\n ) {\n this.#internal.update(options);\n }\n\n reset<\n targetStep extends steps.StepNumbers<value>,\n fields extends UpdateFn.chosenFields<currentStep>,\n currentStep extends UpdateFn.resolvedStep<value, targetStep>,\n >(options: ResetFn.Options<value, targetStep, fields, currentStep>) {\n this.#internal.reset(options);\n }\n\n /**\n * Create a helper function with validated input.\n */\n createHelperFn<\n const chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n validator,\n additionalCtx extends Record<string, unknown>,\n response,\n >(\n options: HelperFnOptions.WithValidator<\n value,\n chosenSteps,\n validator,\n additionalCtx\n >,\n fn: HelperFnInput.WithValidator<\n value,\n chosenSteps,\n validator,\n additionalCtx,\n response\n >\n ): HelperFnOutput.WithValidator<validator, response>;\n /**\n * Create a helper function without input.\n */\n createHelperFn<\n const chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown>,\n response,\n >(\n options: HelperFnOptions.WithoutValidator<\n value,\n chosenSteps,\n additionalCtx\n >,\n fn: HelperFnInput.WithoutValidator<\n value,\n chosenSteps,\n additionalCtx,\n response\n >\n ): HelperFnOutput.WithoutInput<response>;\n // Implementation\n createHelperFn<\n const chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n response,\n additionalCtx extends Record<string, unknown>,\n validator = never,\n >(\n options:\n | HelperFnOptions.WithValidator<\n value,\n chosenSteps,\n validator,\n additionalCtx\n >\n | HelperFnOptions.WithoutValidator<value, chosenSteps, additionalCtx>,\n fn:\n | HelperFnInput.WithValidator<\n value,\n chosenSteps,\n validator,\n additionalCtx,\n response\n >\n | HelperFnInput.WithoutValidator<\n value,\n chosenSteps,\n additionalCtx,\n response\n >\n ) {\n const { stepData, ...rest } = options;\n\n return this.#internal.createStepHelperFn(stepData)(rest, fn);\n }\n\n /**\n * Validates that a given object is the proper shape for step data.\n * @param value\n */\n static hasData(value: unknown): value is steps.config {\n return steps.isValidSteps(value);\n }\n\n /**\n * Gets the value of a given field for a given step.\n * @param step The step to get the value from.\n * @param field The field to get the value from.\n * @returns The value of the {@linkcode field}.\n */\n getValue<\n step extends steps.StepNumbers<value>,\n field extends fields.getDeepFields<value, step>,\n >(step: step, field: field) {\n const stepData = this.value[step];\n const invariant: Invariant = createInvariant('[getValue]');\n const baseErrorMessage = `Unable to get the value for \"${String(\n step\n )}.fields.${String(field)}\"`;\n const errorSuffix = \"This shouldn't be the case, so please open an issue\";\n const createErrorMessage = (reason: string) =>\n `${baseErrorMessage} because ${reason}. ${errorSuffix}`;\n\n invariant(\n typeof stepData === 'object' && stepData !== null,\n createErrorMessage('the step data is not an object')\n );\n invariant(\n 'fields' in stepData,\n createErrorMessage('the step data does not have a \"fields\" property')\n );\n invariant(\n typeof stepData.fields === 'object',\n createErrorMessage('\"fields\" is not an object')\n );\n\n const defaultValue = fields.resolvedDeepPath<\n value,\n step,\n fields.get<value, step>,\n field\n >(field, stepData.fields as fields.get<value, step>);\n\n return defaultValue;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const require_casing = require('../utils/casing.cjs');
|
|
2
|
+
const require_invariant = require('../utils/invariant.cjs');
|
|
3
|
+
require('../utils/index.cjs');
|
|
4
|
+
const require_fields = require('./fields.cjs');
|
|
5
|
+
|
|
6
|
+
//#region src/steps/steps.ts
|
|
7
|
+
const VALIDATED_STEP_REGEX = /^step\d+$/i;
|
|
8
|
+
let steps;
|
|
9
|
+
(function(_steps) {
|
|
10
|
+
function instantiate(def) {
|
|
11
|
+
const { steps: steps$1 } = def;
|
|
12
|
+
const invariant = require_invariant.createInvariant("[instantiateSteps]");
|
|
13
|
+
invariant(steps$1, "No steps were provided to the \"steps\" option.", TypeError);
|
|
14
|
+
invariant(typeof steps$1 === "object", "\"steps\" must be an object.", TypeError);
|
|
15
|
+
invariant(Object.keys(steps$1).length > 0, "\"steps\" must contain at least one step.", TypeError);
|
|
16
|
+
let resolvedSteps = {};
|
|
17
|
+
for (const [stepKey, stepValue] of Object.entries(steps$1)) {
|
|
18
|
+
const invariant$1 = require_invariant.createInvariant(`[instantiateSteps - ${stepKey}]`);
|
|
19
|
+
invariant$1(typeof stepKey === "string", `Each key for the step config must be a string. Key "${stepKey}" was ${typeof stepKey} `, TypeError);
|
|
20
|
+
invariant$1(VALIDATED_STEP_REGEX.test(stepKey), `The key "${stepKey}" isn't formatted properly. Each key in the step config must be the following format: "step{number}"`);
|
|
21
|
+
const { fields: fieldsDef, title, description, validateFields, nameTransformCasing = require_casing.DEFAULT_CASING } = stepValue;
|
|
22
|
+
invariant$1(title, "A title must be provided for each step.", TypeError);
|
|
23
|
+
invariant$1(typeof title === "string", "The title must be a string.", TypeError);
|
|
24
|
+
if (description) invariant$1(typeof description === "string", "The description must be a string.", TypeError);
|
|
25
|
+
if (nameTransformCasing) {
|
|
26
|
+
invariant$1(typeof nameTransformCasing === "string", `The nameTransformCasing must be a string. Was ${typeof nameTransformCasing}`, TypeError);
|
|
27
|
+
invariant$1(require_casing.isCasingValid(nameTransformCasing), (formatter) => `The nameTransformCasing is not a valid casing. Was ${nameTransformCasing}, must be one of ${formatter.format(require_casing.CASING_TYPES)}`, TypeError);
|
|
28
|
+
}
|
|
29
|
+
const instantiatedFields = require_fields.fields.instantiate({
|
|
30
|
+
fields: fieldsDef,
|
|
31
|
+
defaultCasing: nameTransformCasing,
|
|
32
|
+
validateFields
|
|
33
|
+
});
|
|
34
|
+
resolvedSteps[stepKey] = {
|
|
35
|
+
...resolvedSteps[stepKey],
|
|
36
|
+
title,
|
|
37
|
+
...typeof description === "string" ? { description } : {},
|
|
38
|
+
nameTransformCasing,
|
|
39
|
+
fields: instantiatedFields
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return resolvedSteps;
|
|
43
|
+
}
|
|
44
|
+
_steps.instantiate = instantiate;
|
|
45
|
+
function isValidStepValue(stepValue) {
|
|
46
|
+
if (stepValue === null || typeof stepValue !== "object") return false;
|
|
47
|
+
const step = stepValue;
|
|
48
|
+
if (!("title" in step) || typeof step.title !== "string") return false;
|
|
49
|
+
if ("description" in step) {
|
|
50
|
+
if (typeof step.description !== "string") return false;
|
|
51
|
+
}
|
|
52
|
+
if ("nameTransformCasing" in step) {
|
|
53
|
+
const casing = step.nameTransformCasing;
|
|
54
|
+
if (typeof casing !== "string" || !require_casing.isCasingValid(casing)) return false;
|
|
55
|
+
}
|
|
56
|
+
if (!("fields" in step)) return false;
|
|
57
|
+
return require_fields.fields.isValidFieldConfig(step.fields);
|
|
58
|
+
}
|
|
59
|
+
function isValidSteps(value) {
|
|
60
|
+
if (value === null || typeof value !== "object") return false;
|
|
61
|
+
const steps$1 = value;
|
|
62
|
+
if (Object.keys(steps$1).length === 0) return false;
|
|
63
|
+
for (const [stepKey, stepValue] of Object.entries(steps$1)) {
|
|
64
|
+
if (typeof stepKey !== "string") return false;
|
|
65
|
+
if (!VALIDATED_STEP_REGEX.test(stepKey)) return false;
|
|
66
|
+
if (!isValidStepValue(stepValue)) return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
_steps.isValidSteps = isValidSteps;
|
|
71
|
+
})(steps || (steps = {}));
|
|
72
|
+
const instantiateSteps = steps.instantiate;
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
exports.VALIDATED_STEP_REGEX = VALIDATED_STEP_REGEX;
|
|
76
|
+
exports.instantiateSteps = instantiateSteps;
|
|
77
|
+
Object.defineProperty(exports, 'steps', {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function () {
|
|
80
|
+
return steps;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=steps.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.cjs","names":["invariant: Invariant","createInvariant","steps","resolvedSteps: Record<string, unknown>","DEFAULT_CASING","isCasingValid","CASING_TYPES","fields"],"sources":["../../src/steps/steps.ts"],"sourcesContent":["import {\n CASING_TYPES,\n CasingType,\n Constrain,\n DEFAULT_CASING,\n DefaultCasing,\n isCasingValid,\n type Expand,\n type Show,\n} from '@/utils';\nimport { createInvariant, type Invariant } from '@/utils/invariant';\nimport type { AnyValidator, DefaultValidator } from '@/utils/validator';\nimport { fields } from './fields';\nimport type { StepSpecificHelperFn } from './fn-utils/helper-fn/utils';\nimport type { ResetFn } from './fn-utils/reset-fn';\nimport type { UpdateFn } from './fn-utils/update-fn';\n\nexport const VALIDATED_STEP_REGEX = /^step\\d+$/i;\n\nexport namespace steps {\n type ValidStepKey<N extends number = number> = `step${N}`;\n\n export interface Config<\n TCasing extends CasingType,\n TFields extends fields.FieldConfig<TCasing>,\n TValidator = unknown,\n > extends fields.NameTransformCasingOptions<TCasing> {\n title: string;\n description?: string;\n fields: TFields;\n validateFields?: Constrain<TValidator, AnyValidator, DefaultValidator>;\n }\n export type AnyConfig = Config<\n CasingType,\n fields.FieldConfig<CasingType>,\n AnyValidator\n >;\n export type config<\n TCasing extends CasingType = DefaultCasing,\n TFields extends fields.FieldConfig<TCasing> = fields.FieldConfig<TCasing>,\n TValidator = unknown,\n > = Record<ValidStepKey, Config<TCasing, TFields, TValidator>>;\n\n export type instantiateConfig<TMap extends config = config> = {\n /**\n * The steps that this multi step form will include.\n * @example\n * ```ts\n * {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * name: {\n * defaultValue: '',\n * },\n * },\n * },\n * step2: {\n * title: 'Step 2',\n * fields: {\n * dateOfBirth: {\n * defaultValue: new Date(),\n * // `type` is automatically set to `date` if the defaultValue is a Date\n * },\n * },\n * },\n * }\n * ```\n */\n steps: TMap;\n };\n /**\n * Extended step specific properties for the step.\n */\n // @ts-expect-error - This is a placeholder for the extended step specific properties.\n export interface ExtendedStepSpecificProperties<t, key> {}\n export type _instantiateSteps<T = unknown> = [T] extends [object]\n ? T extends instantiateConfig\n ? {\n -readonly [key in keyof T['steps']]: Expand<\n {\n title: string;\n nameTransformCasing: fields.inferNameTransformCasing<\n T['steps'][key],\n DefaultCasing\n >;\n fields: fields.instantiateFields<\n T['steps'][key],\n fields.inferNameTransformCasing<T['steps'][key], DefaultCasing>\n >;\n } & (T['steps'][key] extends {\n description: infer description extends string;\n }\n ? { description: description }\n : {}) &\n ExtendedStepSpecificProperties<T, key>\n >;\n }\n : {}\n : {};\n /**\n * Extended step specific functions for the step.\n */\n export interface ExtendedStepSpecificFunctions<\n def,\n value,\n key extends StepNumbers<value>,\n > {}\n export type instantiateSteps<\n t = unknown,\n value = _instantiateSteps<t>,\n > = Expand<{\n [key in keyof value]: Show<\n value[key] &\n (value extends {}\n ? key extends StepNumbers<value>\n ? {\n update: UpdateFn.stepSpecific<value, key>;\n reset: ResetFn.stepSpecific<value, key>;\n createHelperFn: StepSpecificHelperFn<value, key>;\n } & ExtendedStepSpecificFunctions<t, value, key>\n : {}\n : {})\n >;\n }>;\n export type Any = instantiateSteps<instantiateConfig>;\n export type StepNumbers<T> = keyof T extends string ? keyof T : never;\n export type getCurrent<\n value extends instantiateSteps,\n stepNumbers extends StepNumbers<value>,\n > = value[stepNumbers];\n\n export function instantiate<\n const def extends instantiateConfig,\n inst = instantiateSteps<def>,\n >(def: def) {\n const { steps } = def;\n const invariant: Invariant = createInvariant('[instantiateSteps]');\n\n invariant(\n steps,\n 'No steps were provided to the \"steps\" option.',\n TypeError\n );\n invariant(\n typeof steps === 'object',\n '\"steps\" must be an object.',\n TypeError\n );\n invariant(\n Object.keys(steps).length > 0,\n '\"steps\" must contain at least one step.',\n TypeError\n );\n\n let resolvedSteps: Record<string, unknown> = {};\n\n for (const [stepKey, stepValue] of Object.entries(steps)) {\n const invariant: Invariant = createInvariant(\n `[instantiateSteps - ${stepKey}]`\n );\n\n invariant(\n typeof stepKey === 'string',\n `Each key for the step config must be a string. Key \"${stepKey}\" was ${typeof stepKey} `,\n TypeError\n );\n invariant(\n VALIDATED_STEP_REGEX.test(stepKey),\n `The key \"${stepKey}\" isn't formatted properly. Each key in the step config must be the following format: \"step{number}\"`\n );\n\n const {\n fields: fieldsDef,\n title,\n description,\n validateFields,\n nameTransformCasing = DEFAULT_CASING,\n } = stepValue;\n\n // title validation\n invariant(title, 'A title must be provided for each step.', TypeError);\n invariant(\n typeof title === 'string',\n 'The title must be a string.',\n TypeError\n );\n\n if (description) {\n invariant(\n typeof description === 'string',\n 'The description must be a string.',\n TypeError\n );\n }\n\n if (nameTransformCasing) {\n invariant(\n typeof nameTransformCasing === 'string',\n `The nameTransformCasing must be a string. Was ${typeof nameTransformCasing}`,\n TypeError\n );\n invariant(\n isCasingValid(nameTransformCasing),\n (formatter) =>\n `The nameTransformCasing is not a valid casing. Was ${nameTransformCasing}, must be one of ${formatter.format(\n CASING_TYPES\n )}`,\n TypeError\n );\n }\n\n const instantiatedFields = fields.instantiate({\n fields: fieldsDef,\n defaultCasing: nameTransformCasing,\n validateFields,\n });\n\n resolvedSteps[stepKey] = {\n ...(resolvedSteps[stepKey] as Record<string, unknown>),\n title,\n // Only add the description if it's defined\n ...(typeof description === 'string' ? { description } : {}),\n nameTransformCasing,\n fields: instantiatedFields,\n };\n }\n\n return resolvedSteps as inst;\n }\n\n function isValidStepValue(stepValue: unknown): stepValue is AnyConfig {\n if (stepValue === null || typeof stepValue !== 'object') {\n return false;\n }\n\n const step = stepValue as Record<string, unknown>;\n\n // Must have title\n if (!('title' in step) || typeof step.title !== 'string') {\n return false;\n }\n\n // If description is provided, it must be a string\n if ('description' in step) {\n if (typeof step.description !== 'string') {\n return false;\n }\n }\n\n // If nameTransformCasing is provided, it must be a valid casing\n if ('nameTransformCasing' in step) {\n const casing = step.nameTransformCasing;\n if (typeof casing !== 'string' || !isCasingValid(casing)) {\n return false;\n }\n }\n\n // Must have fields and it must be a valid field config\n if (!('fields' in step)) {\n return false;\n }\n\n return fields.isValidFieldConfig(step.fields);\n }\n\n export function isValidSteps(value: unknown): value is config {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n\n const steps = value as Record<string, unknown>;\n\n // Check if steps has at least one key\n if (Object.keys(steps).length === 0) {\n return false;\n }\n\n // Validate each step\n for (const [stepKey, stepValue] of Object.entries(steps)) {\n // Each key must be a string\n if (typeof stepKey !== 'string') {\n return false;\n }\n\n // Each key must match the step regex pattern\n if (!VALIDATED_STEP_REGEX.test(stepKey)) {\n return false;\n }\n\n // Each value must be a valid step config\n if (!isValidStepValue(stepValue)) {\n return false;\n }\n }\n\n return true;\n }\n}\n\nexport const instantiateSteps = steps.instantiate;\n"],"mappings":";;;;;;AAiBA,MAAa,uBAAuB;;;CAmH3B,SAAS,YAGd,KAAU;EACV,MAAM,EAAE,mBAAU;EAClB,MAAMA,YAAuBC,kCAAgB,qBAAqB;AAElE,YACEC,SACA,mDACA,UACD;AACD,YACE,OAAOA,YAAU,UACjB,gCACA,UACD;AACD,YACE,OAAO,KAAKA,QAAM,CAAC,SAAS,GAC5B,6CACA,UACD;EAED,IAAIC,gBAAyC,EAAE;AAE/C,OAAK,MAAM,CAAC,SAAS,cAAc,OAAO,QAAQD,QAAM,EAAE;GACxD,MAAMF,cAAuBC,kCAC3B,uBAAuB,QAAQ,GAChC;AAED,eACE,OAAO,YAAY,UACnB,uDAAuD,QAAQ,QAAQ,OAAO,QAAQ,IACtF,UACD;AACD,eACE,qBAAqB,KAAK,QAAQ,EAClC,YAAY,QAAQ,sGACrB;GAED,MAAM,EACJ,QAAQ,WACR,OACA,aACA,gBACA,sBAAsBG,kCACpB;AAGJ,eAAU,OAAO,2CAA2C,UAAU;AACtE,eACE,OAAO,UAAU,UACjB,+BACA,UACD;AAED,OAAI,YACF,aACE,OAAO,gBAAgB,UACvB,qCACA,UACD;AAGH,OAAI,qBAAqB;AACvB,gBACE,OAAO,wBAAwB,UAC/B,iDAAiD,OAAO,uBACxD,UACD;AACD,gBACEC,6BAAc,oBAAoB,GACjC,cACC,sDAAsD,oBAAoB,mBAAmB,UAAU,OACrGC,4BACD,IACH,UACD;;GAGH,MAAM,qBAAqBC,sBAAO,YAAY;IAC5C,QAAQ;IACR,eAAe;IACf;IACD,CAAC;AAEF,iBAAc,WAAW;IACvB,GAAI,cAAc;IAClB;IAEA,GAAI,OAAO,gBAAgB,WAAW,EAAE,aAAa,GAAG,EAAE;IAC1D;IACA,QAAQ;IACT;;AAGH,SAAO;;;CAGT,SAAS,iBAAiB,WAA4C;AACpE,MAAI,cAAc,QAAQ,OAAO,cAAc,SAC7C,QAAO;EAGT,MAAM,OAAO;AAGb,MAAI,EAAE,WAAW,SAAS,OAAO,KAAK,UAAU,SAC9C,QAAO;AAIT,MAAI,iBAAiB,MACnB;OAAI,OAAO,KAAK,gBAAgB,SAC9B,QAAO;;AAKX,MAAI,yBAAyB,MAAM;GACjC,MAAM,SAAS,KAAK;AACpB,OAAI,OAAO,WAAW,YAAY,CAACF,6BAAc,OAAO,CACtD,QAAO;;AAKX,MAAI,EAAE,YAAY,MAChB,QAAO;AAGT,SAAOE,sBAAO,mBAAmB,KAAK,OAAO;;CAGxC,SAAS,aAAa,OAAiC;AAC5D,MAAI,UAAU,QAAQ,OAAO,UAAU,SACrC,QAAO;EAGT,MAAML,UAAQ;AAGd,MAAI,OAAO,KAAKA,QAAM,CAAC,WAAW,EAChC,QAAO;AAIT,OAAK,MAAM,CAAC,SAAS,cAAc,OAAO,QAAQA,QAAM,EAAE;AAExD,OAAI,OAAO,YAAY,SACrB,QAAO;AAIT,OAAI,CAAC,qBAAqB,KAAK,QAAQ,CACrC,QAAO;AAIT,OAAI,CAAC,iBAAiB,UAAU,CAC9B,QAAO;;AAIX,SAAO;;;;AAIX,MAAa,mBAAmB,MAAM"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Constrain, Expand, Show } from "../utils/types.cjs";
|
|
2
|
+
import { CasingType, DefaultCasing } from "../utils/casing.cjs";
|
|
3
|
+
import { AnyValidator, DefaultValidator } from "../utils/validator.cjs";
|
|
4
|
+
import { fields } from "./fields.cjs";
|
|
5
|
+
import { UpdateFn } from "./fn-utils/update-fn.cjs";
|
|
6
|
+
import { ResetFn } from "./fn-utils/reset-fn.cjs";
|
|
7
|
+
import { StepSpecificHelperFn } from "./fn-utils/helper-fn/utils.cjs";
|
|
8
|
+
|
|
9
|
+
//#region src/steps/steps.d.ts
|
|
10
|
+
declare const VALIDATED_STEP_REGEX: RegExp;
|
|
11
|
+
declare namespace steps {
|
|
12
|
+
type ValidStepKey<N extends number = number> = `step${N}`;
|
|
13
|
+
export interface Config<TCasing extends CasingType, TFields extends fields.FieldConfig<TCasing>, TValidator = unknown> extends fields.NameTransformCasingOptions<TCasing> {
|
|
14
|
+
title: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
fields: TFields;
|
|
17
|
+
validateFields?: Constrain<TValidator, AnyValidator, DefaultValidator>;
|
|
18
|
+
}
|
|
19
|
+
export type AnyConfig = Config<CasingType, fields.FieldConfig<CasingType>, AnyValidator>;
|
|
20
|
+
export type config<TCasing extends CasingType = DefaultCasing, TFields extends fields.FieldConfig<TCasing> = fields.FieldConfig<TCasing>, TValidator = unknown> = Record<ValidStepKey, Config<TCasing, TFields, TValidator>>;
|
|
21
|
+
export type instantiateConfig<TMap extends config = config> = {
|
|
22
|
+
/**
|
|
23
|
+
* The steps that this multi step form will include.
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* {
|
|
27
|
+
* step1: {
|
|
28
|
+
* title: 'Step 1',
|
|
29
|
+
* fields: {
|
|
30
|
+
* name: {
|
|
31
|
+
* defaultValue: '',
|
|
32
|
+
* },
|
|
33
|
+
* },
|
|
34
|
+
* },
|
|
35
|
+
* step2: {
|
|
36
|
+
* title: 'Step 2',
|
|
37
|
+
* fields: {
|
|
38
|
+
* dateOfBirth: {
|
|
39
|
+
* defaultValue: new Date(),
|
|
40
|
+
* // `type` is automatically set to `date` if the defaultValue is a Date
|
|
41
|
+
* },
|
|
42
|
+
* },
|
|
43
|
+
* },
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
steps: TMap;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Extended step specific properties for the step.
|
|
51
|
+
*/
|
|
52
|
+
export interface ExtendedStepSpecificProperties<t, key> {}
|
|
53
|
+
export type _instantiateSteps<T = unknown> = [T] extends [object] ? T extends instantiateConfig ? { -readonly [key in keyof T['steps']]: Expand<{
|
|
54
|
+
title: string;
|
|
55
|
+
nameTransformCasing: fields.inferNameTransformCasing<T['steps'][key], DefaultCasing>;
|
|
56
|
+
fields: fields.instantiateFields<T['steps'][key], fields.inferNameTransformCasing<T['steps'][key], DefaultCasing>>;
|
|
57
|
+
} & (T['steps'][key] extends {
|
|
58
|
+
description: infer description extends string;
|
|
59
|
+
} ? {
|
|
60
|
+
description: description;
|
|
61
|
+
} : {}) & ExtendedStepSpecificProperties<T, key>> } : {} : {};
|
|
62
|
+
/**
|
|
63
|
+
* Extended step specific functions for the step.
|
|
64
|
+
*/
|
|
65
|
+
export interface ExtendedStepSpecificFunctions<def, value, key extends StepNumbers<value>> {}
|
|
66
|
+
export type instantiateSteps<t = unknown, value = _instantiateSteps<t>> = Expand<{ [key in keyof value]: Show<value[key] & (value extends {} ? key extends StepNumbers<value> ? {
|
|
67
|
+
update: UpdateFn.stepSpecific<value, key>;
|
|
68
|
+
reset: ResetFn.stepSpecific<value, key>;
|
|
69
|
+
createHelperFn: StepSpecificHelperFn<value, key>;
|
|
70
|
+
} & ExtendedStepSpecificFunctions<t, value, key> : {} : {})> }>;
|
|
71
|
+
export type Any = instantiateSteps<instantiateConfig>;
|
|
72
|
+
export type StepNumbers<T> = keyof T extends string ? keyof T : never;
|
|
73
|
+
export type getCurrent<value extends instantiateSteps, stepNumbers extends StepNumbers<value>> = value[stepNumbers];
|
|
74
|
+
export function instantiate<const def extends instantiateConfig, inst = instantiateSteps<def>>(def: def): inst;
|
|
75
|
+
export function isValidSteps(value: unknown): value is config;
|
|
76
|
+
export {};
|
|
77
|
+
}
|
|
78
|
+
declare const instantiateSteps: typeof steps.instantiate;
|
|
79
|
+
//#endregion
|
|
80
|
+
export { VALIDATED_STEP_REGEX, steps };
|
|
81
|
+
//# sourceMappingURL=steps.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.cts","names":[],"sources":["../../src/steps/steps.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Constrain, Expand, Show } from "../utils/types.mjs";
|
|
2
|
+
import { CasingType, DefaultCasing } from "../utils/casing.mjs";
|
|
3
|
+
import { AnyValidator, DefaultValidator } from "../utils/validator.mjs";
|
|
4
|
+
import { fields } from "./fields.mjs";
|
|
5
|
+
import { UpdateFn } from "./fn-utils/update-fn.mjs";
|
|
6
|
+
import { ResetFn } from "./fn-utils/reset-fn.mjs";
|
|
7
|
+
import { StepSpecificHelperFn } from "./fn-utils/helper-fn/utils.mjs";
|
|
8
|
+
|
|
9
|
+
//#region src/steps/steps.d.ts
|
|
10
|
+
declare const VALIDATED_STEP_REGEX: RegExp;
|
|
11
|
+
declare namespace steps {
|
|
12
|
+
type ValidStepKey<N extends number = number> = `step${N}`;
|
|
13
|
+
export interface Config<TCasing extends CasingType, TFields extends fields.FieldConfig<TCasing>, TValidator = unknown> extends fields.NameTransformCasingOptions<TCasing> {
|
|
14
|
+
title: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
fields: TFields;
|
|
17
|
+
validateFields?: Constrain<TValidator, AnyValidator, DefaultValidator>;
|
|
18
|
+
}
|
|
19
|
+
export type AnyConfig = Config<CasingType, fields.FieldConfig<CasingType>, AnyValidator>;
|
|
20
|
+
export type config<TCasing extends CasingType = DefaultCasing, TFields extends fields.FieldConfig<TCasing> = fields.FieldConfig<TCasing>, TValidator = unknown> = Record<ValidStepKey, Config<TCasing, TFields, TValidator>>;
|
|
21
|
+
export type instantiateConfig<TMap extends config = config> = {
|
|
22
|
+
/**
|
|
23
|
+
* The steps that this multi step form will include.
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* {
|
|
27
|
+
* step1: {
|
|
28
|
+
* title: 'Step 1',
|
|
29
|
+
* fields: {
|
|
30
|
+
* name: {
|
|
31
|
+
* defaultValue: '',
|
|
32
|
+
* },
|
|
33
|
+
* },
|
|
34
|
+
* },
|
|
35
|
+
* step2: {
|
|
36
|
+
* title: 'Step 2',
|
|
37
|
+
* fields: {
|
|
38
|
+
* dateOfBirth: {
|
|
39
|
+
* defaultValue: new Date(),
|
|
40
|
+
* // `type` is automatically set to `date` if the defaultValue is a Date
|
|
41
|
+
* },
|
|
42
|
+
* },
|
|
43
|
+
* },
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
steps: TMap;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Extended step specific properties for the step.
|
|
51
|
+
*/
|
|
52
|
+
export interface ExtendedStepSpecificProperties<t, key> {}
|
|
53
|
+
export type _instantiateSteps<T = unknown> = [T] extends [object] ? T extends instantiateConfig ? { -readonly [key in keyof T['steps']]: Expand<{
|
|
54
|
+
title: string;
|
|
55
|
+
nameTransformCasing: fields.inferNameTransformCasing<T['steps'][key], DefaultCasing>;
|
|
56
|
+
fields: fields.instantiateFields<T['steps'][key], fields.inferNameTransformCasing<T['steps'][key], DefaultCasing>>;
|
|
57
|
+
} & (T['steps'][key] extends {
|
|
58
|
+
description: infer description extends string;
|
|
59
|
+
} ? {
|
|
60
|
+
description: description;
|
|
61
|
+
} : {}) & ExtendedStepSpecificProperties<T, key>> } : {} : {};
|
|
62
|
+
/**
|
|
63
|
+
* Extended step specific functions for the step.
|
|
64
|
+
*/
|
|
65
|
+
export interface ExtendedStepSpecificFunctions<def, value, key extends StepNumbers<value>> {}
|
|
66
|
+
export type instantiateSteps<t = unknown, value = _instantiateSteps<t>> = Expand<{ [key in keyof value]: Show<value[key] & (value extends {} ? key extends StepNumbers<value> ? {
|
|
67
|
+
update: UpdateFn.stepSpecific<value, key>;
|
|
68
|
+
reset: ResetFn.stepSpecific<value, key>;
|
|
69
|
+
createHelperFn: StepSpecificHelperFn<value, key>;
|
|
70
|
+
} & ExtendedStepSpecificFunctions<t, value, key> : {} : {})> }>;
|
|
71
|
+
export type Any = instantiateSteps<instantiateConfig>;
|
|
72
|
+
export type StepNumbers<T> = keyof T extends string ? keyof T : never;
|
|
73
|
+
export type getCurrent<value extends instantiateSteps, stepNumbers extends StepNumbers<value>> = value[stepNumbers];
|
|
74
|
+
export function instantiate<const def extends instantiateConfig, inst = instantiateSteps<def>>(def: def): inst;
|
|
75
|
+
export function isValidSteps(value: unknown): value is config;
|
|
76
|
+
export {};
|
|
77
|
+
}
|
|
78
|
+
declare const instantiateSteps: typeof steps.instantiate;
|
|
79
|
+
//#endregion
|
|
80
|
+
export { VALIDATED_STEP_REGEX, steps };
|
|
81
|
+
//# sourceMappingURL=steps.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.mts","names":[],"sources":["../../src/steps/steps.ts"],"sourcesContent":[],"mappings":"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"}
|