@vuehookform/core 0.3.0 → 0.3.3

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 CHANGED
@@ -10,7 +10,7 @@ A TypeScript-first form library for Vue 3, inspired by React Hook Form.
10
10
  - **Field Arrays** - Dynamic lists with stable keys built-in
11
11
  - **Performant** - Minimal re-renders using uncontrolled inputs
12
12
  - **Zod Native** - First-class Zod integration for validation
13
- - **Tiny Bundle** - < 5kb gzipped, tree-shakable
13
+ - **Tiny Bundle** - ~10kb gzipped, tree-shakable
14
14
  - **UI Agnostic** - Works with any UI library or custom components
15
15
 
16
16
  ## Quick Start
@@ -1,8 +1,4 @@
1
1
  import { ZodType } from 'zod';
2
- /**
3
- * DEV flag for tree-shaking
4
- * In production builds, this becomes `false` and all warning code is eliminated
5
- */
6
2
  export declare const __DEV__: boolean;
7
3
  /**
8
4
  * Warn once per unique message (prevents spam on re-renders)
@@ -53,11 +53,26 @@ function generateId() {
53
53
  const random = Math.random().toString(36).substring(2, 11);
54
54
  return `field_${Date.now()}_${idCounter++}_${random}`;
55
55
  }
56
- const __DEV__ = false;
56
+ var proc = globalThis.process;
57
+ const __DEV__ = proc?.env?.NODE_ENV !== "production";
57
58
  var warnedMessages = /* @__PURE__ */ new Set();
58
- function warnOnce(message, key) {}
59
- function warn(message) {}
59
+ function warnOnce(message, key) {
60
+ if (!__DEV__) return;
61
+ const cacheKey = key ?? message;
62
+ if (warnedMessages.has(cacheKey)) return;
63
+ warnedMessages.add(cacheKey);
64
+ console.warn(`[vue-hook-form] ${message}`);
65
+ }
66
+ function warn(message) {
67
+ if (!__DEV__) return;
68
+ console.warn(`[vue-hook-form] ${message}`);
69
+ }
60
70
  function validatePathSyntax(path) {
71
+ if (!__DEV__) return null;
72
+ if (!path || path.trim() === "") return "Path cannot be empty";
73
+ if (path.startsWith(".") || path.endsWith(".") || path.includes("..")) return `Invalid path "${path}": contains empty segments`;
74
+ if (path.includes("[")) return `Invalid path "${path}": use dot notation (e.g., "items.0") instead of bracket notation (e.g., "items[0]")`;
75
+ if (/\s/.test(path)) return `Invalid path "${path}": paths cannot contain whitespace`;
61
76
  return null;
62
77
  }
