@inertiajs/vue3 2.2.21 → 2.3.1

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/index.js CHANGED
@@ -97,16 +97,17 @@ var remember_default = remember;
97
97
 
98
98
  // src/useForm.ts
99
99
  var import_core2 = require("@inertiajs/core");
100
+ var import_laravel_precognition = require("laravel-precognition");
100
101
  var import_lodash_es2 = require("lodash-es");
101
102
  var import_vue = require("vue");
102
- function useForm(rememberKeyOrData, maybeData) {
103
- const rememberKey = typeof rememberKeyOrData === "string" ? rememberKeyOrData : null;
104
- const data = (typeof rememberKeyOrData === "string" ? maybeData : rememberKeyOrData) ?? {};
103
+ function useForm(...args) {
104
+ let { rememberKey, data, precognitionEndpoint } = import_core2.UseFormUtils.parseUseFormArguments(...args);
105
105
  const restored = rememberKey ? import_core2.router.restore(rememberKey) : null;
106
106
  let defaults = typeof data === "function" ? (0, import_lodash_es2.cloneDeep)(data()) : (0, import_lodash_es2.cloneDeep)(data);
107
107
  let cancelToken = null;
108
108
  let recentlySuccessfulTimeoutId;
109
109
  let transform = (data2) => data2;
110
+ let validatorRef = null;
110
111
  let defaultsCalledInOnSuccess = false;
111
112
  const form = (0, import_vue.reactive)({
112
113
  ...restored ? restored.data : (0, import_lodash_es2.cloneDeep)(defaults),
@@ -117,6 +118,76 @@ function useForm(rememberKeyOrData, maybeData) {
117
118
  progress: null,
118
119
  wasSuccessful: false,
119
120
  recentlySuccessful: false,
121
+ withPrecognition(...args2) {
122
+ precognitionEndpoint = import_core2.UseFormUtils.createWayfinderCallback(...args2);
123
+ const formWithPrecognition = this;
124
+ let withAllErrors = false;
125
+ const validator = (0, import_laravel_precognition.createValidator)((client) => {
126
+ const { method, url } = precognitionEndpoint();
127
+ const transformedData = (0, import_lodash_es2.cloneDeep)(transform(this.data()));
128
+ return client[method](url, transformedData);
129
+ }, (0, import_lodash_es2.cloneDeep)(defaults));
130
+ validatorRef = validator;
131
+ validator.on("validatingChanged", () => {
132
+ formWithPrecognition.validating = validator.validating();
133
+ }).on("validatedChanged", () => {
134
+ formWithPrecognition.__valid = validator.valid();
135
+ }).on("touchedChanged", () => {
136
+ formWithPrecognition.__touched = validator.touched();
137
+ }).on("errorsChanged", () => {
138
+ const validationErrors = withAllErrors ? validator.errors() : (0, import_laravel_precognition.toSimpleValidationErrors)(validator.errors());
139
+ this.errors = {};
140
+ this.setError(validationErrors);
141
+ formWithPrecognition.__valid = validator.valid();
142
+ });
143
+ const tap = (value, callback) => {
144
+ callback(value);
145
+ return value;
146
+ };
147
+ Object.assign(formWithPrecognition, {
148
+ __touched: [],
149
+ __valid: [],
150
+ validating: false,
151
+ validator: () => validator,
152
+ withAllErrors: () => tap(formWithPrecognition, () => withAllErrors = true),
153
+ valid: (field) => formWithPrecognition.__valid.includes(field),
154
+ invalid: (field) => field in this.errors,
155
+ setValidationTimeout: (duration) => tap(formWithPrecognition, () => validator.setTimeout(duration)),
156
+ validateFiles: () => tap(formWithPrecognition, () => validator.validateFiles()),
157
+ withoutFileValidation: () => tap(formWithPrecognition, () => validator.withoutFileValidation()),
158
+ touch: (field, ...fields) => {
159
+ if (Array.isArray(field)) {
160
+ validator.touch(field);
161
+ } else if (typeof field === "string") {
162
+ validator.touch([field, ...fields]);
163
+ } else {
164
+ validator.touch(field);
165
+ }
166
+ return formWithPrecognition;
167
+ },
168
+ touched: (field) => typeof field === "string" ? formWithPrecognition.__touched.includes(field) : formWithPrecognition.__touched.length > 0,
169
+ validate: (field, config2) => {
170
+ if (typeof field === "object" && !("target" in field)) {
171
+ config2 = field;
172
+ field = void 0;
173
+ }
174
+ if (field === void 0) {
175
+ validator.validate(config2);
176
+ } else {
177
+ const fieldName = (0, import_laravel_precognition.resolveName)(field);
178
+ const transformedData = transform(this.data());
179
+ validator.validate(fieldName, (0, import_lodash_es2.get)(transformedData, fieldName), config2);
180
+ }
181
+ return formWithPrecognition;
182
+ },
183
+ setErrors: (errors) => tap(formWithPrecognition, () => this.setError(errors)),
184
+ forgetError: (field) => tap(
185
+ formWithPrecognition,
186
+ () => this.clearErrors((0, import_laravel_precognition.resolveName)(field))
187
+ )
188
+ });
189
+ return formWithPrecognition;
190
+ },
120
191
  data() {
121
192
  return Object.keys(defaults).reduce((carry, key2) => {
122
193
  return (0, import_lodash_es2.set)(carry, key2, (0, import_lodash_es2.get)(this, key2));
@@ -137,6 +208,7 @@ function useForm(rememberKeyOrData, maybeData) {
137
208
  } else {
138
209
  defaults = typeof fieldOrFields === "string" ? (0, import_lodash_es2.set)((0, import_lodash_es2.cloneDeep)(defaults), fieldOrFields, maybeValue) : Object.assign({}, (0, import_lodash_es2.cloneDeep)(defaults), fieldOrFields);
139
210
  }
211
+ validatorRef?.defaults(defaults);
140
212
  return this;
141
213
  },
142
214
  reset(...fields) {
@@ -152,11 +224,14 @@ function useForm(rememberKeyOrData, maybeData) {
152
224
  (0, import_lodash_es2.set)(this, key2, (0, import_lodash_es2.get)(resolvedData, key2));
153
225
  });
154
226
  }
227
+ validatorRef?.reset(...fields);
155
228
  return this;
156
229
  },
157
230
  setError(fieldOrFields, maybeValue) {
158
- Object.assign(this.errors, typeof fieldOrFields === "string" ? { [fieldOrFields]: maybeValue } : fieldOrFields);
231
+ const errors = typeof fieldOrFields === "string" ? { [fieldOrFields]: maybeValue } : fieldOrFields;
232
+ Object.assign(this.errors, errors);
159
233
  this.hasErrors = Object.keys(this.errors).length > 0;
234
+ validatorRef?.setErrors(errors);
160
235
  return this;
161
236
  },
162
237
  clearErrors(...fields) {
@@ -168,6 +243,13 @@ function useForm(rememberKeyOrData, maybeData) {
168
243
  {}
169
244
  );
170
245
  this.hasErrors = Object.keys(this.errors).length > 0;
246
+ if (validatorRef) {
247
+ if (fields.length === 0) {
248
+ validatorRef.setErrors({});
249
+ } else {
250
+ fields.forEach(validatorRef.forgetError);
251
+ }
252
+ }
171
253
  return this;
172
254
  },
173
255
  resetAndClearErrors(...fields) {
@@ -175,11 +257,8 @@ function useForm(rememberKeyOrData, maybeData) {
175
257
  this.clearErrors(...fields);
176
258
  return this;
177
259
  },
178
- submit(...args) {
179
- const objectPassed = args[0] !== null && typeof args[0] === "object";
180
- const method = objectPassed ? args[0].method : args[0];
181
- const url = objectPassed ? args[0].url : args[1];
182
- const options = (objectPassed ? args[1] : args[2]) ?? {};
260
+ submit(...args2) {
261
+ const { method, url, options } = import_core2.UseFormUtils.parseSubmitArguments(args2, precognitionEndpoint);
183
262
  defaultsCalledInOnSuccess = false;
184
263
  const _options = {
185
264
  ...options,
@@ -204,7 +283,7 @@ function useForm(rememberKeyOrData, maybeData) {
204
283
  }
205
284
  },
206
285
  onProgress: (event) => {
207
- this.progress = event;
286
+ this.progress = event ?? null;
208
287
  if (options.onProgress) {
209
288
  return options.onProgress(event);
210
289
  }
@@ -286,17 +365,18 @@ function useForm(rememberKeyOrData, maybeData) {
286
365
  this.setError(restored2.errors);
287
366
  }
288
367
  });
368
+ const typedForm = form;
289
369
  (0, import_vue.watch)(
290
- form,
370
+ typedForm,
291
371
  (newValue) => {
292
- form.isDirty = !(0, import_lodash_es2.isEqual)(form.data(), defaults);
372
+ typedForm.isDirty = !(0, import_lodash_es2.isEqual)(typedForm.data(), defaults);
293
373
  if (rememberKey) {
294
374
  import_core2.router.remember((0, import_lodash_es2.cloneDeep)(newValue.__remember()), rememberKey);
295
375
  }
296
376
  },
297
377
  { immediate: true, deep: true }
298
378
  );
299
- return form;
379
+ return precognitionEndpoint ? typedForm.withPrecognition(precognitionEndpoint) : typedForm;
300
380
  }
301
381
 
302
382
  // src/app.ts
@@ -466,7 +546,7 @@ async function createInertiaApp({
466
546
  (0, import_vue3.h)("script", {
467
547
  "data-page": id,
468
548
  type: "application/json",
469
- innerHTML: JSON.stringify(initialPage)
549
+ innerHTML: JSON.stringify(initialPage).replace(/\//g, "\\/")
470
550
  }),
471
551
  (0, import_vue3.h)("div", {
472
552
  id,
@@ -598,10 +678,35 @@ var Form = (0, import_vue5.defineComponent)({
598
678
  invalidateCacheTags: {
599
679
  type: [String, Array],
600
680
  default: () => []
681
+ },
682
+ validateFiles: {
683
+ type: Boolean,
684
+ default: false
685
+ },
686
+ validationTimeout: {
687
+ type: Number,
688
+ default: 1500
689
+ },
690
+ withAllErrors: {
691
+ type: Boolean,
692
+ default: false
601
693
  }
602
694
  },
603
695
  setup(props, { slots, attrs, expose }) {
604
- const form = useForm({});
696
+ const getTransformedData = () => {
697
+ const [_url, data] = getUrlAndData();
698
+ return props.transform(data);
699
+ };
700
+ const form = useForm({}).withPrecognition(
701
+ () => method.value,
702
+ () => getUrlAndData()[0]
703
+ ).transform(getTransformedData).setValidationTimeout(props.validationTimeout);
704
+ if (props.validateFiles) {
705
+ form.validateFiles();
706
+ }
707
+ if (props.withAllErrors) {
708
+ form.withAllErrors();
709
+ }
605
710
  const formElement = (0, import_vue5.ref)();
606
711
  const method = (0, import_vue5.computed)(
607
712
  () => (0, import_core5.isUrlMethodPair)(props.action) ? props.action.method : props.method.toLowerCase()
@@ -614,18 +719,29 @@ var Form = (0, import_vue5.defineComponent)({
614
719
  const formEvents = ["input", "change", "reset"];
615
720
  (0, import_vue5.onMounted)(() => {
616
721
  defaultData.value = getFormData();
722
+ form.defaults(getData());
617
723
  formEvents.forEach((e) => formElement.value.addEventListener(e, onFormUpdate));
618
724
  });
725
+ (0, import_vue5.watch)(
726
+ () => props.validateFiles,
727
+ (value) => value ? form.validateFiles() : form.withoutFileValidation()
728
+ );
729
+ (0, import_vue5.watch)(
730
+ () => props.validationTimeout,
731
+ (value) => form.setValidationTimeout(value)
732
+ );
619
733
  (0, import_vue5.onBeforeUnmount)(() => formEvents.forEach((e) => formElement.value?.removeEventListener(e, onFormUpdate)));
620
734
  const getFormData = () => new FormData(formElement.value);
621
735
  const getData = () => (0, import_core5.formDataToObject)(getFormData());
622
- const submit = () => {
623
- const [action, data] = (0, import_core5.mergeDataIntoQueryString)(
736
+ const getUrlAndData = () => {
737
+ return (0, import_core5.mergeDataIntoQueryString)(
624
738
  method.value,
625
739
  (0, import_core5.isUrlMethodPair)(props.action) ? props.action.url : props.action,
626
740
  getData(),
627
741
  props.queryStringArrayFormat
628
742
  );
743
+ };
744
+ const submit = () => {
629
745
  const maybeReset = (resetOption) => {
630
746
  if (!resetOption) {
631
747
  return;
@@ -662,13 +778,18 @@ var Form = (0, import_vue5.defineComponent)({
662
778
  },
663
779
  ...props.options
664
780
  };
665
- form.transform(() => props.transform(data)).submit(method.value, action, submitOptions);
781
+ const [url, data] = getUrlAndData();
782
+ form.transform(() => props.transform(data)).submit(method.value, url, submitOptions);
666
783
  };
667
784
  const reset = (...fields) => {
668
785
  (0, import_core5.resetFormFields)(formElement.value, defaultData.value, fields);
786
+ form.reset(...fields);
669
787
  };
670
- const resetAndClearErrors = (...fields) => {
788
+ const clearErrors = (...fields) => {
671
789
  form.clearErrors(...fields);
790
+ };
791
+ const resetAndClearErrors = (...fields) => {
792
+ clearErrors(...fields);
672
793
  reset(...fields);
673
794
  };
674
795
  const defaults = () => {
@@ -694,7 +815,10 @@ var Form = (0, import_vue5.defineComponent)({
694
815
  get recentlySuccessful() {
695
816
  return form.recentlySuccessful;
696
817
  },
697
- clearErrors: (...fields) => form.clearErrors(...fields),
818
+ get validating() {
819
+ return form.validating;
820
+ },
821
+ clearErrors,
698
822
  resetAndClearErrors,
699
823
  setError: (fieldOrFields, maybeValue) => form.setError(typeof fieldOrFields === "string" ? { [fieldOrFields]: maybeValue } : fieldOrFields),
700
824
  get isDirty() {
@@ -704,7 +828,14 @@ var Form = (0, import_vue5.defineComponent)({
704
828
  submit,
705
829
  defaults,
706
830
  getData,
707
- getFormData
831
+ getFormData,
832
+ // Precognition
833
+ touch: form.touch,
834
+ valid: form.valid,
835
+ invalid: form.invalid,
836
+ touched: form.touched,
837
+ validate: (field, config2) => form.validate(...import_core5.UseFormUtils.mergeHeadersForValidation(field, config2, props.headers)),
838
+ validator: () => form.validator()
708
839
  };
709
840
  expose(exposed);
710
841
  return () => {
@@ -1494,21 +1625,21 @@ var whenVisible_default = (0, import_vue12.defineComponent)({
1494
1625
  unmounted() {
1495
1626
  this.observer?.disconnect();
1496
1627
  },
1628
+ computed: {
1629
+ keys() {
1630
+ return this.data ? Array.isArray(this.data) ? this.data : [this.data] : [];
1631
+ }
1632
+ },
1497
1633
  created() {
1498
1634
  const page2 = usePage();
1499
1635
  this.$watch(
1636
+ () => this.keys.map((key2) => page2.props[key2]),
1500
1637
  () => {
1501
- return Array.isArray(this.data) ? this.data.map((data) => page2.props[data]) : page2.props[this.data];
1502
- },
1503
- (value) => {
1504
- if (Array.isArray(this.data)) {
1505
- if (this.data.every((data) => page2.props[data] !== void 0)) {
1506
- return;
1507
- }
1508
- } else if (value !== void 0) {
1638
+ const exists = this.keys.length > 0 && this.keys.every((key2) => page2.props[key2] !== void 0);
1639
+ this.loaded = exists;
1640
+ if (exists && !this.always) {
1509
1641
  return;
1510
1642
  }
1511
- this.loaded = false;
1512
1643
  this.$nextTick(this.registerObserver);
1513
1644
  },
1514
1645
  { immediate: true }