@jfdevelops/multi-step-form-core 1.0.0-alpha.11 → 1.0.0-alpha.13
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 +13 -9
- package/dist/_internals.d.cts +4 -0
- package/dist/_internals.d.mts +4 -0
- package/dist/_internals.mjs +5 -7
- package/dist/index.cjs +45 -669
- package/dist/index.d.cts +14 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.mjs +16 -668
- package/dist/internals/step-schema.cjs +309 -0
- package/dist/internals/step-schema.cjs.map +1 -0
- package/dist/internals/step-schema.d.cts +39 -0
- package/dist/internals/step-schema.d.cts.map +1 -0
- package/dist/internals/step-schema.d.mts +39 -0
- package/dist/internals/step-schema.d.mts.map +1 -0
- package/dist/internals/step-schema.mjs +309 -0
- package/dist/internals/step-schema.mjs.map +1 -0
- package/dist/internals/utils.cjs +94 -0
- package/dist/internals/utils.cjs.map +1 -0
- package/dist/internals/utils.d.cts +27 -0
- package/dist/internals/utils.d.cts.map +1 -0
- package/dist/internals/utils.d.mts +27 -0
- package/dist/internals/utils.d.mts.map +1 -0
- package/dist/internals/utils.mjs +91 -0
- package/dist/internals/utils.mjs.map +1 -0
- package/dist/observable.cjs +44 -0
- package/dist/observable.cjs.map +1 -0
- package/dist/observable.d.cts +26 -0
- package/dist/observable.d.cts.map +1 -0
- package/dist/observable.d.mts +26 -0
- package/dist/observable.d.mts.map +1 -0
- package/dist/observable.mjs +44 -0
- package/dist/observable.mjs.map +1 -0
- package/dist/schema.cjs +68 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +28 -0
- package/dist/schema.d.cts.map +1 -0
- package/dist/schema.d.mts +28 -0
- package/dist/schema.d.mts.map +1 -0
- package/dist/schema.mjs +67 -0
- package/dist/schema.mjs.map +1 -0
- package/dist/steps/fields.cjs +23 -0
- package/dist/steps/fields.cjs.map +1 -0
- package/dist/steps/fields.d.cts +18 -0
- package/dist/steps/fields.d.cts.map +1 -0
- package/dist/steps/fields.d.mts +18 -0
- package/dist/steps/fields.d.mts.map +1 -0
- package/dist/steps/fields.mjs +18 -0
- package/dist/steps/fields.mjs.map +1 -0
- package/dist/steps/index.cjs +4 -0
- package/dist/steps/index.mjs +6 -0
- package/dist/steps/schema.cjs +194 -0
- package/dist/steps/schema.cjs.map +1 -0
- package/dist/steps/schema.d.cts +124 -0
- package/dist/steps/schema.d.cts.map +1 -0
- package/dist/steps/schema.d.mts +124 -0
- package/dist/steps/schema.d.mts.map +1 -0
- package/dist/steps/schema.mjs +194 -0
- package/dist/steps/schema.mjs.map +1 -0
- package/dist/steps/types.cjs +33 -0
- package/dist/steps/types.cjs.map +1 -0
- package/dist/steps/types.d.cts +268 -0
- package/dist/steps/types.d.cts.map +1 -0
- package/dist/steps/types.d.mts +268 -0
- package/dist/steps/types.d.mts.map +1 -0
- package/dist/steps/types.mjs +27 -0
- package/dist/steps/types.mjs.map +1 -0
- package/dist/steps/utils.cjs +96 -0
- package/dist/steps/utils.cjs.map +1 -0
- package/dist/steps/utils.d.cts +10 -0
- package/dist/steps/utils.d.cts.map +1 -0
- package/dist/steps/utils.d.mts +10 -0
- package/dist/steps/utils.d.mts.map +1 -0
- package/dist/steps/utils.mjs +94 -0
- package/dist/steps/utils.mjs.map +1 -0
- package/dist/storage.cjs +72 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +33 -0
- package/dist/storage.d.cts.map +1 -0
- package/dist/storage.d.mts +33 -0
- package/dist/storage.d.mts.map +1 -0
- package/dist/storage.mjs +71 -0
- package/dist/storage.mjs.map +1 -0
- package/dist/subscribable.cjs +25 -0
- package/dist/subscribable.cjs.map +1 -0
- package/dist/subscribable.d.cts +14 -0
- package/dist/subscribable.d.cts.map +1 -0
- package/dist/subscribable.d.mts +14 -0
- package/dist/subscribable.d.mts.map +1 -0
- package/dist/subscribable.mjs +24 -0
- package/dist/subscribable.mjs.map +1 -0
- package/dist/utils/casing.cjs +63 -0
- package/dist/utils/casing.cjs.map +1 -0
- package/dist/utils/casing.d.cts +40 -0
- package/dist/utils/casing.d.cts.map +1 -0
- package/dist/utils/casing.d.mts +40 -0
- package/dist/utils/casing.d.mts.map +1 -0
- package/dist/utils/casing.mjs +57 -0
- package/dist/utils/casing.mjs.map +1 -0
- package/dist/utils/field-types.cjs +23 -0
- package/dist/utils/field-types.cjs.map +1 -0
- package/dist/utils/field-types.d.cts +11 -0
- package/dist/utils/field-types.d.cts.map +1 -0
- package/dist/utils/field-types.d.mts +11 -0
- package/dist/utils/field-types.d.mts.map +1 -0
- package/dist/utils/field-types.mjs +20 -0
- package/dist/utils/field-types.mjs.map +1 -0
- package/dist/utils/helpers.cjs +30 -0
- package/dist/utils/helpers.cjs.map +1 -0
- package/dist/utils/helpers.mjs +27 -0
- package/dist/utils/helpers.mjs.map +1 -0
- package/dist/utils/invariant.cjs +18 -0
- package/dist/utils/invariant.cjs.map +1 -0
- package/dist/utils/invariant.d.cts +5 -0
- package/dist/utils/invariant.d.cts.map +1 -0
- package/dist/utils/invariant.d.mts +5 -0
- package/dist/utils/invariant.d.mts.map +1 -0
- package/dist/utils/invariant.mjs +17 -0
- package/dist/utils/invariant.mjs.map +1 -0
- package/dist/utils/logger.cjs +58 -0
- package/dist/utils/logger.cjs.map +1 -0
- package/dist/utils/logger.d.cts +53 -0
- package/dist/utils/logger.d.cts.map +1 -0
- package/dist/utils/logger.d.mts +53 -0
- package/dist/utils/logger.d.mts.map +1 -0
- package/dist/utils/logger.mjs +56 -0
- package/dist/utils/logger.mjs.map +1 -0
- package/dist/utils/path.cjs +272 -0
- package/dist/utils/path.cjs.map +1 -0
- package/dist/utils/path.d.cts +131 -0
- package/dist/utils/path.d.cts.map +1 -0
- package/dist/utils/path.d.mts +131 -0
- package/dist/utils/path.d.mts.map +1 -0
- package/dist/utils/path.mjs +266 -0
- package/dist/utils/path.mjs.map +1 -0
- package/dist/utils/types.d.cts +23 -0
- package/dist/utils/types.d.cts.map +1 -0
- package/dist/utils/types.d.mts +23 -0
- package/dist/utils/types.d.mts.map +1 -0
- package/dist/utils/validator.cjs +12 -0
- package/dist/utils/validator.cjs.map +1 -0
- package/dist/utils/validator.d.cts +77 -0
- package/dist/utils/validator.d.cts.map +1 -0
- package/dist/utils/validator.d.mts +77 -0
- package/dist/utils/validator.d.mts.map +1 -0
- package/dist/utils/validator.mjs +11 -0
- package/dist/utils/validator.mjs.map +1 -0
- package/package.json +17 -12
- package/dist/_internals.cjs.map +0 -1
- package/dist/_internals.mjs.map +0 -1
- package/dist/errors/invalid-key.d.ts +0 -18
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.mjs.map +0 -1
- package/dist/internals/index.d.ts +0 -2
- package/dist/internals/step-schema.d.ts +0 -28
- package/dist/observable.d.ts +0 -21
- package/dist/schema.d.ts +0 -22
- package/dist/steps/fields.d.ts +0 -20
- package/dist/steps/index.d.ts +0 -4
- package/dist/steps/schema.d.ts +0 -138
- package/dist/steps/types.d.ts +0 -295
- package/dist/steps/utils.d.ts +0 -21
- package/dist/storage.d.ts +0 -28
- package/dist/subscribable.d.ts +0 -10
- package/dist/types-C4Mgnku6.cjs +0 -949
- package/dist/types-C4Mgnku6.cjs.map +0 -1
- package/dist/types-CYf1_lBe.js +0 -953
- package/dist/types-CYf1_lBe.js.map +0 -1
- package/dist/utils/casing.d.ts +0 -38
- package/dist/utils/field-types.d.ts +0 -6
- package/dist/utils/helper-fns.d.ts +0 -8
- package/dist/utils/helpers.d.ts +0 -8
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/invariant.d.ts +0 -1
- package/dist/utils/logger.d.ts +0 -50
- package/dist/utils/path.d.ts +0 -141
- package/dist/utils/types.d.ts +0 -34
- package/dist/utils/validator.d.ts +0 -74
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { comparePartialArray, printErrors } from "../utils/helpers.mjs";
|
|
2
|
+
import { invariant } from "../utils/invariant.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/steps/utils.ts
|
|
5
|
+
/**
|
|
6
|
+
* Gets the step number from an input string.
|
|
7
|
+
* @param input The input to extract the step number from.
|
|
8
|
+
* @returns The extracted step number.
|
|
9
|
+
*/
|
|
10
|
+
function extractNumber(input) {
|
|
11
|
+
invariant(input.includes("step"), "Can't extract a valid step number since");
|
|
12
|
+
const extracted = input.replace("step", "");
|
|
13
|
+
invariant(/^\d+$/.test(extracted), `Invalid step format: "${input}"`);
|
|
14
|
+
return Number.parseInt(extracted, 10);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A factory function to get the data of a specific step.
|
|
18
|
+
* @param resolvedStepValues The resolved step values.
|
|
19
|
+
* @returns A function to get specific step data from a target step.
|
|
20
|
+
*/
|
|
21
|
+
function getStep(resolvedStepValues) {
|
|
22
|
+
/**
|
|
23
|
+
* Gets the step data associated with the target step number.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const result = getStep(resolvedStepValues)({ step: 1 });
|
|
27
|
+
* // result: { step: 1, data: ... }
|
|
28
|
+
*
|
|
29
|
+
* @returns An object containing the `step` number and the associated step data.
|
|
30
|
+
*/
|
|
31
|
+
return function(options) {
|
|
32
|
+
const { step } = options;
|
|
33
|
+
return {
|
|
34
|
+
step,
|
|
35
|
+
data: resolvedStepValues[`step${step}`]
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function createCtxHelper(values, data) {
|
|
40
|
+
return data.reduce((acc, curr) => {
|
|
41
|
+
const stepNumber = extractNumber(curr);
|
|
42
|
+
const { data: data$1 } = getStep(values)({ step: stepNumber });
|
|
43
|
+
for (const [key, value] of Object.entries(data$1)) {
|
|
44
|
+
if (typeof value === "function" && key !== "update") continue;
|
|
45
|
+
data$1[key] = value;
|
|
46
|
+
}
|
|
47
|
+
acc[curr] = data$1;
|
|
48
|
+
return acc;
|
|
49
|
+
}, {});
|
|
50
|
+
}
|
|
51
|
+
function createCtx(values, stepData) {
|
|
52
|
+
const formatter = new Intl.ListFormat("en", {
|
|
53
|
+
style: "long",
|
|
54
|
+
type: "disjunction"
|
|
55
|
+
});
|
|
56
|
+
const validStepKeys = Object.keys(values);
|
|
57
|
+
const baseErrorMessage = () => {
|
|
58
|
+
return `"stepData" must be set to an array of available steps (${formatter.format(validStepKeys)})`;
|
|
59
|
+
};
|
|
60
|
+
if (stepData === "all") {
|
|
61
|
+
let ctx = {};
|
|
62
|
+
for (const key of validStepKeys) ctx = {
|
|
63
|
+
...ctx,
|
|
64
|
+
[key]: getStep(values)({ step: extractNumber(key) })
|
|
65
|
+
};
|
|
66
|
+
return createCtxHelper(values, validStepKeys);
|
|
67
|
+
}
|
|
68
|
+
if (Array.isArray(stepData)) {
|
|
69
|
+
invariant(stepData.every((step) => validStepKeys.includes(step)), () => {
|
|
70
|
+
const comparedResults = comparePartialArray(stepData, validStepKeys.map((key) => extractNumber(key)), formatter);
|
|
71
|
+
if (comparedResults.status === "error") return `${baseErrorMessage()}. See errors:\n ${printErrors(comparedResults.errors)}`;
|
|
72
|
+
return baseErrorMessage();
|
|
73
|
+
});
|
|
74
|
+
return createCtxHelper(values, stepData);
|
|
75
|
+
}
|
|
76
|
+
if (typeof stepData === "object") {
|
|
77
|
+
const keys = Object.keys(stepData);
|
|
78
|
+
invariant(keys.every((key) => validStepKeys.includes(key)), () => {
|
|
79
|
+
const comparedResults = comparePartialArray(keys, validStepKeys, formatter);
|
|
80
|
+
if (comparedResults.status === "error") return `${baseErrorMessage()}. See errors:\n ${printErrors(comparedResults.errors)}`;
|
|
81
|
+
return baseErrorMessage();
|
|
82
|
+
});
|
|
83
|
+
return createCtxHelper(values, keys);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`${baseErrorMessage()} OR to "all"`);
|
|
86
|
+
}
|
|
87
|
+
function functionalUpdate(updater, input) {
|
|
88
|
+
if (typeof updater === "function") return updater(input);
|
|
89
|
+
return updater;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
export { createCtx, functionalUpdate, getStep };
|
|
94
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["data"],"sources":["../../src/steps/utils.ts"],"sourcesContent":["import { comparePartialArray, printErrors } from '@/utils/helpers';\nimport { invariant } from '@/utils/invariant';\nimport type {\n AnyResolvedStep,\n GetCurrentStep,\n HelperFnChosenSteps,\n HelperFnCtx,\n StepNumbers,\n Updater,\n} from './types';\n\nexport type GetStepOptions<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TStepNumber extends TStepNumbers\n> = { step: TStepNumber };\n\n/**\n * Gets the step number from an input string.\n * @param input The input to extract the step number from.\n * @returns The extracted step number.\n */\nexport function extractNumber(input: string) {\n invariant(input.includes('step'), \"Can't extract a valid step number since\");\n\n const extracted = input.replace('step', '');\n\n invariant(/^\\d+$/.test(extracted), `Invalid step format: \"${input}\"`);\n\n return Number.parseInt(extracted, 10);\n}\n\n/**\n * A factory function to get the data of a specific step.\n * @param resolvedStepValues The resolved step values.\n * @returns A function to get specific step data from a target step.\n */\nexport function getStep<\n resolvedStep extends AnyResolvedStep,\n stepNumbers extends StepNumbers<resolvedStep>\n>(resolvedStepValues: resolvedStep) {\n /**\n * Gets the step data associated with the target step number.\n *\n * @example\n * const result = getStep(resolvedStepValues)({ step: 1 });\n * // result: { step: 1, data: ... }\n *\n * @returns An object containing the `step` number and the associated step data.\n */\n return function <stepNumber extends stepNumbers>(\n options: GetStepOptions<resolvedStep, stepNumbers, stepNumber>\n ) {\n const { step } = options;\n const stepKey = `step${step}` as keyof typeof resolvedStepValues;\n\n const data = resolvedStepValues[stepKey] as GetCurrentStep<\n typeof resolvedStepValues,\n stepNumber\n >;\n\n return { step, data };\n };\n}\n\nfunction createCtxHelper<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>\n>(values: TResolvedStep, data: string[]) {\n return data.reduce((acc, curr) => {\n const stepNumber = extractNumber(curr);\n const { data } = getStep(values)({\n step: stepNumber as TStepNumbers,\n });\n\n for (const [key, value] of Object.entries(data)) {\n // console.log({ [key]: value });\n // Remove the functions from the data to comply with `StrippedResolvedStep`\n if (typeof value === 'function' && key !== 'update') {\n continue;\n }\n\n data[key as keyof typeof data] = value as never;\n }\n\n acc[curr as keyof typeof acc] = data as never;\n\n return acc;\n }, {} as HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps>);\n}\n\nexport function createCtx<\n TResolvedStep extends AnyResolvedStep,\n TStepNumbers extends StepNumbers<TResolvedStep>,\n TChosenSteps extends HelperFnChosenSteps<TResolvedStep, TStepNumbers>\n>(values: TResolvedStep, stepData: TChosenSteps) {\n const formatter = new Intl.ListFormat('en', {\n style: 'long',\n type: 'disjunction',\n });\n const validStepKeys = Object.keys(values);\n\n const baseErrorMessage = () => {\n return `\"stepData\" must be set to an array of available steps (${formatter.format(\n validStepKeys\n )})`;\n };\n\n if (stepData === 'all') {\n let ctx = {} as HelperFnCtx<TResolvedStep, TStepNumbers, TChosenSteps>;\n\n for (const key of validStepKeys) {\n ctx = {\n ...ctx,\n [key]: getStep(values)({\n step: extractNumber(key) as never,\n }),\n };\n }\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n validStepKeys\n );\n }\n\n if (Array.isArray(stepData)) {\n invariant(\n stepData.every((step) => validStepKeys.includes(step)),\n () => {\n const comparedResults = comparePartialArray(\n stepData,\n validStepKeys.map((key) => extractNumber(key)),\n formatter\n );\n\n if (comparedResults.status === 'error') {\n return `${baseErrorMessage()}. See errors:\\n ${printErrors(\n comparedResults.errors\n )}`;\n }\n\n return baseErrorMessage();\n }\n );\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n stepData\n );\n }\n\n if (typeof stepData === 'object') {\n const keys = Object.keys(stepData);\n\n invariant(\n keys.every((key) => validStepKeys.includes(key)),\n () => {\n const comparedResults = comparePartialArray(\n keys,\n validStepKeys,\n formatter\n );\n\n if (comparedResults.status === 'error') {\n return `${baseErrorMessage()}. See errors:\\n ${printErrors(\n comparedResults.errors\n )}`;\n }\n\n return baseErrorMessage();\n }\n );\n\n return createCtxHelper<TResolvedStep, TStepNumbers, TChosenSteps>(\n values,\n keys\n );\n }\n\n throw new Error(`${baseErrorMessage()} OR to \"all\"`);\n}\n\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput\n) {\n if (typeof updater === 'function') {\n return (updater as (_: TInput) => TOutput)(input);\n }\n\n return updater;\n}\n"],"mappings":";;;;;;;;;AAsBA,SAAgB,cAAc,OAAe;AAC3C,WAAU,MAAM,SAAS,OAAO,EAAE,0CAA0C;CAE5E,MAAM,YAAY,MAAM,QAAQ,QAAQ,GAAG;AAE3C,WAAU,QAAQ,KAAK,UAAU,EAAE,yBAAyB,MAAM,GAAG;AAErE,QAAO,OAAO,SAAS,WAAW,GAAG;;;;;;;AAQvC,SAAgB,QAGd,oBAAkC;;;;;;;;;;AAUlC,QAAO,SACL,SACA;EACA,MAAM,EAAE,SAAS;AAQjB,SAAO;GAAE;GAAM,MALF,mBAFG,OAAO;GAOF;;;AAIzB,SAAS,gBAIP,QAAuB,MAAgB;AACvC,QAAO,KAAK,QAAQ,KAAK,SAAS;EAChC,MAAM,aAAa,cAAc,KAAK;EACtC,MAAM,EAAE,iBAAS,QAAQ,OAAO,CAAC,EAC/B,MAAM,YACP,CAAC;AAEF,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQA,OAAK,EAAE;AAG/C,OAAI,OAAO,UAAU,cAAc,QAAQ,SACzC;AAGF,UAAK,OAA4B;;AAGnC,MAAI,QAA4BA;AAEhC,SAAO;IACN,EAAE,CAA2D;;AAGlE,SAAgB,UAId,QAAuB,UAAwB;CAC/C,MAAM,YAAY,IAAI,KAAK,WAAW,MAAM;EAC1C,OAAO;EACP,MAAM;EACP,CAAC;CACF,MAAM,gBAAgB,OAAO,KAAK,OAAO;CAEzC,MAAM,yBAAyB;AAC7B,SAAO,0DAA0D,UAAU,OACzE,cACD,CAAC;;AAGJ,KAAI,aAAa,OAAO;EACtB,IAAI,MAAM,EAAE;AAEZ,OAAK,MAAM,OAAO,cAChB,OAAM;GACJ,GAAG;IACF,MAAM,QAAQ,OAAO,CAAC,EACrB,MAAM,cAAc,IAAI,EACzB,CAAC;GACH;AAGH,SAAO,gBACL,QACA,cACD;;AAGH,KAAI,MAAM,QAAQ,SAAS,EAAE;AAC3B,YACE,SAAS,OAAO,SAAS,cAAc,SAAS,KAAK,CAAC,QAChD;GACJ,MAAM,kBAAkB,oBACtB,UACA,cAAc,KAAK,QAAQ,cAAc,IAAI,CAAC,EAC9C,UACD;AAED,OAAI,gBAAgB,WAAW,QAC7B,QAAO,GAAG,kBAAkB,CAAC,kBAAkB,YAC7C,gBAAgB,OACjB;AAGH,UAAO,kBAAkB;IAE5B;AAED,SAAO,gBACL,QACA,SACD;;AAGH,KAAI,OAAO,aAAa,UAAU;EAChC,MAAM,OAAO,OAAO,KAAK,SAAS;AAElC,YACE,KAAK,OAAO,QAAQ,cAAc,SAAS,IAAI,CAAC,QAC1C;GACJ,MAAM,kBAAkB,oBACtB,MACA,eACA,UACD;AAED,OAAI,gBAAgB,WAAW,QAC7B,QAAO,GAAG,kBAAkB,CAAC,kBAAkB,YAC7C,gBAAgB,OACjB;AAGH,UAAO,kBAAkB;IAE5B;AAED,SAAO,gBACL,QACA,KACD;;AAGH,OAAM,IAAI,MAAM,GAAG,kBAAkB,CAAC,cAAc;;AAGtD,SAAgB,iBACd,SACA,OACA;AACA,KAAI,OAAO,YAAY,WACrB,QAAQ,QAAmC,MAAM;AAGnD,QAAO"}
|
package/dist/storage.cjs
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const require_invariant = require('./utils/invariant.cjs');
|
|
2
|
+
const require_logger = require('./utils/logger.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/storage.ts
|
|
5
|
+
const WINDOW_UNDEFINED_MESSAGE = "\"window\" in undefined. No storage is available";
|
|
6
|
+
const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
7
|
+
var MultiStepFormStorage = class {
|
|
8
|
+
key;
|
|
9
|
+
store;
|
|
10
|
+
data;
|
|
11
|
+
log;
|
|
12
|
+
shouldRunActions;
|
|
13
|
+
throwWhenUndefined;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
const { key, data, store, throwWhenUndefined = false } = config;
|
|
16
|
+
this.log = new require_logger.MultiStepFormLogger({ prefix: DEFAULT_STORAGE_KEY });
|
|
17
|
+
this.key = key;
|
|
18
|
+
this.data = data;
|
|
19
|
+
this.throwWhenUndefined = throwWhenUndefined;
|
|
20
|
+
if (store) {
|
|
21
|
+
this.store = store;
|
|
22
|
+
this.shouldRunActions = true;
|
|
23
|
+
if (typeof window === "undefined") {
|
|
24
|
+
this.shouldRunActions = false;
|
|
25
|
+
this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
26
|
+
}
|
|
27
|
+
} else if (typeof window !== "undefined") {
|
|
28
|
+
this.store = window.localStorage;
|
|
29
|
+
this.shouldRunActions = true;
|
|
30
|
+
} else {
|
|
31
|
+
this.shouldRunActions = false;
|
|
32
|
+
this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throwOnEmptyStore() {
|
|
36
|
+
if (!this.throwWhenUndefined) return;
|
|
37
|
+
require_invariant.invariant(this.store, () => {
|
|
38
|
+
if (this.shouldRunActions) return WINDOW_UNDEFINED_MESSAGE;
|
|
39
|
+
return "No storage available";
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
resolveValue(value) {
|
|
43
|
+
if (typeof value === "object") return value;
|
|
44
|
+
if (typeof value === "function") return value(this.data);
|
|
45
|
+
this.log.error(`The updater value must be a function or object. Was a ${typeof value}`, { throw: true });
|
|
46
|
+
}
|
|
47
|
+
hasKey() {
|
|
48
|
+
return this.store.getItem(this.key) !== null;
|
|
49
|
+
}
|
|
50
|
+
get() {
|
|
51
|
+
this.throwOnEmptyStore();
|
|
52
|
+
if (!this.shouldRunActions) return;
|
|
53
|
+
const item = this.store.getItem(this.key);
|
|
54
|
+
if (item) return JSON.parse(item);
|
|
55
|
+
}
|
|
56
|
+
remove() {
|
|
57
|
+
this.throwOnEmptyStore();
|
|
58
|
+
if (!this.shouldRunActions) return;
|
|
59
|
+
this.store.removeItem(this.key);
|
|
60
|
+
}
|
|
61
|
+
add(value) {
|
|
62
|
+
this.throwOnEmptyStore();
|
|
63
|
+
if (!this.shouldRunActions) return;
|
|
64
|
+
const resolvedValue = JSON.stringify(this.resolveValue(value));
|
|
65
|
+
this.store.setItem(this.key, resolvedValue);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
exports.DEFAULT_STORAGE_KEY = DEFAULT_STORAGE_KEY;
|
|
71
|
+
exports.MultiStepFormStorage = MultiStepFormStorage;
|
|
72
|
+
//# sourceMappingURL=storage.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.cjs","names":["MultiStepFormLogger"],"sources":["../src/storage.ts"],"sourcesContent":["import type { Updater } from '@/steps/types';\nimport { invariant } from '@/utils/invariant';\nimport { MultiStepFormLogger } from '@/utils/logger';\n\nexport type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;\nexport type StorageConfig<TData, TKey extends string> = {\n key: TKey;\n data: TData;\n store?: Storage;\n /**\n * An extra option to throw an error when {@linkcode window} is `undefined`\n * @default false\n */\n throwWhenUndefined?: boolean;\n};\n\nconst WINDOW_UNDEFINED_MESSAGE =\n '\"window\" in undefined. No storage is available';\nexport const DEFAULT_STORAGE_KEY = 'MultiStepForm';\n\nexport class MultiStepFormStorage<\n data,\n key extends string = DefaultStorageKey\n> {\n readonly key: key;\n readonly store!: Storage;\n readonly data: data;\n private readonly log: MultiStepFormLogger;\n private readonly shouldRunActions: boolean;\n private readonly throwWhenUndefined: boolean;\n\n constructor(config: StorageConfig<data, key>) {\n const { key, data, store, throwWhenUndefined = false } = config;\n\n this.log = new MultiStepFormLogger({\n prefix: DEFAULT_STORAGE_KEY,\n });\n this.key = key;\n this.data = data;\n this.throwWhenUndefined = throwWhenUndefined;\n\n if (store) {\n this.store = store;\n this.shouldRunActions = true;\n\n if (typeof window === 'undefined') {\n this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n } else if (typeof window !== 'undefined') {\n this.store = window.localStorage;\n this.shouldRunActions = true;\n } else {\n this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n }\n\n private throwOnEmptyStore() {\n if (!this.throwWhenUndefined) {\n return;\n }\n\n invariant(this.store, () => {\n if (this.shouldRunActions) {\n return WINDOW_UNDEFINED_MESSAGE;\n }\n\n return 'No storage available';\n });\n }\n\n private resolveValue(value: Updater<data>) {\n if (typeof value === 'object') {\n return value;\n }\n\n if (typeof value === 'function') {\n return (value as (input: data) => data)(this.data);\n }\n\n this.log.error(\n `The updater value must be a function or object. Was a ${typeof value}`,\n { throw: true }\n );\n }\n\n hasKey() {\n return this.store.getItem(this.key) !== null;\n }\n\n get() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const item = this.store.getItem(this.key);\n\n if (item) {\n const parsed = JSON.parse(item);\n\n return parsed as data;\n }\n }\n\n remove() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n this.store.removeItem(this.key);\n }\n\n add(value: Updater<data>) {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const resolvedValue = JSON.stringify(this.resolveValue(value));\n\n this.store.setItem(this.key, resolvedValue);\n }\n}\n"],"mappings":";;;;AAgBA,MAAM,2BACJ;AACF,MAAa,sBAAsB;AAEnC,IAAa,uBAAb,MAGE;CACA,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,QAAkC;EAC5C,MAAM,EAAE,KAAK,MAAM,OAAO,qBAAqB,UAAU;AAEzD,OAAK,MAAM,IAAIA,mCAAoB,EACjC,QAAQ,qBACT,CAAC;AACF,OAAK,MAAM;AACX,OAAK,OAAO;AACZ,OAAK,qBAAqB;AAE1B,MAAI,OAAO;AACT,QAAK,QAAQ;AACb,QAAK,mBAAmB;AAExB,OAAI,OAAO,WAAW,aAAa;AACjC,SAAK,mBAAmB;AACxB,SAAK,IAAI,KAAK,yBAAyB;;aAEhC,OAAO,WAAW,aAAa;AACxC,QAAK,QAAQ,OAAO;AACpB,QAAK,mBAAmB;SACnB;AACL,QAAK,mBAAmB;AACxB,QAAK,IAAI,KAAK,yBAAyB;;;CAI3C,AAAQ,oBAAoB;AAC1B,MAAI,CAAC,KAAK,mBACR;AAGF,8BAAU,KAAK,aAAa;AAC1B,OAAI,KAAK,iBACP,QAAO;AAGT,UAAO;IACP;;CAGJ,AAAQ,aAAa,OAAsB;AACzC,MAAI,OAAO,UAAU,SACnB,QAAO;AAGT,MAAI,OAAO,UAAU,WACnB,QAAQ,MAAgC,KAAK,KAAK;AAGpD,OAAK,IAAI,MACP,yDAAyD,OAAO,SAChE,EAAE,OAAO,MAAM,CAChB;;CAGH,SAAS;AACP,SAAO,KAAK,MAAM,QAAQ,KAAK,IAAI,KAAK;;CAG1C,MAAM;AACJ,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,OAAO,KAAK,MAAM,QAAQ,KAAK,IAAI;AAEzC,MAAI,KAGF,QAFe,KAAK,MAAM,KAAK;;CAMnC,SAAS;AACP,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;AAGF,OAAK,MAAM,WAAW,KAAK,IAAI;;CAGjC,IAAI,OAAsB;AACxB,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,gBAAgB,KAAK,UAAU,KAAK,aAAa,MAAM,CAAC;AAE9D,OAAK,MAAM,QAAQ,KAAK,KAAK,cAAc"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Updater } from "./steps/types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/storage.d.ts
|
|
4
|
+
type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;
|
|
5
|
+
type StorageConfig<TData, TKey extends string> = {
|
|
6
|
+
key: TKey;
|
|
7
|
+
data: TData;
|
|
8
|
+
store?: Storage;
|
|
9
|
+
/**
|
|
10
|
+
* An extra option to throw an error when {@linkcode window} is `undefined`
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
throwWhenUndefined?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
16
|
+
declare class MultiStepFormStorage<data, key extends string = DefaultStorageKey> {
|
|
17
|
+
readonly key: key;
|
|
18
|
+
readonly store: Storage;
|
|
19
|
+
readonly data: data;
|
|
20
|
+
private readonly log;
|
|
21
|
+
private readonly shouldRunActions;
|
|
22
|
+
private readonly throwWhenUndefined;
|
|
23
|
+
constructor(config: StorageConfig<data, key>);
|
|
24
|
+
private throwOnEmptyStore;
|
|
25
|
+
private resolveValue;
|
|
26
|
+
hasKey(): boolean;
|
|
27
|
+
get(): data | undefined;
|
|
28
|
+
remove(): void;
|
|
29
|
+
add(value: Updater<data>): void;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { DEFAULT_STORAGE_KEY, DefaultStorageKey, MultiStepFormStorage, StorageConfig };
|
|
33
|
+
//# sourceMappingURL=storage.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.cts","names":[],"sources":["../src/storage.ts"],"sourcesContent":[],"mappings":";;;KAIY,iBAAA,UAA2B;KAC3B;EADA,GAAA,EAEL,IAFK;EACA,IAAA,EAEJ,KAFI;EACL,KAAA,CAAA,EAEG,OAFH;EACC;;;AAWR;EAEa,kBAAA,CAAA,EAAA,OAAoB;CAEV;AAEP,cANH,mBAAA,GAMG,eAAA;AACG,cALN,oBAKM,CAAA,IAAA,EAAA,YAAA,MAAA,GAHI,iBAGJ,CAAA,CAAA;EACF,SAAA,GAAA,EAFD,GAEC;EAKmB,SAAA,KAAA,EANjB,OAMiB;EAAM,SAAA,IAAA,EALzB,IAKyB;EAApB,iBAAA,GAAA;EA4DjB,iBAAA,gBAAA;EA0BgB,iBAAA,kBAAA;EAAR,WAAA,CAAA,MAAA,EAtFS,aAsFT,CAtFuB,IAsFvB,EAtF6B,GAsF7B,CAAA;EAAO,QAAA,iBAAA;;;SA1Bf;;aA0BQ,QAAQ"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Updater } from "./steps/types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/storage.d.ts
|
|
4
|
+
type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;
|
|
5
|
+
type StorageConfig<TData, TKey extends string> = {
|
|
6
|
+
key: TKey;
|
|
7
|
+
data: TData;
|
|
8
|
+
store?: Storage;
|
|
9
|
+
/**
|
|
10
|
+
* An extra option to throw an error when {@linkcode window} is `undefined`
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
throwWhenUndefined?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
16
|
+
declare class MultiStepFormStorage<data, key extends string = DefaultStorageKey> {
|
|
17
|
+
readonly key: key;
|
|
18
|
+
readonly store: Storage;
|
|
19
|
+
readonly data: data;
|
|
20
|
+
private readonly log;
|
|
21
|
+
private readonly shouldRunActions;
|
|
22
|
+
private readonly throwWhenUndefined;
|
|
23
|
+
constructor(config: StorageConfig<data, key>);
|
|
24
|
+
private throwOnEmptyStore;
|
|
25
|
+
private resolveValue;
|
|
26
|
+
hasKey(): boolean;
|
|
27
|
+
get(): data | undefined;
|
|
28
|
+
remove(): void;
|
|
29
|
+
add(value: Updater<data>): void;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { DEFAULT_STORAGE_KEY, DefaultStorageKey, MultiStepFormStorage, StorageConfig };
|
|
33
|
+
//# sourceMappingURL=storage.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.mts","names":[],"sources":["../src/storage.ts"],"sourcesContent":[],"mappings":";;;KAIY,iBAAA,UAA2B;KAC3B;EADA,GAAA,EAEL,IAFK;EACA,IAAA,EAEJ,KAFI;EACL,KAAA,CAAA,EAEG,OAFH;EACC;;;AAWR;EAEa,kBAAA,CAAA,EAAA,OAAoB;CAEV;AAEP,cANH,mBAAA,GAMG,eAAA;AACG,cALN,oBAKM,CAAA,IAAA,EAAA,YAAA,MAAA,GAHI,iBAGJ,CAAA,CAAA;EACF,SAAA,GAAA,EAFD,GAEC;EAKmB,SAAA,KAAA,EANjB,OAMiB;EAAM,SAAA,IAAA,EALzB,IAKyB;EAApB,iBAAA,GAAA;EA4DjB,iBAAA,gBAAA;EA0BgB,iBAAA,kBAAA;EAAR,WAAA,CAAA,MAAA,EAtFS,aAsFT,CAtFuB,IAsFvB,EAtF6B,GAsF7B,CAAA;EAAO,QAAA,iBAAA;;;SA1Bf;;aA0BQ,QAAQ"}
|
package/dist/storage.mjs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { invariant } from "./utils/invariant.mjs";
|
|
2
|
+
import { MultiStepFormLogger } from "./utils/logger.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/storage.ts
|
|
5
|
+
const WINDOW_UNDEFINED_MESSAGE = "\"window\" in undefined. No storage is available";
|
|
6
|
+
const DEFAULT_STORAGE_KEY = "MultiStepForm";
|
|
7
|
+
var MultiStepFormStorage = class {
|
|
8
|
+
key;
|
|
9
|
+
store;
|
|
10
|
+
data;
|
|
11
|
+
log;
|
|
12
|
+
shouldRunActions;
|
|
13
|
+
throwWhenUndefined;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
const { key, data, store, throwWhenUndefined = false } = config;
|
|
16
|
+
this.log = new MultiStepFormLogger({ prefix: DEFAULT_STORAGE_KEY });
|
|
17
|
+
this.key = key;
|
|
18
|
+
this.data = data;
|
|
19
|
+
this.throwWhenUndefined = throwWhenUndefined;
|
|
20
|
+
if (store) {
|
|
21
|
+
this.store = store;
|
|
22
|
+
this.shouldRunActions = true;
|
|
23
|
+
if (typeof window === "undefined") {
|
|
24
|
+
this.shouldRunActions = false;
|
|
25
|
+
this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
26
|
+
}
|
|
27
|
+
} else if (typeof window !== "undefined") {
|
|
28
|
+
this.store = window.localStorage;
|
|
29
|
+
this.shouldRunActions = true;
|
|
30
|
+
} else {
|
|
31
|
+
this.shouldRunActions = false;
|
|
32
|
+
this.log.warn(WINDOW_UNDEFINED_MESSAGE);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throwOnEmptyStore() {
|
|
36
|
+
if (!this.throwWhenUndefined) return;
|
|
37
|
+
invariant(this.store, () => {
|
|
38
|
+
if (this.shouldRunActions) return WINDOW_UNDEFINED_MESSAGE;
|
|
39
|
+
return "No storage available";
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
resolveValue(value) {
|
|
43
|
+
if (typeof value === "object") return value;
|
|
44
|
+
if (typeof value === "function") return value(this.data);
|
|
45
|
+
this.log.error(`The updater value must be a function or object. Was a ${typeof value}`, { throw: true });
|
|
46
|
+
}
|
|
47
|
+
hasKey() {
|
|
48
|
+
return this.store.getItem(this.key) !== null;
|
|
49
|
+
}
|
|
50
|
+
get() {
|
|
51
|
+
this.throwOnEmptyStore();
|
|
52
|
+
if (!this.shouldRunActions) return;
|
|
53
|
+
const item = this.store.getItem(this.key);
|
|
54
|
+
if (item) return JSON.parse(item);
|
|
55
|
+
}
|
|
56
|
+
remove() {
|
|
57
|
+
this.throwOnEmptyStore();
|
|
58
|
+
if (!this.shouldRunActions) return;
|
|
59
|
+
this.store.removeItem(this.key);
|
|
60
|
+
}
|
|
61
|
+
add(value) {
|
|
62
|
+
this.throwOnEmptyStore();
|
|
63
|
+
if (!this.shouldRunActions) return;
|
|
64
|
+
const resolvedValue = JSON.stringify(this.resolveValue(value));
|
|
65
|
+
this.store.setItem(this.key, resolvedValue);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
export { DEFAULT_STORAGE_KEY, MultiStepFormStorage };
|
|
71
|
+
//# sourceMappingURL=storage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.mjs","names":[],"sources":["../src/storage.ts"],"sourcesContent":["import type { Updater } from '@/steps/types';\nimport { invariant } from '@/utils/invariant';\nimport { MultiStepFormLogger } from '@/utils/logger';\n\nexport type DefaultStorageKey = typeof DEFAULT_STORAGE_KEY;\nexport type StorageConfig<TData, TKey extends string> = {\n key: TKey;\n data: TData;\n store?: Storage;\n /**\n * An extra option to throw an error when {@linkcode window} is `undefined`\n * @default false\n */\n throwWhenUndefined?: boolean;\n};\n\nconst WINDOW_UNDEFINED_MESSAGE =\n '\"window\" in undefined. No storage is available';\nexport const DEFAULT_STORAGE_KEY = 'MultiStepForm';\n\nexport class MultiStepFormStorage<\n data,\n key extends string = DefaultStorageKey\n> {\n readonly key: key;\n readonly store!: Storage;\n readonly data: data;\n private readonly log: MultiStepFormLogger;\n private readonly shouldRunActions: boolean;\n private readonly throwWhenUndefined: boolean;\n\n constructor(config: StorageConfig<data, key>) {\n const { key, data, store, throwWhenUndefined = false } = config;\n\n this.log = new MultiStepFormLogger({\n prefix: DEFAULT_STORAGE_KEY,\n });\n this.key = key;\n this.data = data;\n this.throwWhenUndefined = throwWhenUndefined;\n\n if (store) {\n this.store = store;\n this.shouldRunActions = true;\n\n if (typeof window === 'undefined') {\n this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n } else if (typeof window !== 'undefined') {\n this.store = window.localStorage;\n this.shouldRunActions = true;\n } else {\n this.shouldRunActions = false;\n this.log.warn(WINDOW_UNDEFINED_MESSAGE);\n }\n }\n\n private throwOnEmptyStore() {\n if (!this.throwWhenUndefined) {\n return;\n }\n\n invariant(this.store, () => {\n if (this.shouldRunActions) {\n return WINDOW_UNDEFINED_MESSAGE;\n }\n\n return 'No storage available';\n });\n }\n\n private resolveValue(value: Updater<data>) {\n if (typeof value === 'object') {\n return value;\n }\n\n if (typeof value === 'function') {\n return (value as (input: data) => data)(this.data);\n }\n\n this.log.error(\n `The updater value must be a function or object. Was a ${typeof value}`,\n { throw: true }\n );\n }\n\n hasKey() {\n return this.store.getItem(this.key) !== null;\n }\n\n get() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const item = this.store.getItem(this.key);\n\n if (item) {\n const parsed = JSON.parse(item);\n\n return parsed as data;\n }\n }\n\n remove() {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n this.store.removeItem(this.key);\n }\n\n add(value: Updater<data>) {\n this.throwOnEmptyStore();\n\n if (!this.shouldRunActions) {\n return;\n }\n\n const resolvedValue = JSON.stringify(this.resolveValue(value));\n\n this.store.setItem(this.key, resolvedValue);\n }\n}\n"],"mappings":";;;;AAgBA,MAAM,2BACJ;AACF,MAAa,sBAAsB;AAEnC,IAAa,uBAAb,MAGE;CACA,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,QAAkC;EAC5C,MAAM,EAAE,KAAK,MAAM,OAAO,qBAAqB,UAAU;AAEzD,OAAK,MAAM,IAAI,oBAAoB,EACjC,QAAQ,qBACT,CAAC;AACF,OAAK,MAAM;AACX,OAAK,OAAO;AACZ,OAAK,qBAAqB;AAE1B,MAAI,OAAO;AACT,QAAK,QAAQ;AACb,QAAK,mBAAmB;AAExB,OAAI,OAAO,WAAW,aAAa;AACjC,SAAK,mBAAmB;AACxB,SAAK,IAAI,KAAK,yBAAyB;;aAEhC,OAAO,WAAW,aAAa;AACxC,QAAK,QAAQ,OAAO;AACpB,QAAK,mBAAmB;SACnB;AACL,QAAK,mBAAmB;AACxB,QAAK,IAAI,KAAK,yBAAyB;;;CAI3C,AAAQ,oBAAoB;AAC1B,MAAI,CAAC,KAAK,mBACR;AAGF,YAAU,KAAK,aAAa;AAC1B,OAAI,KAAK,iBACP,QAAO;AAGT,UAAO;IACP;;CAGJ,AAAQ,aAAa,OAAsB;AACzC,MAAI,OAAO,UAAU,SACnB,QAAO;AAGT,MAAI,OAAO,UAAU,WACnB,QAAQ,MAAgC,KAAK,KAAK;AAGpD,OAAK,IAAI,MACP,yDAAyD,OAAO,SAChE,EAAE,OAAO,MAAM,CAChB;;CAGH,SAAS;AACP,SAAO,KAAK,MAAM,QAAQ,KAAK,IAAI,KAAK;;CAG1C,MAAM;AACJ,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,OAAO,KAAK,MAAM,QAAQ,KAAK,IAAI;AAEzC,MAAI,KAGF,QAFe,KAAK,MAAM,KAAK;;CAMnC,SAAS;AACP,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;AAGF,OAAK,MAAM,WAAW,KAAK,IAAI;;CAGjC,IAAI,OAAsB;AACxB,OAAK,mBAAmB;AAExB,MAAI,CAAC,KAAK,iBACR;EAGF,MAAM,gBAAgB,KAAK,UAAU,KAAK,aAAa,MAAM,CAAC;AAE9D,OAAK,MAAM,QAAQ,KAAK,KAAK,cAAc"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/subscribable.ts
|
|
3
|
+
var Subscribable = class {
|
|
4
|
+
listeners = /* @__PURE__ */ new Set();
|
|
5
|
+
constructor() {
|
|
6
|
+
this.subscribe = this.subscribe.bind(this);
|
|
7
|
+
}
|
|
8
|
+
subscribe(listener) {
|
|
9
|
+
this.listeners.add(listener);
|
|
10
|
+
this.onSubscribe();
|
|
11
|
+
return () => {
|
|
12
|
+
this.listeners.delete(listener);
|
|
13
|
+
this.onUnsubscribe();
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
hasListeners() {
|
|
17
|
+
return this.listeners.size > 0;
|
|
18
|
+
}
|
|
19
|
+
onSubscribe() {}
|
|
20
|
+
onUnsubscribe() {}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
exports.Subscribable = Subscribable;
|
|
25
|
+
//# sourceMappingURL=subscribable.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.cjs","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":["export abstract class Subscribable<TListener extends Function> {\n protected listeners = new Set<TListener>();\n\n constructor() {\n this.subscribe = this.subscribe.bind(this);\n }\n\n subscribe(listener: TListener) {\n this.listeners.add(listener);\n\n this.onSubscribe();\n\n return () => {\n this.listeners.delete(listener);\n this.onUnsubscribe();\n };\n }\n\n hasListeners() {\n return this.listeners.size > 0;\n }\n\n protected onSubscribe() {}\n protected onUnsubscribe() {}\n protected abstract notify(): void;\n abstract getSnapshot(): this;\n}\n"],"mappings":";;AAAA,IAAsB,eAAtB,MAA+D;CAC7D,AAAU,4BAAY,IAAI,KAAgB;CAE1C,cAAc;AACZ,OAAK,YAAY,KAAK,UAAU,KAAK,KAAK;;CAG5C,UAAU,UAAqB;AAC7B,OAAK,UAAU,IAAI,SAAS;AAE5B,OAAK,aAAa;AAElB,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;AAC/B,QAAK,eAAe;;;CAIxB,eAAe;AACb,SAAO,KAAK,UAAU,OAAO;;CAG/B,AAAU,cAAc;CACxB,AAAU,gBAAgB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/subscribable.d.ts
|
|
2
|
+
declare abstract class Subscribable<TListener extends Function> {
|
|
3
|
+
protected listeners: Set<TListener>;
|
|
4
|
+
constructor();
|
|
5
|
+
subscribe(listener: TListener): () => void;
|
|
6
|
+
hasListeners(): boolean;
|
|
7
|
+
protected onSubscribe(): void;
|
|
8
|
+
protected onUnsubscribe(): void;
|
|
9
|
+
protected abstract notify(): void;
|
|
10
|
+
abstract getSnapshot(): this;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Subscribable };
|
|
14
|
+
//# sourceMappingURL=subscribable.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.d.cts","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":[],"mappings":";uBAAsB,+BAA+B;EAA/B,UAAA,SAAY,EACb,GADa,CACb,SADa,CAAA;EAAmB,WAAA,CAAA;EAChC,SAAA,CAAA,QAAA,EAMC,SAND,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,YAAA,CAAA,CAAA,EAAA,OAAA;EAMC,UAAA,WAAA,CAAA,CAAA,EAAA,IAAA;EAAS,UAAA,aAAA,CAAA,CAAA,EAAA,IAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/subscribable.d.ts
|
|
2
|
+
declare abstract class Subscribable<TListener extends Function> {
|
|
3
|
+
protected listeners: Set<TListener>;
|
|
4
|
+
constructor();
|
|
5
|
+
subscribe(listener: TListener): () => void;
|
|
6
|
+
hasListeners(): boolean;
|
|
7
|
+
protected onSubscribe(): void;
|
|
8
|
+
protected onUnsubscribe(): void;
|
|
9
|
+
protected abstract notify(): void;
|
|
10
|
+
abstract getSnapshot(): this;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Subscribable };
|
|
14
|
+
//# sourceMappingURL=subscribable.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.d.mts","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":[],"mappings":";uBAAsB,+BAA+B;EAA/B,UAAA,SAAY,EACb,GADa,CACb,SADa,CAAA;EAAmB,WAAA,CAAA;EAChC,SAAA,CAAA,QAAA,EAMC,SAND,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,YAAA,CAAA,CAAA,EAAA,OAAA;EAMC,UAAA,WAAA,CAAA,CAAA,EAAA,IAAA;EAAS,UAAA,aAAA,CAAA,CAAA,EAAA,IAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/subscribable.ts
|
|
2
|
+
var Subscribable = class {
|
|
3
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4
|
+
constructor() {
|
|
5
|
+
this.subscribe = this.subscribe.bind(this);
|
|
6
|
+
}
|
|
7
|
+
subscribe(listener) {
|
|
8
|
+
this.listeners.add(listener);
|
|
9
|
+
this.onSubscribe();
|
|
10
|
+
return () => {
|
|
11
|
+
this.listeners.delete(listener);
|
|
12
|
+
this.onUnsubscribe();
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
hasListeners() {
|
|
16
|
+
return this.listeners.size > 0;
|
|
17
|
+
}
|
|
18
|
+
onSubscribe() {}
|
|
19
|
+
onUnsubscribe() {}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Subscribable };
|
|
24
|
+
//# sourceMappingURL=subscribable.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribable.mjs","names":[],"sources":["../src/subscribable.ts"],"sourcesContent":["export abstract class Subscribable<TListener extends Function> {\n protected listeners = new Set<TListener>();\n\n constructor() {\n this.subscribe = this.subscribe.bind(this);\n }\n\n subscribe(listener: TListener) {\n this.listeners.add(listener);\n\n this.onSubscribe();\n\n return () => {\n this.listeners.delete(listener);\n this.onUnsubscribe();\n };\n }\n\n hasListeners() {\n return this.listeners.size > 0;\n }\n\n protected onSubscribe() {}\n protected onUnsubscribe() {}\n protected abstract notify(): void;\n abstract getSnapshot(): this;\n}\n"],"mappings":";AAAA,IAAsB,eAAtB,MAA+D;CAC7D,AAAU,4BAAY,IAAI,KAAgB;CAE1C,cAAc;AACZ,OAAK,YAAY,KAAK,UAAU,KAAK,KAAK;;CAG5C,UAAU,UAAqB;AAC7B,OAAK,UAAU,IAAI,SAAS;AAE5B,OAAK,aAAa;AAElB,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;AAC/B,QAAK,eAAe;;;CAIxB,eAAe;AACb,SAAO,KAAK,UAAU,OAAO;;CAG/B,AAAU,cAAc;CACxB,AAAU,gBAAgB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/casing.ts
|
|
3
|
+
const CASING_TYPES = [
|
|
4
|
+
"sentence",
|
|
5
|
+
"title",
|
|
6
|
+
"camel",
|
|
7
|
+
"lower",
|
|
8
|
+
"upper",
|
|
9
|
+
"pascal",
|
|
10
|
+
"snake",
|
|
11
|
+
"screaming-snake",
|
|
12
|
+
"flat",
|
|
13
|
+
"kebab"
|
|
14
|
+
];
|
|
15
|
+
const DEFAULT_CASING = "title";
|
|
16
|
+
function changeCasing(input, type) {
|
|
17
|
+
const words = input.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").trim().split(/\s+/).map((w) => w.toLowerCase());
|
|
18
|
+
switch (type) {
|
|
19
|
+
case "sentence": return words[0].charAt(0).toUpperCase() + words[0].slice(1) + (words.length > 1 ? " " + words.slice(1).join(" ") : "");
|
|
20
|
+
case "title": return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
21
|
+
case "camel": return words[0] + words.slice(1).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
22
|
+
case "pascal": return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
23
|
+
case "lower": return words.join(" ");
|
|
24
|
+
case "upper": return words.join(" ").toUpperCase();
|
|
25
|
+
case "snake": return words.join("_");
|
|
26
|
+
case "screaming-snake": return words.join("_").toUpperCase();
|
|
27
|
+
case "kebab": return words.join("-");
|
|
28
|
+
case "flat": return words.join("");
|
|
29
|
+
default: return input;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function quote(str, quoteChar = "\"") {
|
|
33
|
+
const startsWithQuote = str.startsWith(quoteChar);
|
|
34
|
+
const endsWithQuote = str.endsWith(quoteChar);
|
|
35
|
+
if (startsWithQuote && endsWithQuote) return str;
|
|
36
|
+
return `${quoteChar}${str.replace(/^['"]|['"]$/g, "")}${quoteChar}`;
|
|
37
|
+
}
|
|
38
|
+
function isCasingValid(value) {
|
|
39
|
+
if (typeof value !== "string") return false;
|
|
40
|
+
return CASING_TYPES.includes(value);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validates {@linkcode input} is a valid {@linkcode CasingType}.
|
|
44
|
+
*
|
|
45
|
+
* If there is no explicit {@linkcode fallback} value provided,
|
|
46
|
+
* it will default to {@linkcode DEFAULT_CASING}.
|
|
47
|
+
* @param input The input to check.
|
|
48
|
+
* @param fallback An optional fallback value if {@linkcode input} is `undefined`.
|
|
49
|
+
* @returns The {@linkcode input} or {@linkcode fallback} if {@linkcode input} is `undefined` or an {@linkcode isCasingValid invalid} {@linkcode CasingType}.
|
|
50
|
+
*/
|
|
51
|
+
function setCasingType(input, fallback = DEFAULT_CASING) {
|
|
52
|
+
if (isCasingValid(input)) return input;
|
|
53
|
+
return fallback;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
exports.CASING_TYPES = CASING_TYPES;
|
|
58
|
+
exports.DEFAULT_CASING = DEFAULT_CASING;
|
|
59
|
+
exports.changeCasing = changeCasing;
|
|
60
|
+
exports.isCasingValid = isCasingValid;
|
|
61
|
+
exports.quote = quote;
|
|
62
|
+
exports.setCasingType = setCasingType;
|
|
63
|
+
//# sourceMappingURL=casing.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casing.cjs","names":["DEFAULT_CASING: SetDefaultString<CasingType, 'title'>"],"sources":["../../src/utils/casing.ts"],"sourcesContent":["import type { Expand, SetDefaultString } from './types';\n\nexport type CasingType = (typeof CASING_TYPES)[number];\nexport type ToLower<S extends string> = S extends `${infer F}${infer R}`\n ? `${Lowercase<F>}${ToLower<R>}`\n : S;\n\nexport type CapitalizeWord<S extends string> = S extends `${infer F}${infer R}`\n ? `${Uppercase<F>}${ToLower<R>}`\n : S;\n// Pascal => Capitalize each \"word\" chunk\ntype Pascalize<S extends string> = Capitalize<S>; // naive\n\n// SnakeCase: turn spaces/hyphens into underscores, lowercase\ntype SnakeCase<S extends string> = Lowercase<\n S extends `${infer A} ${infer B}`\n ? `${A}_${SnakeCase<B>}`\n : S extends `${infer A}-${infer B}`\n ? `${A}_${SnakeCase<B>}`\n : S\n>;\n\n// KebabCase: same as snake but with \"-\"\ntype KebabCase<S extends string> = Lowercase<\n S extends `${infer A} ${infer B}`\n ? `${A}-${KebabCase<B>}`\n : S extends `${infer A}_${infer B}`\n ? `${A}-${KebabCase<B>}`\n : S\n>;\n\n// Flat: just strip spaces/underscores/hyphens\ntype RemoveDelimiters<S extends string> = S extends `${infer A} ${infer B}`\n ? `${A}${RemoveDelimiters<B>}`\n : S extends `${infer A}_${infer B}`\n ? `${A}${RemoveDelimiters<B>}`\n : S extends `${infer A}-${infer B}`\n ? `${A}${RemoveDelimiters<B>}`\n : S;\n\n// TitleCase: Capitalize the whole thing\ntype TitleCase<S extends string> = Capitalize<Lowercase<S>>;\n\n// SentenceCase: First word capped, rest lower\ntype SentenceCase<S extends string> = Capitalize<Lowercase<S>>;\nexport type ChangeCasing<\n S extends string,\n T extends CasingType\n> = T extends 'lower'\n ? Lowercase<S>\n : T extends 'upper'\n ? Uppercase<S>\n : T extends 'camel'\n ? Uncapitalize<Pascalize<S>>\n : T extends 'pascal'\n ? Pascalize<S>\n : T extends 'snake'\n ? SnakeCase<S>\n : T extends 'screaming-snake'\n ? Uppercase<SnakeCase<S>>\n : T extends 'kebab'\n ? KebabCase<S>\n : T extends 'flat'\n ? RemoveDelimiters<Lowercase<S>>\n : T extends 'title'\n ? TitleCase<S>\n : T extends 'sentence'\n ? SentenceCase<S>\n : S;\nexport type ChangeObjectCasing<\n T extends object,\n TCasing extends CasingType\n> = Expand<{\n [K in keyof T as K extends string ? ChangeCasing<K, TCasing> : K]: T[K];\n}>;\n\nexport const CASING_TYPES = [\n 'sentence',\n 'title',\n 'camel',\n 'lower',\n 'upper',\n 'pascal',\n 'snake',\n 'screaming-snake',\n 'flat',\n 'kebab',\n] as const;\n\nexport type DefaultCasing = typeof DEFAULT_CASING;\nexport const DEFAULT_CASING: SetDefaultString<CasingType, 'title'> = 'title';\n\n/**\n * Changes the casing of a string according to the specified casing type.\n *\n * @param input - The string to transform.\n * @param type - The casing type to apply.\n * @returns The transformed string in the specified casing.\n */\n// TODO make return type safe\nexport function changeCasing<TValue extends string, TType extends CasingType>(\n input: TValue,\n type: TType\n): ChangeCasing<TValue, TType>;\nexport function changeCasing<TValue extends string, TType extends CasingType>(\n input: TValue,\n type: TType\n) {\n // Step 1: Normalize to words\n const words = input\n // Replace camelCase boundaries with space\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Replace separators with space\n .replace(/[-_]+/g, ' ')\n // Trim and split into words\n .trim()\n .split(/\\s+/)\n .map((w) => w.toLowerCase());\n\n // Step 2: Apply casing\n switch (type) {\n case 'sentence':\n return (\n words[0].charAt(0).toUpperCase() +\n words[0].slice(1) +\n (words.length > 1 ? ' ' + words.slice(1).join(' ') : '')\n );\n\n case 'title':\n return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');\n\n case 'camel':\n return (\n words[0] +\n words\n .slice(1)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join('')\n );\n\n case 'pascal':\n return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('');\n\n case 'lower':\n return words.join(' ');\n\n case 'upper':\n return words.join(' ').toUpperCase();\n\n case 'snake':\n return words.join('_');\n\n case 'screaming-snake':\n return words.join('_').toUpperCase();\n\n case 'kebab':\n return words.join('-');\n\n case 'flat':\n return words.join('');\n\n default:\n return input;\n }\n}\n\nexport function quote(str: string, quoteChar: '\"' | \"'\" = '\"') {\n const startsWithQuote = str.startsWith(quoteChar);\n const endsWithQuote = str.endsWith(quoteChar);\n\n if (startsWithQuote && endsWithQuote) {\n // Already wrapped correctly\n return str;\n }\n\n // If it starts or ends with a quote but not both → strip those first\n const trimmed = str.replace(/^['\"]|['\"]$/g, '');\n\n // Then add new quotes consistently\n return `${quoteChar}${trimmed}${quoteChar}`;\n}\n\nexport function isCasingValid(value: unknown): value is CasingType {\n if (typeof value !== 'string') {\n return false;\n }\n\n const isValid = CASING_TYPES.includes(value as CasingType);\n\n // invariant(isValid, () => {\n // const formatter = new Intl.ListFormat('en', {\n // style: 'long',\n // type: 'conjunction',\n // });\n\n // return `${value} is not a valid casing type. Valid types include ${formatter.format(\n // CASING_TYPES.map((word) => quote(word))\n // )}`;\n // });\n\n return isValid;\n}\n\n/**\n * Validates {@linkcode input} is a valid {@linkcode CasingType}.\n *\n * If there is no explicit {@linkcode fallback} value provided,\n * it will default to {@linkcode DEFAULT_CASING}.\n * @param input The input to check.\n * @param fallback An optional fallback value if {@linkcode input} is `undefined`.\n * @returns The {@linkcode input} or {@linkcode fallback} if {@linkcode input} is `undefined` or an {@linkcode isCasingValid invalid} {@linkcode CasingType}.\n */\nexport function setCasingType<TCasing extends CasingType>(\n input: TCasing | undefined,\n fallback: CasingType = DEFAULT_CASING\n) {\n if (isCasingValid(input)) {\n return input;\n }\n\n return fallback;\n}\n"],"mappings":";;AA4EA,MAAa,eAAe;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAGD,MAAaA,iBAAwD;AAcrE,SAAgB,aACd,OACA,MACA;CAEA,MAAM,QAAQ,MAEX,QAAQ,mBAAmB,QAAQ,CAEnC,QAAQ,UAAU,IAAI,CAEtB,MAAM,CACN,MAAM,MAAM,CACZ,KAAK,MAAM,EAAE,aAAa,CAAC;AAG9B,SAAQ,MAAR;EACE,KAAK,WACH,QACE,MAAM,GAAG,OAAO,EAAE,CAAC,aAAa,GAChC,MAAM,GAAG,MAAM,EAAE,IAChB,MAAM,SAAS,IAAI,MAAM,MAAM,MAAM,EAAE,CAAC,KAAK,IAAI,GAAG;EAGzD,KAAK,QACH,QAAO,MAAM,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI;EAE3E,KAAK,QACH,QACE,MAAM,KACN,MACG,MAAM,EAAE,CACR,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,CAClD,KAAK,GAAG;EAGf,KAAK,SACH,QAAO,MAAM,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG;EAE1E,KAAK,QACH,QAAO,MAAM,KAAK,IAAI;EAExB,KAAK,QACH,QAAO,MAAM,KAAK,IAAI,CAAC,aAAa;EAEtC,KAAK,QACH,QAAO,MAAM,KAAK,IAAI;EAExB,KAAK,kBACH,QAAO,MAAM,KAAK,IAAI,CAAC,aAAa;EAEtC,KAAK,QACH,QAAO,MAAM,KAAK,IAAI;EAExB,KAAK,OACH,QAAO,MAAM,KAAK,GAAG;EAEvB,QACE,QAAO;;;AAIb,SAAgB,MAAM,KAAa,YAAuB,MAAK;CAC7D,MAAM,kBAAkB,IAAI,WAAW,UAAU;CACjD,MAAM,gBAAgB,IAAI,SAAS,UAAU;AAE7C,KAAI,mBAAmB,cAErB,QAAO;AAOT,QAAO,GAAG,YAHM,IAAI,QAAQ,gBAAgB,GAAG,GAGf;;AAGlC,SAAgB,cAAc,OAAqC;AACjE,KAAI,OAAO,UAAU,SACnB,QAAO;AAgBT,QAbgB,aAAa,SAAS,MAAoB;;;;;;;;;;;AAyB5D,SAAgB,cACd,OACA,WAAuB,gBACvB;AACA,KAAI,cAAc,MAAM,CACtB,QAAO;AAGT,QAAO"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Expand, SetDefaultString } from "./types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/casing.d.ts
|
|
4
|
+
type CasingType = (typeof CASING_TYPES)[number];
|
|
5
|
+
type ToLower<S extends string> = S extends `${infer F}${infer R}` ? `${Lowercase<F>}${ToLower<R>}` : S;
|
|
6
|
+
type CapitalizeWord<S extends string> = S extends `${infer F}${infer R}` ? `${Uppercase<F>}${ToLower<R>}` : S;
|
|
7
|
+
type Pascalize<S extends string> = Capitalize<S>;
|
|
8
|
+
type SnakeCase<S extends string> = Lowercase<S extends `${infer A} ${infer B}` ? `${A}_${SnakeCase<B>}` : S extends `${infer A}-${infer B}` ? `${A}_${SnakeCase<B>}` : S>;
|
|
9
|
+
type KebabCase<S extends string> = Lowercase<S extends `${infer A} ${infer B}` ? `${A}-${KebabCase<B>}` : S extends `${infer A}_${infer B}` ? `${A}-${KebabCase<B>}` : S>;
|
|
10
|
+
type RemoveDelimiters<S extends string> = S extends `${infer A} ${infer B}` ? `${A}${RemoveDelimiters<B>}` : S extends `${infer A}_${infer B}` ? `${A}${RemoveDelimiters<B>}` : S extends `${infer A}-${infer B}` ? `${A}${RemoveDelimiters<B>}` : S;
|
|
11
|
+
type TitleCase<S extends string> = Capitalize<Lowercase<S>>;
|
|
12
|
+
type SentenceCase<S extends string> = Capitalize<Lowercase<S>>;
|
|
13
|
+
type ChangeCasing<S extends string, T extends CasingType> = T extends 'lower' ? Lowercase<S> : T extends 'upper' ? Uppercase<S> : T extends 'camel' ? Uncapitalize<Pascalize<S>> : T extends 'pascal' ? Pascalize<S> : T extends 'snake' ? SnakeCase<S> : T extends 'screaming-snake' ? Uppercase<SnakeCase<S>> : T extends 'kebab' ? KebabCase<S> : T extends 'flat' ? RemoveDelimiters<Lowercase<S>> : T extends 'title' ? TitleCase<S> : T extends 'sentence' ? SentenceCase<S> : S;
|
|
14
|
+
type ChangeObjectCasing<T extends object, TCasing extends CasingType> = Expand<{ [K in keyof T as K extends string ? ChangeCasing<K, TCasing> : K]: T[K] }>;
|
|
15
|
+
declare const CASING_TYPES: readonly ["sentence", "title", "camel", "lower", "upper", "pascal", "snake", "screaming-snake", "flat", "kebab"];
|
|
16
|
+
type DefaultCasing = typeof DEFAULT_CASING;
|
|
17
|
+
declare const DEFAULT_CASING: SetDefaultString<CasingType, 'title'>;
|
|
18
|
+
/**
|
|
19
|
+
* Changes the casing of a string according to the specified casing type.
|
|
20
|
+
*
|
|
21
|
+
* @param input - The string to transform.
|
|
22
|
+
* @param type - The casing type to apply.
|
|
23
|
+
* @returns The transformed string in the specified casing.
|
|
24
|
+
*/
|
|
25
|
+
declare function changeCasing<TValue extends string, TType extends CasingType>(input: TValue, type: TType): ChangeCasing<TValue, TType>;
|
|
26
|
+
declare function quote(str: string, quoteChar?: '"' | "'"): string;
|
|
27
|
+
declare function isCasingValid(value: unknown): value is CasingType;
|
|
28
|
+
/**
|
|
29
|
+
* Validates {@linkcode input} is a valid {@linkcode CasingType}.
|
|
30
|
+
*
|
|
31
|
+
* If there is no explicit {@linkcode fallback} value provided,
|
|
32
|
+
* it will default to {@linkcode DEFAULT_CASING}.
|
|
33
|
+
* @param input The input to check.
|
|
34
|
+
* @param fallback An optional fallback value if {@linkcode input} is `undefined`.
|
|
35
|
+
* @returns The {@linkcode input} or {@linkcode fallback} if {@linkcode input} is `undefined` or an {@linkcode isCasingValid invalid} {@linkcode CasingType}.
|
|
36
|
+
*/
|
|
37
|
+
declare function setCasingType<TCasing extends CasingType>(input: TCasing | undefined, fallback?: CasingType): "sentence" | "title" | "camel" | "lower" | "upper" | "pascal" | "snake" | "screaming-snake" | "flat" | "kebab";
|
|
38
|
+
//#endregion
|
|
39
|
+
export { CASING_TYPES, CapitalizeWord, CasingType, ChangeCasing, ChangeObjectCasing, DEFAULT_CASING, DefaultCasing, ToLower, changeCasing, isCasingValid, quote, setCasingType };
|
|
40
|
+
//# sourceMappingURL=casing.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casing.d.cts","names":[],"sources":["../../src/utils/casing.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Expand, SetDefaultString } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/casing.d.ts
|
|
4
|
+
type CasingType = (typeof CASING_TYPES)[number];
|
|
5
|
+
type ToLower<S extends string> = S extends `${infer F}${infer R}` ? `${Lowercase<F>}${ToLower<R>}` : S;
|
|
6
|
+
type CapitalizeWord<S extends string> = S extends `${infer F}${infer R}` ? `${Uppercase<F>}${ToLower<R>}` : S;
|
|
7
|
+
type Pascalize<S extends string> = Capitalize<S>;
|
|
8
|
+
type SnakeCase<S extends string> = Lowercase<S extends `${infer A} ${infer B}` ? `${A}_${SnakeCase<B>}` : S extends `${infer A}-${infer B}` ? `${A}_${SnakeCase<B>}` : S>;
|
|
9
|
+
type KebabCase<S extends string> = Lowercase<S extends `${infer A} ${infer B}` ? `${A}-${KebabCase<B>}` : S extends `${infer A}_${infer B}` ? `${A}-${KebabCase<B>}` : S>;
|
|
10
|
+
type RemoveDelimiters<S extends string> = S extends `${infer A} ${infer B}` ? `${A}${RemoveDelimiters<B>}` : S extends `${infer A}_${infer B}` ? `${A}${RemoveDelimiters<B>}` : S extends `${infer A}-${infer B}` ? `${A}${RemoveDelimiters<B>}` : S;
|
|
11
|
+
type TitleCase<S extends string> = Capitalize<Lowercase<S>>;
|
|
12
|
+
type SentenceCase<S extends string> = Capitalize<Lowercase<S>>;
|
|
13
|
+
type ChangeCasing<S extends string, T extends CasingType> = T extends 'lower' ? Lowercase<S> : T extends 'upper' ? Uppercase<S> : T extends 'camel' ? Uncapitalize<Pascalize<S>> : T extends 'pascal' ? Pascalize<S> : T extends 'snake' ? SnakeCase<S> : T extends 'screaming-snake' ? Uppercase<SnakeCase<S>> : T extends 'kebab' ? KebabCase<S> : T extends 'flat' ? RemoveDelimiters<Lowercase<S>> : T extends 'title' ? TitleCase<S> : T extends 'sentence' ? SentenceCase<S> : S;
|
|
14
|
+
type ChangeObjectCasing<T extends object, TCasing extends CasingType> = Expand<{ [K in keyof T as K extends string ? ChangeCasing<K, TCasing> : K]: T[K] }>;
|
|
15
|
+
declare const CASING_TYPES: readonly ["sentence", "title", "camel", "lower", "upper", "pascal", "snake", "screaming-snake", "flat", "kebab"];
|
|
16
|
+
type DefaultCasing = typeof DEFAULT_CASING;
|
|
17
|
+
declare const DEFAULT_CASING: SetDefaultString<CasingType, 'title'>;
|
|
18
|
+
/**
|
|
19
|
+
* Changes the casing of a string according to the specified casing type.
|
|
20
|
+
*
|
|
21
|
+
* @param input - The string to transform.
|
|
22
|
+
* @param type - The casing type to apply.
|
|
23
|
+
* @returns The transformed string in the specified casing.
|
|
24
|
+
*/
|
|
25
|
+
declare function changeCasing<TValue extends string, TType extends CasingType>(input: TValue, type: TType): ChangeCasing<TValue, TType>;
|
|
26
|
+
declare function quote(str: string, quoteChar?: '"' | "'"): string;
|
|
27
|
+
declare function isCasingValid(value: unknown): value is CasingType;
|
|
28
|
+
/**
|
|
29
|
+
* Validates {@linkcode input} is a valid {@linkcode CasingType}.
|
|
30
|
+
*
|
|
31
|
+
* If there is no explicit {@linkcode fallback} value provided,
|
|
32
|
+
* it will default to {@linkcode DEFAULT_CASING}.
|
|
33
|
+
* @param input The input to check.
|
|
34
|
+
* @param fallback An optional fallback value if {@linkcode input} is `undefined`.
|
|
35
|
+
* @returns The {@linkcode input} or {@linkcode fallback} if {@linkcode input} is `undefined` or an {@linkcode isCasingValid invalid} {@linkcode CasingType}.
|
|
36
|
+
*/
|
|
37
|
+
declare function setCasingType<TCasing extends CasingType>(input: TCasing | undefined, fallback?: CasingType): "sentence" | "title" | "camel" | "lower" | "upper" | "pascal" | "snake" | "screaming-snake" | "flat" | "kebab";
|
|
38
|
+
//#endregion
|
|
39
|
+
export { CASING_TYPES, CapitalizeWord, CasingType, ChangeCasing, ChangeObjectCasing, DEFAULT_CASING, DefaultCasing, ToLower, changeCasing, isCasingValid, quote, setCasingType };
|
|
40
|
+
//# sourceMappingURL=casing.d.mts.map
|