63
78
  function traverseSchemaPath(schema, path) {
@@ -94,16 +109,77 @@ function traverseSchemaPath(schema, path) {
94
109
  return { schema: currentSchema };
95
110
  }
96
111
  function validatePathAgainstSchema(schema, path) {
97
- return { valid: true };
112
+ if (!__DEV__) return { valid: true };
113
+ try {
114
+ const result = traverseSchemaPath(schema, path);
115
+ if ("error" in result) return {
116
+ valid: false,
117
+ reason: result.error,
118
+ availableFields: result.availableFields
119
+ };
120
+ return { valid: true };
121
+ } catch {
122
+ return { valid: true };
123
+ }
98
124
  }
99
125
  function isArrayFieldInSchema(schema, path) {
100
- return null;
126
+ if (!__DEV__) return null;
127
+ try {
128
+ const result = traverseSchemaPath(schema, path);
129
+ if ("error" in result) return null;
130
+ return isZodArray(unwrapSchema(result.schema));
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+ function warnInvalidPath(fnName, path, reason) {
136
+ if (!__DEV__) return;
137
+ let message = `${fnName}("${path}"): ${reason}`;
138
+ if (reason.includes("bracket notation")) {
139
+ const fixedPath = path.replace(/\[(\d+)\]/g, ".$1");
140
+ message += `\n FIX: Use dot notation for array indices`;
141
+ message += `\n EXAMPLE: ${fnName}("${fixedPath}")`;
142
+ } else if (reason.includes("empty")) {
143
+ message += `\n FIX: Provide a non-empty field path`;
144
+ message += `\n EXAMPLE: ${fnName}("email") or ${fnName}("user.address.city")`;
145
+ } else if (reason.includes("whitespace")) {
146
+ const fixedPath = path.replace(/\s/g, "");
147
+ message += `\n FIX: Remove spaces from the field path`;
148
+ message += `\n EXAMPLE: ${fnName}("${fixedPath}")`;
149
+ } else if (reason.includes("empty segments")) {
150
+ const fixedPath = path.replace(/\.{2,}/g, ".").replace(/^\./, "").replace(/\.$/, "");
151
+ message += `\n FIX: Remove extra dots from the path`;
152
+ message += `\n EXAMPLE: ${fnName}("${fixedPath}")`;
153
+ }
154
+ warnOnce(message, `invalid-path:${fnName}:${path}`);
155
+ }
156
+ function warnPathNotInSchema(fnName, path, availableFields) {
157
+ if (!__DEV__) return;
158
+ let message = `${fnName}("${path}"): Path does not exist in your Zod schema.`;
159
+ message += `\n FIX: Check that the path matches your schema definition exactly (case-sensitive)`;
160
+ if (availableFields && availableFields.length > 0) {
161
+ const pathLower = path.toLowerCase();
162
+ const suggestions = availableFields.filter((f) => f.toLowerCase().includes(pathLower) || pathLower.includes(f.toLowerCase()));
163
+ if (suggestions.length > 0) message += `\n DID YOU MEAN: ${suggestions.slice(0, 3).map((s) => `"${s}"`).join(", ")}`;
164
+ message += `\n AVAILABLE: ${availableFields.slice(0, 8).join(", ")}${availableFields.length > 8 ? "..." : ""}`;
165
+ }
166
+ warnOnce(message, `path-not-in-schema:${fnName}:${path}`);
167
+ }
168
+ function warnFieldsOnNonArray(path) {
169
+ if (!__DEV__) return;
170
+ warnOnce(`fields("${path}"): Expected an array field, but this path does not point to an array in your schema. The fields() method is only for array fields. Use register() for non-array fields.`, `fields-non-array:${path}`);
171
+ }
172
+ function warnArrayOperationRejected(operation, path, reason, details) {
173
+ if (!__DEV__) return;
174
+ warn(`${operation}() on "${path}": ${{
175
+ maxLength: details ? `Would exceed maxLength (current: ${details.current}, max: ${details.limit})` : "Would exceed maxLength rule",
176
+ minLength: details ? `Would violate minLength (current: ${details.current}, min: ${details.limit})` : "Would violate minLength rule"
177
+ }[reason]}. Operation was silently ignored.`);
178
+ }
179
+ function warnArrayIndexOutOfBounds(operation, path, index, length) {
180
+ if (!__DEV__) return;
181
+ warn(`${operation}() on "${path}": Index ${index} is out of bounds (array length: ${length}). Operation was silently ignored.`);
101
182
  }
102
- function warnInvalidPath(fnName, path, reason) {}
103
- function warnPathNotInSchema(fnName, path, availableFields) {}
104
- function warnFieldsOnNonArray(path) {}
105
- function warnArrayOperationRejected(operation, path, reason, details) {}
106
- function warnArrayIndexOutOfBounds(operation, path, index, length) {}
107
183
  function getDefProp(schema, prop) {
108
184
  return schema.def[prop];
109
185
  }
@@ -369,6 +445,12 @@ function createValidation(ctx) {
369
445
  var validationRequestCounter = 0;
370
446
  function createFieldRegistration(ctx, validate) {
371
447
  function register(name, registerOptions) {
448
+ if (__DEV__) {
449
+ const syntaxError = validatePathSyntax(name);
450
+ if (syntaxError) warnInvalidPath("register", name, syntaxError);
451
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, name);
452
+ if (!schemaResult.valid) warnPathNotInSchema("register", name, schemaResult.availableFields);
453
+ }
372
454
  let fieldRef = ctx.fieldRefs.get(name);
373
455
  if (!fieldRef) {
374
456
  fieldRef = (0, vue.ref)(null);
@@ -535,6 +617,13 @@ function createFieldRegistration(ctx, validate) {
535
617
  }
536
618
  function createFieldArrayManager(ctx, validate, setFocus) {
537
619
  function fields(name, options) {
620
+ if (__DEV__) {
621
+ const syntaxError = validatePathSyntax(name);
622
+ if (syntaxError) warnInvalidPath("fields", name, syntaxError);
623
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, name);
624
+ if (!schemaResult.valid) warnPathNotInSchema("fields", name, schemaResult.availableFields);
625
+ if (isArrayFieldInSchema(ctx.options.schema, name) === false) warnFieldsOnNonArray(name);
626
+ }
538
627
  let fieldArray = ctx.fieldArrays.get(name);
539
628
  if (!fieldArray) {
540
629
  const existingValues = get(ctx.formData, name) || [];
@@ -586,7 +675,13 @@ function createFieldArrayManager(ctx, validate, setFocus) {
586
675
  const currentValues = get(ctx.formData, name) || [];
587
676
  const insertIndex = currentValues.length;
588
677
  const rules = fa.rules;
589
- if (rules?.maxLength && currentValues.length + values.length > rules.maxLength.value) return false;
678
+ if (rules?.maxLength && currentValues.length + values.length > rules.maxLength.value) {
679
+ if (__DEV__) warnArrayOperationRejected("append", name, "maxLength", {
680
+ current: currentValues.length,
681
+ limit: rules.maxLength.value
682
+ });
683
+ return false;
684
+ }
590
685
  const newValues = [...currentValues, ...values];
591
686
  set(ctx.formData, name, newValues);
592
687
  const newItems = values.map(() => createItem(generateId()));
@@ -605,7 +700,13 @@ function createFieldArrayManager(ctx, validate, setFocus) {
605
700
  if (values.length === 0) return true;
606
701
  const currentValues = get(ctx.formData, name) || [];
607
702
  const rules = fa.rules;
608
- if (rules?.maxLength && currentValues.length + values.length > rules.maxLength.value) return false;
703
+ if (rules?.maxLength && currentValues.length + values.length > rules.maxLength.value) {
704
+ if (__DEV__) warnArrayOperationRejected("prepend", name, "maxLength", {
705
+ current: currentValues.length,
706
+ limit: rules.maxLength.value
707
+ });
708
+ return false;
709
+ }
609
710
  const newValues = [...values, ...currentValues];
610
711
  set(ctx.formData, name, newValues);
611
712
  const newItems = values.map(() => createItem(generateId()));
@@ -621,7 +722,10 @@ function createFieldArrayManager(ctx, validate, setFocus) {
621
722
  };
622
723
  const update = (index, value) => {
623
724
  const currentValues = get(ctx.formData, name) || [];
624
- if (index < 0 || index >= currentValues.length) return false;
725
+ if (index < 0 || index >= currentValues.length) {
726
+ if (__DEV__) warnArrayIndexOutOfBounds("update", name, index, currentValues.length);
727
+ return false;
728
+ }
625
729
  const newValues = [...currentValues];
626
730
  newValues[index] = value;
627
731
  set(ctx.formData, name, newValues);
@@ -634,9 +738,18 @@ function createFieldArrayManager(ctx, validate, setFocus) {
634
738
  };
635
739
  const removeAt = (index) => {
636
740
  const currentValues = get(ctx.formData, name) || [];
637
- if (index < 0 || index >= currentValues.length) return false;
741
+ if (index < 0 || index >= currentValues.length) {
742
+ if (__DEV__) warnArrayIndexOutOfBounds("remove", name, index, currentValues.length);
743
+ return false;
744
+ }
638
745
  const rules = fa.rules;
639
- if (rules?.minLength && currentValues.length - 1 < rules.minLength.value) return false;
746
+ if (rules?.minLength && currentValues.length - 1 < rules.minLength.value) {
747
+ if (__DEV__) warnArrayOperationRejected("remove", name, "minLength", {
748
+ current: currentValues.length,
749
+ limit: rules.minLength.value
750
+ });
751
+ return false;
752
+ }
640
753
  const newValues = currentValues.filter((_, i) => i !== index);
641
754
  set(ctx.formData, name, newValues);
642
755
  const keyToRemove = fa.items.value[index]?.key;
@@ -654,7 +767,13 @@ function createFieldArrayManager(ctx, validate, setFocus) {
654
767
  if (values.length === 0) return true;
655
768
  const currentValues = get(ctx.formData, name) || [];
656
769
  const rules = fa.rules;
657
- if (rules?.maxLength && currentValues.length + values.length > rules.maxLength.value) return false;
770
+ if (rules?.maxLength && currentValues.length + values.length > rules.maxLength.value) {
771
+ if (__DEV__) warnArrayOperationRejected("insert", name, "maxLength", {
772
+ current: currentValues.length,
773
+ limit: rules.maxLength.value
774
+ });
775
+ return false;
776
+ }
658
777
  const clampedIndex = Math.max(0, Math.min(index, currentValues.length));
659
778
  const newValues = [
660
779
  ...currentValues.slice(0, clampedIndex),
@@ -679,7 +798,10 @@ function createFieldArrayManager(ctx, validate, setFocus) {
679
798
  };
680
799
  const swap = (indexA, indexB) => {
681
800
  const currentValues = get(ctx.formData, name) || [];
682
- if (indexA < 0 || indexB < 0 || indexA >= currentValues.length || indexB >= currentValues.length) return false;
801
+ if (indexA < 0 || indexB < 0 || indexA >= currentValues.length || indexB >= currentValues.length) {
802
+ if (__DEV__) warnArrayIndexOutOfBounds("swap", name, indexA < 0 || indexA >= currentValues.length ? indexA : indexB, currentValues.length);
803
+ return false;
804
+ }
683
805
  const newValues = [...currentValues];
684
806
  [newValues[indexA], newValues[indexB]] = [newValues[indexB], newValues[indexA]];
685
807
  set(ctx.formData, name, newValues);
@@ -701,7 +823,10 @@ function createFieldArrayManager(ctx, validate, setFocus) {
701
823
  };
702
824
  const move = (from, to) => {
703
825
  const currentValues = get(ctx.formData, name) || [];
704
- if (from < 0 || from >= currentValues.length || to < 0) return false;
826
+ if (from < 0 || from >= currentValues.length || to < 0) {
827
+ if (__DEV__) warnArrayIndexOutOfBounds("move", name, from < 0 || from >= currentValues.length ? from : to, currentValues.length);
828
+ return false;
829
+ }
705
830
  const newValues = [...currentValues];
706
831
  const [removed] = newValues.splice(from, 1);
707
832
  if (removed !== void 0) {
@@ -738,7 +863,13 @@ function createFieldArrayManager(ctx, validate, setFocus) {
738
863
  };
739
864
  const removeAll = () => {
740
865
  const rules = fa.rules;
741
- if (rules?.minLength && rules.minLength.value > 0) return false;
866
+ if (rules?.minLength && rules.minLength.value > 0) {
867
+ if (__DEV__) warnArrayOperationRejected("removeAll", name, "minLength", {
868
+ current: fa.items.value.length,
869
+ limit: rules.minLength.value
870
+ });
871
+ return false;
872
+ }
742
873
  set(ctx.formData, name, []);
743
874
  fa.items.value = [];
744
875
  rebuildIndexCache();
@@ -755,7 +886,13 @@ function createFieldArrayManager(ctx, validate, setFocus) {
755
886
  if (validIndices.length === 0) return true;
756
887
  const rules = fa.rules;
757
888
  const remainingCount = currentValues.length - validIndices.length;
758
- if (rules?.minLength && remainingCount < rules.minLength.value) return false;
889
+ if (rules?.minLength && remainingCount < rules.minLength.value) {
890
+ if (__DEV__) warnArrayOperationRejected("removeMany", name, "minLength", {
891
+ current: currentValues.length,
892
+ limit: rules.minLength.value
893
+ });
894
+ return false;
895
+ }
759
896
  const sortedIndices = [...new Set(validIndices)].sort((a, b) => b - a);
760
897
  const indicesToRemove = new Set(sortedIndices);
761
898
  const newValues = currentValues.filter((_, i) => !indicesToRemove.has(i));
@@ -829,6 +966,14 @@ function useForm(options) {
829
966
  const { validate, clearAllPendingErrors } = createValidation(ctx);
830
967
  const { register, unregister } = createFieldRegistration(ctx, validate);
831
968
  function setFocus(name, focusOptions) {
969
+ if (__DEV__) {
970
+ const syntaxError = validatePathSyntax(name);
971
+ if (syntaxError) warnInvalidPath("setFocus", name, syntaxError);
972
+ else {
973
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, name);
974
+ if (!schemaResult.valid) warnPathNotInSchema("setFocus", name, schemaResult.availableFields);
975
+ }
976
+ }
832
977
  const fieldRef = ctx.fieldRefs.get(name);
833
978
  if (!fieldRef?.value) return;
834
979
  const el = fieldRef.value;
@@ -891,6 +1036,14 @@ function useForm(options) {
891
1036
  };
892
1037
  }
893
1038
  function setValue(name, value, setValueOptions) {
1039
+ if (__DEV__) {
1040
+ const syntaxError = validatePathSyntax(name);
1041
+ if (syntaxError) warnInvalidPath("setValue", name, syntaxError);
1042
+ else {
1043
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, name);
1044
+ if (!schemaResult.valid) warnPathNotInSchema("setValue", name, schemaResult.availableFields);
1045
+ }
1046
+ }
894
1047
  set(ctx.formData, name, value);
895
1048
  if (setValueOptions?.shouldDirty !== false) markFieldDirty(ctx.dirtyFields, name);
896
1049
  if (setValueOptions?.shouldTouch) markFieldTouched(ctx.touchedFields, name);
@@ -927,6 +1080,14 @@ function useForm(options) {
927
1080
  }
928
1081
  }
929
1082
  function resetField(name, resetFieldOptions) {
1083
+ if (__DEV__) {
1084
+ const syntaxError = validatePathSyntax(name);
1085
+ if (syntaxError) warnInvalidPath("resetField", name, syntaxError);
1086
+ else {
1087
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, name);
1088
+ if (!schemaResult.valid) warnPathNotInSchema("resetField", name, schemaResult.availableFields);
1089
+ }
1090
+ }
930
1091
  const opts = resetFieldOptions || {};
931
1092
  ctx.resetGeneration.value++;
932
1093
  const errorTimer = ctx.errorDelayTimers.get(name);
@@ -949,6 +1110,17 @@ function useForm(options) {
949
1110
  }
950
1111
  }
951
1112
  function watch$1(name) {
1113
+ if (__DEV__ && name) {
1114
+ const names = Array.isArray(name) ? name : [name];
1115
+ for (const n of names) {
1116
+ const syntaxError = validatePathSyntax(n);
1117
+ if (syntaxError) warnInvalidPath("watch", n, syntaxError);
1118
+ else {
1119
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, n);
1120
+ if (!schemaResult.valid) warnPathNotInSchema("watch", n, schemaResult.availableFields);
1121
+ }
1122
+ }
1123
+ }
952
1124
  return (0, vue.computed)(() => {
953
1125
  if (!name) return ctx.formData;
954
1126
  if (Array.isArray(name)) {
@@ -960,6 +1132,18 @@ function useForm(options) {
960
1132
  });
961
1133
  }
962
1134
  function clearErrors(name) {
1135
+ if (__DEV__ && name && !String(name).startsWith("root")) {
1136
+ const names = Array.isArray(name) ? name : [name];
1137
+ for (const n of names) {
1138
+ if (String(n).startsWith("root")) continue;
1139
+ const syntaxError = validatePathSyntax(n);
1140
+ if (syntaxError) warnInvalidPath("clearErrors", n, syntaxError);
1141
+ else {
1142
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, n);
1143
+ if (!schemaResult.valid) warnPathNotInSchema("clearErrors", n, schemaResult.availableFields);
1144
+ }
1145
+ }
1146
+ }
963
1147
  if (name === void 0) {
964
1148
  ctx.errors.value = {};
965
1149
  return;
@@ -998,6 +1182,17 @@ function useForm(options) {
998
1182
  return get(mergedErrors, fieldPath);
999
1183
  }
1000
1184
  function getValues(nameOrNames) {
1185
+ if (__DEV__ && nameOrNames) {
1186
+ const names = Array.isArray(nameOrNames) ? nameOrNames : [nameOrNames];
1187
+ for (const n of names) {
1188
+ const syntaxError = validatePathSyntax(n);
1189
+ if (syntaxError) warnInvalidPath("getValues", n, syntaxError);
1190
+ else {
1191
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, n);
1192
+ if (!schemaResult.valid) warnPathNotInSchema("getValues", n, schemaResult.availableFields);
1193
+ }
1194
+ }
1195
+ }
1001
1196
  syncUncontrolledInputs(ctx.fieldRefs, ctx.fieldOptions, ctx.formData);
1002
1197
  if (nameOrNames === void 0) return { ...ctx.formData };
1003
1198
  if (Array.isArray(nameOrNames)) {
@@ -1008,6 +1203,14 @@ function useForm(options) {
1008
1203
  return get(ctx.formData, nameOrNames);
1009
1204
  }
1010
1205
  function getFieldState(name) {
1206
+ if (__DEV__) {
1207
+ const syntaxError = validatePathSyntax(name);
1208
+ if (syntaxError) warnInvalidPath("getFieldState", name, syntaxError);
1209
+ else {
1210
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, name);
1211
+ if (!schemaResult.valid) warnPathNotInSchema("getFieldState", name, schemaResult.availableFields);
1212
+ }
1213
+ }
1011
1214
  const error = get(ctx.errors.value, name);
1012
1215
  return {
1013
1216
  isDirty: ctx.dirtyFields.value[name] === true,
@@ -1017,6 +1220,17 @@ function useForm(options) {
1017
1220
  };
1018
1221
  }
1019
1222
  async function trigger(name) {
1223
+ if (__DEV__ && name) {
1224
+ const names = Array.isArray(name) ? name : [name];
1225
+ for (const n of names) {
1226
+ const syntaxError = validatePathSyntax(n);
1227
+ if (syntaxError) warnInvalidPath("trigger", n, syntaxError);
1228
+ else {
1229
+ const schemaResult = validatePathAgainstSchema(ctx.options.schema, n);
1230
+ if (!schemaResult.valid) warnPathNotInSchema("trigger", n, schemaResult.availableFields);
1231
+ }
1232
+ }
1233
+ }
1020
1234
  if (name === void 0) return await validate();
1021
1235
  if (Array.isArray(name)) {
1022
1236
  let allValid = true;
@@ -52,7 +52,7 @@ function generateId() {
52
52
  const random = Math.random().toString(36).substring(2, 11);
53
53
  return `field_${Date.now()}_${idCounter++}_${random}`;
54
54
  }
55
- const __DEV__ = typeof import.meta !== "undefined" && false;
55
+ const __DEV__ = globalThis.process?.env?.NODE_ENV !== "production";
56
56
  var warnedMessages = /* @__PURE__ */ new Set();
57
57
  function warnOnce(message, key) {
58
58
  if (!__DEV__) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuehookform/core",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "TypeScript-first form library for Vue 3, inspired by React Hook Form. Form-level state management with Zod validation.",
5
5
  "type": "module",
6
6
  "main": "./dist/vuehookform.cjs",
@@ -21,22 +21,19 @@
21
21
  "node": "^20.19.0 || >=22.12.0"
22
22
  },
23
23
  "scripts": {
24
- "dev": "vite",
25
- "build": "run-p type-check \"build-only {@}\" --",
26
- "build:lib": "run-p type-check build-lib-only",
27
- "build-lib-only": "vite build --config vite.config.lib.ts",
28
- "preview": "vite preview",
29
- "build-only": "vite build",
24
+ "build:lib": "vite build --config vite.config.lib.ts",
25
+ "build": "run-p type-check build:lib",
26
+ "docs": "vitepress dev docs",
27
+ "docs:build": "vitepress build docs",
28
+ "docs:preview": "vitepress preview docs",
30
29
  "type-check": "vue-tsc --build",
31
30
  "lint:oxlint": "oxlint . --fix -D correctness --ignore-path .gitignore",
32
31
  "lint:eslint": "eslint . --fix --cache",
33
32
  "lint": "run-s lint:*",
34
- "format": "prettier --write --experimental-cli src/ tests/",
33
+ "format": "prettier --write --experimental-cli lib/ docs/",
35
34
  "test": "vitest",
36
35
  "test:run": "vitest run",
37
36
  "test:coverage": "vitest run --coverage",
38
- "prepublishOnly": "npm run build:lib",
39
- "postversion": "git push && git push --tags",
40
37
  "prepare": "husky"
41
38
  },
42
39
  "repository": {
@@ -70,7 +67,6 @@
70
67
  },
71
68
  "devDependencies": {
72
69
  "@prettier/plugin-oxc": "^0.0.5",
73
- "@tailwindcss/vite": "^4.1.18",
74
70
  "@tsconfig/node24": "^24.0.3",
75
71
  "@types/node": "^24.10.1",
76
72
  "@vitejs/plugin-vue": "^6.0.2",
@@ -85,20 +81,16 @@
85
81
  "husky": "^9.1.7",
86
82
  "jiti": "^2.6.1",
87
83
  "lint-staged": "^16.2.7",
88
- "material-icons": "^1.13.14",
89
- "material-symbols": "^0.40.2",
90
84
  "npm-run-all2": "^8.0.4",
85
+ "oxc-minify": "^0.105.0",
91
86
  "oxlint": "~1.29.0",
92
- "pinia": "^3.0.4",
93
87
  "prettier": "3.6.2",
94
- "tailwindcss": "^4.1.18",
95
88
  "typescript": "~5.9.0",
96
89
  "vite": "npm:rolldown-vite@latest",
97
- "vite-plugin-compression2": "^2.4.0",
98
90
  "vite-plugin-dts": "^4.5.4",
91
+ "vitepress": "^2.0.0-alpha.15",
99
92
  "vitest": "^4.0.16",
100
93
  "vue": "^3.5.25",
101
- "vue-router": "^4.6.3",
102
94
  "vue-tsc": "^3.1.5",
103
95
  "zod": "^4.2.1"
104
96
  },