@formisch/qwik 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/index.d.ts +16 -13
- package/dist/index.qwik.js +30 -26
- package/package.json +7 -9
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Formisch is a schema-based, headless form library for Qwik. It manages form state and validation. It is type-safe, fast by default and its bundle size is small due to its modular design. Try it out in our [playground](https://stackblitz.com/edit/formisch-playground-qwik)!
|
|
4
4
|
|
|
5
|
+
Formisch is also available for [Preact][formisch-preact], [SolidJS][formisch-solid], and [Vue][formisch-vue]. Svelte will follow soon.
|
|
6
|
+
|
|
5
7
|
## Highlights
|
|
6
8
|
|
|
7
9
|
- Small bundle size starting at 2.5 kB
|
|
@@ -60,6 +62,16 @@ export default component$(() => {
|
|
|
60
62
|
|
|
61
63
|
In addition, Formisch offers several functions (we call them "methods") that can be used to read and manipulate the form state. These include `focus`, `getErrors`, `getAllErrors`, `getInput`, `insert`, `move`, `remove`, `replace`, `reset`, `setErrors`, `setInput`, `submit`, `swap` and `validate`. These methods allow you to control the form programmatically.
|
|
62
64
|
|
|
65
|
+
## Comparison
|
|
66
|
+
|
|
67
|
+
What makes Formisch unique is its framework-agnostic core, which is fully native to the framework you are using. It works by inserting framework-specific reactivity blocks when the core package is built. The result is a small bundle size and native performance for any UI update. This feature, along with a few others, distinguishes Formisch from other form libraries. My vision for Formisch is to create a framework-agnostic platform similar to [Vite](https://vite.dev/), but for forms.
|
|
68
|
+
|
|
69
|
+
## Partners
|
|
70
|
+
|
|
71
|
+
Thanks to our partners who support the development! [Join them](https://github.com/sponsors/fabian-hiller) and contribute to the sustainability of open source software!
|
|
72
|
+
|
|
73
|
+

|
|
74
|
+
|
|
63
75
|
## Feedback
|
|
64
76
|
|
|
65
77
|
Find a bug or have an idea how to improve the library? Please fill out an [issue](https://github.com/fabian-hiller/formisch/issues/new). Together we can make forms even better!
|
|
@@ -67,3 +79,7 @@ Find a bug or have an idea how to improve the library? Please fill out an [issue
|
|
|
67
79
|
## License
|
|
68
80
|
|
|
69
81
|
This project is available free of charge and licensed under the [MIT license](https://github.com/fabian-hiller/formisch/blob/main/LICENSE.md).
|
|
82
|
+
|
|
83
|
+
[formisch-preact]: https://github.com/fabian-hiller/formisch/tree/main/frameworks/preact
|
|
84
|
+
[formisch-solid]: https://github.com/fabian-hiller/formisch/tree/main/frameworks/solid
|
|
85
|
+
[formisch-vue]: https://github.com/fabian-hiller/formisch/tree/main/frameworks/vue
|
package/dist/index.d.ts
CHANGED
|
@@ -78,21 +78,21 @@ type PartialValues<TValue> = TValue extends readonly unknown[] ? number extends
|
|
|
78
78
|
* Value type of the validation mode.
|
|
79
79
|
*/
|
|
80
80
|
type ValidationMode = "initial" | "touch" | "input" | "change" | "blur" | "submit";
|
|
81
|
-
type SubmitHandler<TSchema extends Schema> = (output: v.InferOutput<TSchema>, event: SubmitEvent) => MaybePromise<
|
|
81
|
+
type SubmitHandler<TSchema extends Schema> = (output: v.InferOutput<TSchema>, event: SubmitEvent) => MaybePromise<unknown>;
|
|
82
82
|
//#endregion
|
|
83
83
|
//#region src/types/form.qwik.d.ts
|
|
84
84
|
interface FormConfig<TSchema extends Schema = Schema> {
|
|
85
85
|
readonly schema: TSchema;
|
|
86
86
|
readonly initialInput?: DeepPartial<v.InferInput<TSchema>> | undefined;
|
|
87
|
-
readonly
|
|
88
|
-
readonly
|
|
87
|
+
readonly validate?: ValidationMode | undefined;
|
|
88
|
+
readonly revalidate?: Exclude<ValidationMode, "initial"> | undefined;
|
|
89
89
|
}
|
|
90
90
|
interface InternalFormStore<TSchema extends Schema = Schema> extends InternalObjectStore {
|
|
91
91
|
element?: HTMLFormElement;
|
|
92
92
|
validators: number;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
validate: ValidationMode;
|
|
94
|
+
revalidate: Exclude<ValidationMode, "initial">;
|
|
95
|
+
parse: QRL<(input: unknown) => Promise<v.SafeParseResult<TSchema>>>;
|
|
96
96
|
isSubmitting: Signal<boolean>;
|
|
97
97
|
isSubmitted: Signal<boolean>;
|
|
98
98
|
isValidating: Signal<boolean>;
|
|
@@ -129,16 +129,16 @@ type MergeUnion<T> = { [K in KeyOf<T>]: T extends Record<K, infer V> ? V : never
|
|
|
129
129
|
/**
|
|
130
130
|
* Lazily evaluate only the first valid path segment based on the given value.
|
|
131
131
|
*/
|
|
132
|
-
type LazyPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValidPath : TPathToCheck extends readonly [infer TFirstKey extends KeyOf<TValue>, ...infer TPathRest extends Path] ? LazyPath<MergeUnion<TValue>[TFirstKey]
|
|
132
|
+
type LazyPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValidPath : TPathToCheck extends readonly [infer TFirstKey extends KeyOf<TValue>, ...infer TPathRest extends Path] ? LazyPath<Required<MergeUnion<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<KeyOf<TValue>> extends false ? readonly [...TValidPath, KeyOf<TValue>] : TValidPath;
|
|
133
133
|
/**
|
|
134
134
|
* Returns the path if valid, otherwise the first possible valid path based on
|
|
135
135
|
* the given value.
|
|
136
136
|
*/
|
|
137
|
-
type ValidPath<TValue, TPath extends RequiredPath> = TPath extends LazyPath<TValue
|
|
137
|
+
type ValidPath<TValue, TPath extends RequiredPath> = TPath extends LazyPath<Required<TValue>, TPath> ? TPath : LazyPath<Required<TValue>, TPath>;
|
|
138
138
|
/**
|
|
139
139
|
* Extracts the value type at the given path.
|
|
140
140
|
*/
|
|
141
|
-
type PathValue<TValue, TPath extends Path> = TPath extends readonly [infer TKey, ...infer TRest extends Path] ? TKey extends KeyOf<TValue
|
|
141
|
+
type PathValue<TValue, TPath extends Path> = TPath extends readonly [infer TKey, ...infer TRest extends Path] ? TKey extends KeyOf<Required<TValue>> ? PathValue<MergeUnion<Required<TValue>>[TKey], TRest> : unknown : TValue;
|
|
142
142
|
/**
|
|
143
143
|
* Checks if a value is an array or contains one.
|
|
144
144
|
*/
|
|
@@ -146,16 +146,16 @@ type IsOrHasArray<TValue> = IsAny<TValue> extends true ? false : TValue extends
|
|
|
146
146
|
/**
|
|
147
147
|
* Extracts the exact keys of a tuple, array or object that contain arrays.
|
|
148
148
|
*/
|
|
149
|
-
type KeyOfArrayPath<TValue> = IsAny<TValue> extends true ? never : TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? IsOrHasArray<TItem> extends true ? number : never : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? IsOrHasArray<TValue[TKey]
|
|
149
|
+
type KeyOfArrayPath<TValue> = IsAny<TValue> extends true ? never : TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? IsOrHasArray<TItem> extends true ? number : never : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? IsOrHasArray<NonNullable<TValue[TKey]>> extends true ? TIndex : never : never }[number] : TValue extends Record<string, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<NonNullable<TValue[TKey]>> extends true ? TKey : never }[keyof TValue] & PathKey : never;
|
|
150
150
|
/**
|
|
151
151
|
* Lazily evaluate only the first valid array path segment based on the given value.
|
|
152
152
|
*/
|
|
153
|
-
type LazyArrayPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? TValidPath : readonly [...TValidPath, KeyOfArrayPath<TValue>] : TPathToCheck extends readonly [infer TFirstKey extends KeyOfArrayPath<TValue>, ...infer TPathRest extends Path] ? LazyArrayPath<MergeUnion<TValue>[TFirstKey]
|
|
153
|
+
type LazyArrayPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? TValidPath : readonly [...TValidPath, KeyOfArrayPath<TValue>] : TPathToCheck extends readonly [infer TFirstKey extends KeyOfArrayPath<TValue>, ...infer TPathRest extends Path] ? LazyArrayPath<Required<MergeUnion<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<KeyOfArrayPath<TValue>> extends false ? readonly [...TValidPath, KeyOfArrayPath<TValue>] : never;
|
|
154
154
|
/**
|
|
155
155
|
* Returns the path if valid, otherwise the first possible valid array path based on
|
|
156
156
|
* the given value.
|
|
157
157
|
*/
|
|
158
|
-
type ValidArrayPath<TValue, TPath extends RequiredPath> = TPath extends LazyArrayPath<TValue
|
|
158
|
+
type ValidArrayPath<TValue, TPath extends RequiredPath> = TPath extends LazyArrayPath<Required<TValue>, TPath> ? TPath : LazyArrayPath<Required<TValue>, TPath>;
|
|
159
159
|
//#endregion
|
|
160
160
|
//#region src/array/copyItemState/copyItemState.d.ts
|
|
161
161
|
/**
|
|
@@ -199,6 +199,9 @@ interface GetFieldInputConfig<TSchema extends Schema, TFieldPath extends Require
|
|
|
199
199
|
declare function getInput<TSchema extends Schema>(form: BaseFormStore<TSchema>): PartialValues<v.InferInput<TSchema>>;
|
|
200
200
|
declare function getInput<TSchema extends Schema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? GetFieldInputConfig<TSchema, TFieldPath> : GetFormInputConfig): PartialValues<TFieldPath extends RequiredPath ? PathValue<v.InferInput<TSchema>, TFieldPath> : v.InferInput<TSchema>>;
|
|
201
201
|
//#endregion
|
|
202
|
+
//#region src/handleSubmit/handleSubmit.d.ts
|
|
203
|
+
declare function handleSubmit<TSchema extends Schema>(form: BaseFormStore<TSchema>, handler: SubmitHandler<TSchema>): (event: SubmitEvent) => void;
|
|
204
|
+
//#endregion
|
|
202
205
|
//#region src/insert/insert.d.ts
|
|
203
206
|
interface InsertConfig<TSchema extends Schema, TFieldArrayPath extends RequiredPath> {
|
|
204
207
|
readonly path: ValidArrayPath<v.InferInput<TSchema>, TFieldArrayPath>;
|
|
@@ -389,4 +392,4 @@ declare function useFieldArray<TSchema extends Schema, TFieldArrayPath extends R
|
|
|
389
392
|
declare function useFormQrl<TSchema extends Schema>(configQrl: QRL<FormConfig<TSchema>>): FormStore<TSchema>;
|
|
390
393
|
declare const useForm$: <TSchema extends Schema>(qrl: FormConfig<TSchema>) => FormStore<TSchema>;
|
|
391
394
|
//#endregion
|
|
392
|
-
export { Field, FieldArray, FieldArrayProps, FieldArrayStore, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, FormProps, FormStore, GetFieldErrorsConfig, GetFieldInputConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, MoveConfig, RemoveConfig, ReplaceConfig, ResetFieldConfig, ResetFormConfig, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, SwapConfig, UseFieldArrayConfig, UseFieldConfig, ValidateFormConfig, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
|
395
|
+
export { Field, FieldArray, FieldArrayProps, FieldArrayStore, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, FormProps, FormStore, GetFieldErrorsConfig, GetFieldInputConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, MoveConfig, RemoveConfig, ReplaceConfig, ResetFieldConfig, ResetFormConfig, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, type SubmitHandler, SwapConfig, UseFieldArrayConfig, UseFieldConfig, ValidateFormConfig, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
package/dist/index.qwik.js
CHANGED
|
@@ -123,6 +123,7 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
123
123
|
*/
|
|
124
124
|
function resetItemState(internalFieldStore, initialInput) {
|
|
125
125
|
batch(() => {
|
|
126
|
+
internalFieldStore.errors.value = null;
|
|
126
127
|
if (internalFieldStore.kind === "array") {
|
|
127
128
|
internalFieldStore.isTouched.value = false;
|
|
128
129
|
internalFieldStore.isDirty.value = false;
|
|
@@ -295,6 +296,7 @@ function setFieldInput(internalFieldStore, input) {
|
|
|
295
296
|
} else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setFieldInput(internalFieldStore.children[key], input[key]);
|
|
296
297
|
else {
|
|
297
298
|
internalFieldStore.input.value = input;
|
|
299
|
+
internalFieldStore.isTouched.value = true;
|
|
298
300
|
const startInput = untrack(() => internalFieldStore.startInput.value);
|
|
299
301
|
internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
|
|
300
302
|
}
|
|
@@ -323,12 +325,12 @@ function walkFieldStore(internalFieldStore, callback) {
|
|
|
323
325
|
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
|
|
324
326
|
else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
|
|
325
327
|
}
|
|
326
|
-
function createFormStore(config,
|
|
328
|
+
function createFormStore(config, parse) {
|
|
327
329
|
const store = {};
|
|
328
330
|
initializeFieldStore(store, config.schema, config.initialInput, []);
|
|
329
|
-
store.
|
|
330
|
-
store.
|
|
331
|
-
store.
|
|
331
|
+
store.validate = config.validate ?? "submit";
|
|
332
|
+
store.revalidate = config.revalidate ?? "input";
|
|
333
|
+
store.parse = parse;
|
|
332
334
|
store.isSubmitting = createSignal(false);
|
|
333
335
|
store.isSubmitted = createSignal(false);
|
|
334
336
|
store.isValidating = createSignal(false);
|
|
@@ -337,7 +339,7 @@ function createFormStore(config, validate$1) {
|
|
|
337
339
|
async function validateFormInput(internalFormStore, config) {
|
|
338
340
|
internalFormStore.validators++;
|
|
339
341
|
internalFormStore.isValidating.value = true;
|
|
340
|
-
const result = await internalFormStore.
|
|
342
|
+
const result = await internalFormStore.parse(untrack(() => getFieldInput(internalFormStore)));
|
|
341
343
|
let rootErrors;
|
|
342
344
|
let nestedErrors;
|
|
343
345
|
if (result.issues) {
|
|
@@ -377,7 +379,7 @@ async function validateFormInput(internalFormStore, config) {
|
|
|
377
379
|
return result;
|
|
378
380
|
}
|
|
379
381
|
function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
|
|
380
|
-
if (validationModes === (internalFormStore.
|
|
382
|
+
if (validationModes === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
|
|
381
383
|
}
|
|
382
384
|
const INTERNAL = "~internal";
|
|
383
385
|
|
|
@@ -401,6 +403,22 @@ function getErrors(form, config) {
|
|
|
401
403
|
function getInput(form, config) {
|
|
402
404
|
return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
|
|
403
405
|
}
|
|
406
|
+
function handleSubmit(form, handler) {
|
|
407
|
+
return async (event) => {
|
|
408
|
+
event.preventDefault();
|
|
409
|
+
const internalFormStore = form[INTERNAL];
|
|
410
|
+
internalFormStore.isSubmitted.value = true;
|
|
411
|
+
internalFormStore.isSubmitting.value = true;
|
|
412
|
+
try {
|
|
413
|
+
const result = await validateFormInput(internalFormStore, { shouldFocus: true });
|
|
414
|
+
if (result.success) await handler(result.output, event);
|
|
415
|
+
} catch (error) {
|
|
416
|
+
internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
|
|
417
|
+
} finally {
|
|
418
|
+
internalFormStore.isSubmitting.value = false;
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
}
|
|
404
422
|
function insert(form, config) {
|
|
405
423
|
const internalFormStore = form[INTERNAL];
|
|
406
424
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -492,7 +510,7 @@ function reset(form, config) {
|
|
|
492
510
|
});
|
|
493
511
|
if (!config?.path) {
|
|
494
512
|
if (!config?.keepSubmitted) internalFormStore.isSubmitted.value = false;
|
|
495
|
-
if (internalFormStore.
|
|
513
|
+
if (internalFormStore.validate === "initial") validateFormInput(internalFormStore);
|
|
496
514
|
}
|
|
497
515
|
});
|
|
498
516
|
});
|
|
@@ -504,7 +522,6 @@ function setInput(form, config) {
|
|
|
504
522
|
batch(() => {
|
|
505
523
|
const internalFormStore = form[INTERNAL];
|
|
506
524
|
const internalFieldStore = config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
|
|
507
|
-
setFieldBool(internalFieldStore, "isTouched", true);
|
|
508
525
|
setFieldInput(internalFieldStore, config.input);
|
|
509
526
|
validateIfRequired(internalFormStore, internalFieldStore, "input");
|
|
510
527
|
});
|
|
@@ -576,8 +593,7 @@ function useField(form, config) {
|
|
|
576
593
|
validateIfRequired(form[INTERNAL], internalFieldStore.value, "touch");
|
|
577
594
|
}),
|
|
578
595
|
onInput$: $((_, element) => {
|
|
579
|
-
|
|
580
|
-
setFieldInput(internalFieldStore.value, nextValue);
|
|
596
|
+
setFieldInput(internalFieldStore.value, getElementInput(element, internalFieldStore.value));
|
|
581
597
|
validateIfRequired(form[INTERNAL], internalFieldStore.value, "input");
|
|
582
598
|
}),
|
|
583
599
|
onChange$: $(() => {
|
|
@@ -636,9 +652,9 @@ function useFormQrl(configQrl) {
|
|
|
636
652
|
errors: internalFormStore.errors
|
|
637
653
|
};
|
|
638
654
|
});
|
|
639
|
-
const
|
|
655
|
+
const validate$1 = config.validate;
|
|
640
656
|
useTask$(async () => {
|
|
641
|
-
if (
|
|
657
|
+
if (validate$1 === "initial") await validateFormInput(form[INTERNAL]);
|
|
642
658
|
});
|
|
643
659
|
return form;
|
|
644
660
|
}
|
|
@@ -676,22 +692,10 @@ const Form = component$(({ of, onSubmit$,...other }) => {
|
|
|
676
692
|
ref: (element) => {
|
|
677
693
|
of[INTERNAL].element = element;
|
|
678
694
|
},
|
|
679
|
-
onSubmit$:
|
|
680
|
-
const internalFormStore = of[INTERNAL];
|
|
681
|
-
internalFormStore.isSubmitted.value = true;
|
|
682
|
-
internalFormStore.isSubmitting.value = true;
|
|
683
|
-
try {
|
|
684
|
-
const result = await validateFormInput(internalFormStore, { shouldFocus: true });
|
|
685
|
-
if (result.success) await onSubmit$(result.output, event);
|
|
686
|
-
} catch (error) {
|
|
687
|
-
internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
|
|
688
|
-
} finally {
|
|
689
|
-
internalFormStore.isSubmitting.value = false;
|
|
690
|
-
}
|
|
691
|
-
},
|
|
695
|
+
onSubmit$: (event) => handleSubmit(of, onSubmit$)(event),
|
|
692
696
|
children: /* @__PURE__ */ jsx(Slot, {})
|
|
693
697
|
});
|
|
694
698
|
});
|
|
695
699
|
|
|
696
700
|
//#endregion
|
|
697
|
-
export { Field, FieldArray, Form, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
|
701
|
+
export { Field, FieldArray, Form, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formisch/qwik",
|
|
3
3
|
"description": "The modular and type-safe form library for Qwik",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Fabian Hiller",
|
|
7
7
|
"homepage": "https://formisch.dev",
|
|
@@ -11,13 +11,10 @@
|
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"qwik",
|
|
14
|
-
"
|
|
14
|
+
"form",
|
|
15
15
|
"typescript",
|
|
16
16
|
"schema",
|
|
17
|
-
"validation"
|
|
18
|
-
"parsing",
|
|
19
|
-
"bundle-size",
|
|
20
|
-
"type-safe"
|
|
17
|
+
"validation"
|
|
21
18
|
],
|
|
22
19
|
"type": "module",
|
|
23
20
|
"main": "./dist/index.qwik.js",
|
|
@@ -40,9 +37,10 @@
|
|
|
40
37
|
},
|
|
41
38
|
"scripts": {
|
|
42
39
|
"build": "tsdown",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
40
|
+
"lint": "eslint \"src/**/*.ts*\" && tsc --noEmit",
|
|
41
|
+
"lint.fix": "eslint \"src/**/*.ts*\" --fix",
|
|
42
|
+
"format": "prettier --write ./src",
|
|
43
|
+
"format.check": "prettier --check ./src",
|
|
46
44
|
"qwik": "qwik"
|
|
47
45
|
},
|
|
48
46
|
"devDependencies": {
|