quival 0.4.2 → 0.5.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/README.md CHANGED
@@ -29,7 +29,7 @@ There are 2 ways to start using `quival` in your project.
29
29
  Get the script from [jsDelivr CDN page](https://www.jsdelivr.com/package/npm/quival) and include it in your HTML page.
30
30
 
31
31
  ```html
32
- <script src="https://cdn.jsdelivr.net/npm/quival@0.4.x/dist/quival.min.js"></script>
32
+ <script src="https://cdn.jsdelivr.net/npm/quival@0.5.x/dist/quival.min.js"></script>
33
33
  ```
34
34
 
35
35
  Extract `Validator` class from `quival` global variable, and you are good to go.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * quival v0.4.2 (https://github.com/apih/quival)
2
+ * quival v0.5.1 (https://github.com/apih/quival)
3
3
  * (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
4
4
  * Released under the MIT License.
5
5
  */
@@ -46,6 +46,7 @@ this.quival.locales.en = (function () {
46
46
  digits_between: 'The :attribute field must be between :min and :max digits.',
47
47
  dimensions: 'The :attribute field has invalid image dimensions.',
48
48
  distinct: 'The :attribute field has a duplicate value.',
49
+ doesnt_contain: 'The :attribute field must not contain any of the following: :values.',
49
50
  doesnt_end_with: 'The :attribute field must not end with one of the following: :values.',
50
51
  doesnt_start_with: 'The :attribute field must not start with one of the following: :values.',
51
52
  email: 'The :attribute field must be a valid email address.',
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * quival v0.4.2 (https://github.com/apih/quival)
2
+ * quival v0.5.1 (https://github.com/apih/quival)
3
3
  * (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
4
4
  * Released under the MIT License.
5
5
  */
6
- this.quival=this.quival||{},this.quival.locales=this.quival.locales||{},this.quival.locales.en=function(){"use strict";return{accepted:"The :attribute field must be accepted.",accepted_if:"The :attribute field must be accepted when :other is :value.",active_url:"The :attribute field must be a valid URL.",after:"The :attribute field must be a date after :date.",after_or_equal:"The :attribute field must be a date after or equal to :date.",alpha:"The :attribute field must only contain letters.",alpha_dash:"The :attribute field must only contain letters, numbers, dashes, and underscores.",alpha_num:"The :attribute field must only contain letters and numbers.",array:"The :attribute field must be an array.",ascii:"The :attribute field must only contain single-byte alphanumeric characters and symbols.",before:"The :attribute field must be a date before :date.",before_or_equal:"The :attribute field must be a date before or equal to :date.",between:{array:"The :attribute field must have between :min and :max items.",file:"The :attribute field must be between :min and :max kilobytes.",numeric:"The :attribute field must be between :min and :max.",string:"The :attribute field must be between :min and :max characters."},boolean:"The :attribute field must be true or false.",can:"The :attribute field contains an unauthorized value.",confirmed:"The :attribute field confirmation does not match.",contains:"The :attribute field is missing a required value.",current_password:"The password is incorrect.",date:"The :attribute field must be a valid date.",date_equals:"The :attribute field must be a date equal to :date.",date_format:"The :attribute field must match the format :format.",decimal:"The :attribute field must have :decimal decimal places.",declined:"The :attribute field must be declined.",declined_if:"The :attribute field must be declined when :other is :value.",different:"The :attribute field and :other must be different.",digits:"The :attribute field must be :digits digits.",digits_between:"The :attribute field must be between :min and :max digits.",dimensions:"The :attribute field has invalid image dimensions.",distinct:"The :attribute field has a duplicate value.",doesnt_end_with:"The :attribute field must not end with one of the following: :values.",doesnt_start_with:"The :attribute field must not start with one of the following: :values.",email:"The :attribute field must be a valid email address.",ends_with:"The :attribute field must end with one of the following: :values.",enum:"The selected :attribute is invalid.",exists:"The selected :attribute is invalid.",extensions:"The :attribute field must have one of the following extensions: :values.",file:"The :attribute field must be a file.",filled:"The :attribute field must have a value.",gt:{array:"The :attribute field must have more than :value items.",file:"The :attribute field must be greater than :value kilobytes.",numeric:"The :attribute field must be greater than :value.",string:"The :attribute field must be greater than :value characters."},gte:{array:"The :attribute field must have :value items or more.",file:"The :attribute field must be greater than or equal to :value kilobytes.",numeric:"The :attribute field must be greater than or equal to :value.",string:"The :attribute field must be greater than or equal to :value characters."},hex_color:"The :attribute field must be a valid hexadecimal color.",image:"The :attribute field must be an image.",in:"The selected :attribute is invalid.",in_array:"The :attribute field must exist in :other.",integer:"The :attribute field must be an integer.",ip:"The :attribute field must be a valid IP address.",ipv4:"The :attribute field must be a valid IPv4 address.",ipv6:"The :attribute field must be a valid IPv6 address.",json:"The :attribute field must be a valid JSON string.",list:"The :attribute field must be a list.",lowercase:"The :attribute field must be lowercase.",lt:{array:"The :attribute field must have less than :value items.",file:"The :attribute field must be less than :value kilobytes.",numeric:"The :attribute field must be less than :value.",string:"The :attribute field must be less than :value characters."},lte:{array:"The :attribute field must not have more than :value items.",file:"The :attribute field must be less than or equal to :value kilobytes.",numeric:"The :attribute field must be less than or equal to :value.",string:"The :attribute field must be less than or equal to :value characters."},mac_address:"The :attribute field must be a valid MAC address.",max:{array:"The :attribute field must not have more than :max items.",file:"The :attribute field must not be greater than :max kilobytes.",numeric:"The :attribute field must not be greater than :max.",string:"The :attribute field must not be greater than :max characters."},max_digits:"The :attribute field must not have more than :max digits.",mimes:"The :attribute field must be a file of type: :values.",mimetypes:"The :attribute field must be a file of type: :values.",min:{array:"The :attribute field must have at least :min items.",file:"The :attribute field must be at least :min kilobytes.",numeric:"The :attribute field must be at least :min.",string:"The :attribute field must be at least :min characters."},min_digits:"The :attribute field must have at least :min digits.",missing:"The :attribute field must be missing.",missing_if:"The :attribute field must be missing when :other is :value.",missing_unless:"The :attribute field must be missing unless :other is :value.",missing_with:"The :attribute field must be missing when :values is present.",missing_with_all:"The :attribute field must be missing when :values are present.",multiple_of:"The :attribute field must be a multiple of :value.",not_in:"The selected :attribute is invalid.",not_regex:"The :attribute field format is invalid.",numeric:"The :attribute field must be a number.",password:{letters:"The :attribute field must contain at least one letter.",mixed:"The :attribute field must contain at least one uppercase and one lowercase letter.",numbers:"The :attribute field must contain at least one number.",symbols:"The :attribute field must contain at least one symbol.",uncompromised:"The given :attribute has appeared in a data leak. Please choose a different :attribute."},present:"The :attribute field must be present.",prohibited:"The :attribute field is prohibited.",prohibited_if:"The :attribute field is prohibited when :other is :value.",prohibited_unless:"The :attribute field is prohibited unless :other is in :values.",prohibits:"The :attribute field prohibits :other from being present.",regex:"The :attribute field format is invalid.",required:"The :attribute field is required.",required_array_keys:"The :attribute field must contain entries for: :values.",required_if:"The :attribute field is required when :other is :value.",required_if_accepted:"The :attribute field is required when :other is accepted.",required_if_declined:"The :attribute field is required when :other is declined.",required_unless:"The :attribute field is required unless :other is in :values.",required_with:"The :attribute field is required when :values is present.",required_with_all:"The :attribute field is required when :values are present.",required_without:"The :attribute field is required when :values is not present.",required_without_all:"The :attribute field is required when none of :values are present.",same:"The :attribute field must match :other.",size:{array:"The :attribute field must contain :size items.",file:"The :attribute field must be :size kilobytes.",numeric:"The :attribute field must be :size.",string:"The :attribute field must be :size characters."},starts_with:"The :attribute field must start with one of the following: :values.",string:"The :attribute field must be a string.",timezone:"The :attribute field must be a valid timezone.",unique:"The :attribute has already been taken.",uploaded:"The :attribute failed to upload.",uppercase:"The :attribute field must be uppercase.",url:"The :attribute field must be a valid URL.",ulid:"The :attribute field must be a valid ULID.",uuid:"The :attribute field must be a valid UUID.",custom:{"attribute-name":{"rule-name":"custom-message"}},attributes:{},values:{}}}();
6
+ this.quival=this.quival||{},this.quival.locales=this.quival.locales||{},this.quival.locales.en=function(){"use strict";return{accepted:"The :attribute field must be accepted.",accepted_if:"The :attribute field must be accepted when :other is :value.",active_url:"The :attribute field must be a valid URL.",after:"The :attribute field must be a date after :date.",after_or_equal:"The :attribute field must be a date after or equal to :date.",alpha:"The :attribute field must only contain letters.",alpha_dash:"The :attribute field must only contain letters, numbers, dashes, and underscores.",alpha_num:"The :attribute field must only contain letters and numbers.",array:"The :attribute field must be an array.",ascii:"The :attribute field must only contain single-byte alphanumeric characters and symbols.",before:"The :attribute field must be a date before :date.",before_or_equal:"The :attribute field must be a date before or equal to :date.",between:{array:"The :attribute field must have between :min and :max items.",file:"The :attribute field must be between :min and :max kilobytes.",numeric:"The :attribute field must be between :min and :max.",string:"The :attribute field must be between :min and :max characters."},boolean:"The :attribute field must be true or false.",can:"The :attribute field contains an unauthorized value.",confirmed:"The :attribute field confirmation does not match.",contains:"The :attribute field is missing a required value.",current_password:"The password is incorrect.",date:"The :attribute field must be a valid date.",date_equals:"The :attribute field must be a date equal to :date.",date_format:"The :attribute field must match the format :format.",decimal:"The :attribute field must have :decimal decimal places.",declined:"The :attribute field must be declined.",declined_if:"The :attribute field must be declined when :other is :value.",different:"The :attribute field and :other must be different.",digits:"The :attribute field must be :digits digits.",digits_between:"The :attribute field must be between :min and :max digits.",dimensions:"The :attribute field has invalid image dimensions.",distinct:"The :attribute field has a duplicate value.",doesnt_contain:"The :attribute field must not contain any of the following: :values.",doesnt_end_with:"The :attribute field must not end with one of the following: :values.",doesnt_start_with:"The :attribute field must not start with one of the following: :values.",email:"The :attribute field must be a valid email address.",ends_with:"The :attribute field must end with one of the following: :values.",enum:"The selected :attribute is invalid.",exists:"The selected :attribute is invalid.",extensions:"The :attribute field must have one of the following extensions: :values.",file:"The :attribute field must be a file.",filled:"The :attribute field must have a value.",gt:{array:"The :attribute field must have more than :value items.",file:"The :attribute field must be greater than :value kilobytes.",numeric:"The :attribute field must be greater than :value.",string:"The :attribute field must be greater than :value characters."},gte:{array:"The :attribute field must have :value items or more.",file:"The :attribute field must be greater than or equal to :value kilobytes.",numeric:"The :attribute field must be greater than or equal to :value.",string:"The :attribute field must be greater than or equal to :value characters."},hex_color:"The :attribute field must be a valid hexadecimal color.",image:"The :attribute field must be an image.",in:"The selected :attribute is invalid.",in_array:"The :attribute field must exist in :other.",integer:"The :attribute field must be an integer.",ip:"The :attribute field must be a valid IP address.",ipv4:"The :attribute field must be a valid IPv4 address.",ipv6:"The :attribute field must be a valid IPv6 address.",json:"The :attribute field must be a valid JSON string.",list:"The :attribute field must be a list.",lowercase:"The :attribute field must be lowercase.",lt:{array:"The :attribute field must have less than :value items.",file:"The :attribute field must be less than :value kilobytes.",numeric:"The :attribute field must be less than :value.",string:"The :attribute field must be less than :value characters."},lte:{array:"The :attribute field must not have more than :value items.",file:"The :attribute field must be less than or equal to :value kilobytes.",numeric:"The :attribute field must be less than or equal to :value.",string:"The :attribute field must be less than or equal to :value characters."},mac_address:"The :attribute field must be a valid MAC address.",max:{array:"The :attribute field must not have more than :max items.",file:"The :attribute field must not be greater than :max kilobytes.",numeric:"The :attribute field must not be greater than :max.",string:"The :attribute field must not be greater than :max characters."},max_digits:"The :attribute field must not have more than :max digits.",mimes:"The :attribute field must be a file of type: :values.",mimetypes:"The :attribute field must be a file of type: :values.",min:{array:"The :attribute field must have at least :min items.",file:"The :attribute field must be at least :min kilobytes.",numeric:"The :attribute field must be at least :min.",string:"The :attribute field must be at least :min characters."},min_digits:"The :attribute field must have at least :min digits.",missing:"The :attribute field must be missing.",missing_if:"The :attribute field must be missing when :other is :value.",missing_unless:"The :attribute field must be missing unless :other is :value.",missing_with:"The :attribute field must be missing when :values is present.",missing_with_all:"The :attribute field must be missing when :values are present.",multiple_of:"The :attribute field must be a multiple of :value.",not_in:"The selected :attribute is invalid.",not_regex:"The :attribute field format is invalid.",numeric:"The :attribute field must be a number.",password:{letters:"The :attribute field must contain at least one letter.",mixed:"The :attribute field must contain at least one uppercase and one lowercase letter.",numbers:"The :attribute field must contain at least one number.",symbols:"The :attribute field must contain at least one symbol.",uncompromised:"The given :attribute has appeared in a data leak. Please choose a different :attribute."},present:"The :attribute field must be present.",prohibited:"The :attribute field is prohibited.",prohibited_if:"The :attribute field is prohibited when :other is :value.",prohibited_unless:"The :attribute field is prohibited unless :other is in :values.",prohibits:"The :attribute field prohibits :other from being present.",regex:"The :attribute field format is invalid.",required:"The :attribute field is required.",required_array_keys:"The :attribute field must contain entries for: :values.",required_if:"The :attribute field is required when :other is :value.",required_if_accepted:"The :attribute field is required when :other is accepted.",required_if_declined:"The :attribute field is required when :other is declined.",required_unless:"The :attribute field is required unless :other is in :values.",required_with:"The :attribute field is required when :values is present.",required_with_all:"The :attribute field is required when :values are present.",required_without:"The :attribute field is required when :values is not present.",required_without_all:"The :attribute field is required when none of :values are present.",same:"The :attribute field must match :other.",size:{array:"The :attribute field must contain :size items.",file:"The :attribute field must be :size kilobytes.",numeric:"The :attribute field must be :size.",string:"The :attribute field must be :size characters."},starts_with:"The :attribute field must start with one of the following: :values.",string:"The :attribute field must be a string.",timezone:"The :attribute field must be a valid timezone.",unique:"The :attribute has already been taken.",uploaded:"The :attribute failed to upload.",uppercase:"The :attribute field must be uppercase.",url:"The :attribute field must be a valid URL.",ulid:"The :attribute field must be a valid ULID.",uuid:"The :attribute field must be a valid UUID.",custom:{"attribute-name":{"rule-name":"custom-message"}},attributes:{},values:{}}}();
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * quival v0.4.2 (https://github.com/apih/quival)
2
+ * quival v0.5.1 (https://github.com/apih/quival)
3
3
  * (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
4
4
  * Released under the MIT License.
5
5
  */
@@ -46,6 +46,7 @@ this.quival.locales.ms = (function () {
46
46
  digits_between: 'Medan :attribute mesti mengandungi antara :min dan :max digit.',
47
47
  dimensions: 'Medan :attribute mempunyai dimensi imej yang tidak sah.',
48
48
  distinct: 'Medan :attribute mempunyai nilai yang berulang.',
49
+ doesnt_contain: 'Medan :attribute tidak boleh mengandungi salah satu daripada berikut: :values.',
49
50
  doesnt_end_with: 'Medan :attribute tidak boleh berakhir dengan salah satu daripada berikut: :values.',
50
51
  doesnt_start_with: 'Medan :attribute tidak boleh bermula dengan salah satu daripada berikut: :values.',
51
52
  email: 'Medan :attribute mesti alamat emel yang sah.',
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * quival v0.4.2 (https://github.com/apih/quival)
2
+ * quival v0.5.1 (https://github.com/apih/quival)
3
3
  * (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
4
4
  * Released under the MIT License.
5
5
  */
6
- this.quival=this.quival||{},this.quival.locales=this.quival.locales||{},this.quival.locales.ms=function(){"use strict";return{accepted:"Medan :attribute mesti diterima.",accepted_if:"Medan :attribute mesti diterima apabila :other ialah :value.",active_url:"Medan :attribute mesti URL yang sah.",after:"Medan :attribute mesti tarikh selepas :date.",after_or_equal:"Medan :attribute mesti tarikh selepas atau sama dengan :date.",alpha:"Medan :attribute hanya boleh mengandungi huruf.",alpha_dash:"Medan :attribute hanya boleh mengandungi huruf, nombor, tanda sengkang, dan garis bawah.",alpha_num:"Medan :attribute hanya boleh mengandungi huruf dan nombor.",array:"Medan :attribute mesti jujukan.",ascii:"Medan :attribute hanya boleh mengandungi abjad, angka dan simbol berjenis bait tunggal.",before:"Medan :attribute mesti tarikh sebelum :date.",before_or_equal:"Medan :attribute mesti tarikh sebelum atau sama dengan :date.",between:{array:"Medan :attribute mesti mempunyai antara :min dan :max item.",file:"Medan :attribute mesti antara :min dan :max kilobait.",numeric:"Medan :attribute mesti antara :min dan :max.",string:"Medan :attribute mesti antara :min dan :max huruf."},boolean:"Medan :attribute mesti benar atau salah.",can:"Medan :attribute field mengandungi nilai yang tidak dibenarkan.",confirmed:"Pengesahan medan :attribute tidak sepadan.",contains:"Medan :attribute tiada nilai yang diperlukan.",current_password:"Kata laluan tidak sah.",date:"Medan :attribute mesti tarikh yang sah.",date_equals:"Medan :attribute mesti bersamaan dengan :date.",date_format:"Medan :attribute mesti sepadan dengan format :format.",decimal:"Medan :attribute mesti mempunyai :decimal tempat perpuluhan.",declined:"Medan :attribute mesti ditolak.",declined_if:"Medan :attribute mesti ditolak apabila :other adalah :value.",different:"Medan :attribute dan :other mesti berbeza.",digits:"Medan :attribute mesti mengandungi :digits digit.",digits_between:"Medan :attribute mesti mengandungi antara :min dan :max digit.",dimensions:"Medan :attribute mempunyai dimensi imej yang tidak sah.",distinct:"Medan :attribute mempunyai nilai yang berulang.",doesnt_end_with:"Medan :attribute tidak boleh berakhir dengan salah satu daripada berikut: :values.",doesnt_start_with:"Medan :attribute tidak boleh bermula dengan salah satu daripada berikut: :values.",email:"Medan :attribute mesti alamat emel yang sah.",ends_with:"Medan :attribute mesti berakhir dengan salah satu daripada berikut: :values.",enum:"Nilai :attribute yang dipilih tidak sah.",exists:"Nilai :attribute yang dipilih tidak sah.",extensions:"Medan :attribute mesti salah satu daripada sambungan berikut: :values.",file:"Medan :attribute mesti fail.",filled:"Medan :attribute mesti mempunyai nilai.",gt:{array:"Medan :attribute mesti mempunyai lebih daripada :value item.",file:"Medan :attribute mesti lebih besar daripada :value kilobait.",numeric:"Medan :attribute mesti lebih besar daripada :value.",string:"Medan :attribute mesti lebih besar daripada :value huruf."},gte:{array:"Medan :attribute mesti mempunyai :value item atau lebih.",file:"Medan :attribute mesti lebih besar daripada atau sama dengan :value kilobait.",numeric:"Medan :attribute mesti lebih besar daripada atau sama dengan :value.",string:"Medan :attribute mesti lebih besar daripada atau sama dengan :value huruf."},hex_color:"Medan :attribute mesti warna heksadesimal yang sah.",image:"Medan :attribute mesti imej.",in:"Nilai :attribute yang dipilih tidak sah.",in_array:"Medan :attribute mesti wujud dalam :other.",integer:"Medan :attribute mesti nombor bulat.",ip:"Medan :attribute mesti alamat IP yang sah.",ipv4:"Medan :attribute mesti alamat IPv4 yang sah.",ipv6:"Medan :attribute mesti alamat IPv6 yang sah.",json:"Medan :attribute mesti rentetan JSON yang sah.",list:"Medan :attribute mesti berbentuk senarai.",lowercase:"Medan :attribute mesti dalam huruf kecil.",lt:{array:"Medan :attribute mesti mempunyai kurang daripada :value item.",file:"Medan :attribute mesti kurang daripada :value kilobait.",numeric:"Medan :attribute mesti kurang daripada :value.",string:"Medan :attribute mesti kurang daripada :value huruf."},lte:{array:"Medan :attribute tidak boleh mempunyai lebih daripada :value item.",file:"Medan :attribute mesti kurang daripada atau sama dengan :value kilobait.",numeric:"Medan :attribute mesti kurang daripada atau sama dengan :value.",string:"Medan :attribute mesti kurang daripada atau sama dengan :value huruf."},mac_address:"Medan :attribute mesti alamat MAC yang sah.",max:{array:"Medan :attribute tidak boleh mempunyai lebih daripada :max item.",file:"Medan :attribute tidak boleh lebih besar daripada :max kilobait.",numeric:"Medan :attribute tidak boleh melebihi :max.",string:"Medan :attribute tidak boleh melebihi :max huruf."},max_digits:"Medan :attribute tidak boleh mempunyai lebih daripada :max digit.",mimes:"Medan :attribute mesti jenis fail: :values.",mimetypes:"Medan :attribute mesti jenis fail: :values.",min:{array:"Medan :attribute mesti mempunyai sekurang-kurangnya :min item.",file:"Medan :attribute mesti sekurang-kurangnya :min kilobait.",numeric:"Medan :attribute mesti sekurang-kurangnya :min.",string:"Medan :attribute mesti sekurang-kurangnya :min huruf."},min_digits:"Medan :attribute mesti mempunyai sekurang-kurangnya :min digit.",missing:"Medan :attribute mesti tiada.",missing_if:"Medan :attribute mesti tiada apabila :other adalah :value.",missing_unless:"Medan :attribute mesti tiada kecuali :other adalah :value.",missing_with:"Medan :attribute mesti tiada apabila :values wujud.",missing_with_all:"Medan :attribute mesti tiada apabila :values wujud.",multiple_of:"Medan :attribute mesti gandaan :value.",not_in:"Nilai :attribute yang dipilih tidak sah.",not_regex:"Format medan :attribute tidak sah.",numeric:"Medan :attribute mesti nombor.",password:{letters:"Medan :attribute mesti mengandungi sekurang-kurangnya satu huruf.",mixed:"Medan :attribute mesti mengandungi sekurang-kurangnya satu huruf besar dan satu huruf kecil.",numbers:"Medan :attribute mesti mengandungi sekurang-kurangnya satu nombor.",symbols:"Medan :attribute mesti mengandungi sekurang-kurangnya satu simbol.",uncompromised:"Nilai :attribute yang diberikan telah muncul dalam kebocoran data. Sila pilih :attribute yang berbeza."},present:"Medan :attribute mesti wujud.",prohibited:"Medan :attribute dilarang.",prohibited_if:"Medan :attribute dilarang apabila :other adalah :value.",prohibited_unless:"Medan :attribute dilarang melainkan :other berada dalam :values.",prohibits:"Medan :attribute melarang :other daripada wujud.",regex:"Format medan :attribute tidak sah.",required:"Medan :attribute diperlukan.",required_array_keys:"Medan :attribute mesti mengandungi entri untuk: :values.",required_if:"Medan :attribute diperlukan apabila :other adalah :value.",required_if_accepted:"Medan :attribute diperlukan apabila :other diterima.",required_if_declined:"Medan :attribute diperlukan apabila :other ditolak.",required_unless:"Medan :attribute diperlukan melainkan :other berada dalam :values.",required_with:"Medan :attribute diperlukan apabila :values wujud.",required_with_all:"Medan :attribute diperlukan apabila semua :values wujud.",required_without:"Medan :attribute diperlukan apabila :values tidak wujud.",required_without_all:"Medan :attribute diperlukan apabila tiada satu pun daripada :values wujud.",same:"Medan :attribute mesti sepadan dengan :other.",size:{array:"Medan :attribute mesti mengandungi :size item.",file:"Medan :attribute mesti :size kilobait.",numeric:"Medan :attribute mesti :size.",string:"Medan :attribute mesti :size huruf."},starts_with:"Medan :attribute mesti bermula dengan salah satu dari berikut: :values.",string:"Medan :attribute mesti perkataan / rentetan aksara.",timezone:"Medan :attribute mesti zon masa yang sah.",unique:"Medan :attribute telah wujud.",uploaded:"Medan :attribute gagal dimuat naik.",uppercase:"Medan :attribute mesti dalam huruf besar.",url:"Medan :attribute mesti URL yang sah.",ulid:"Medan :attribute mesti ULID yang sah.",uuid:"Medan :attribute mesti UUID yang sah.",custom:{"attribute-name":{"rule-name":"custom-message"}},attributes:{},values:{}}}();
6
+ this.quival=this.quival||{},this.quival.locales=this.quival.locales||{},this.quival.locales.ms=function(){"use strict";return{accepted:"Medan :attribute mesti diterima.",accepted_if:"Medan :attribute mesti diterima apabila :other ialah :value.",active_url:"Medan :attribute mesti URL yang sah.",after:"Medan :attribute mesti tarikh selepas :date.",after_or_equal:"Medan :attribute mesti tarikh selepas atau sama dengan :date.",alpha:"Medan :attribute hanya boleh mengandungi huruf.",alpha_dash:"Medan :attribute hanya boleh mengandungi huruf, nombor, tanda sengkang, dan garis bawah.",alpha_num:"Medan :attribute hanya boleh mengandungi huruf dan nombor.",array:"Medan :attribute mesti jujukan.",ascii:"Medan :attribute hanya boleh mengandungi abjad, angka dan simbol berjenis bait tunggal.",before:"Medan :attribute mesti tarikh sebelum :date.",before_or_equal:"Medan :attribute mesti tarikh sebelum atau sama dengan :date.",between:{array:"Medan :attribute mesti mempunyai antara :min dan :max item.",file:"Medan :attribute mesti antara :min dan :max kilobait.",numeric:"Medan :attribute mesti antara :min dan :max.",string:"Medan :attribute mesti antara :min dan :max huruf."},boolean:"Medan :attribute mesti benar atau salah.",can:"Medan :attribute field mengandungi nilai yang tidak dibenarkan.",confirmed:"Pengesahan medan :attribute tidak sepadan.",contains:"Medan :attribute tiada nilai yang diperlukan.",current_password:"Kata laluan tidak sah.",date:"Medan :attribute mesti tarikh yang sah.",date_equals:"Medan :attribute mesti bersamaan dengan :date.",date_format:"Medan :attribute mesti sepadan dengan format :format.",decimal:"Medan :attribute mesti mempunyai :decimal tempat perpuluhan.",declined:"Medan :attribute mesti ditolak.",declined_if:"Medan :attribute mesti ditolak apabila :other adalah :value.",different:"Medan :attribute dan :other mesti berbeza.",digits:"Medan :attribute mesti mengandungi :digits digit.",digits_between:"Medan :attribute mesti mengandungi antara :min dan :max digit.",dimensions:"Medan :attribute mempunyai dimensi imej yang tidak sah.",distinct:"Medan :attribute mempunyai nilai yang berulang.",doesnt_contain:"Medan :attribute tidak boleh mengandungi salah satu daripada berikut: :values.",doesnt_end_with:"Medan :attribute tidak boleh berakhir dengan salah satu daripada berikut: :values.",doesnt_start_with:"Medan :attribute tidak boleh bermula dengan salah satu daripada berikut: :values.",email:"Medan :attribute mesti alamat emel yang sah.",ends_with:"Medan :attribute mesti berakhir dengan salah satu daripada berikut: :values.",enum:"Nilai :attribute yang dipilih tidak sah.",exists:"Nilai :attribute yang dipilih tidak sah.",extensions:"Medan :attribute mesti salah satu daripada sambungan berikut: :values.",file:"Medan :attribute mesti fail.",filled:"Medan :attribute mesti mempunyai nilai.",gt:{array:"Medan :attribute mesti mempunyai lebih daripada :value item.",file:"Medan :attribute mesti lebih besar daripada :value kilobait.",numeric:"Medan :attribute mesti lebih besar daripada :value.",string:"Medan :attribute mesti lebih besar daripada :value huruf."},gte:{array:"Medan :attribute mesti mempunyai :value item atau lebih.",file:"Medan :attribute mesti lebih besar daripada atau sama dengan :value kilobait.",numeric:"Medan :attribute mesti lebih besar daripada atau sama dengan :value.",string:"Medan :attribute mesti lebih besar daripada atau sama dengan :value huruf."},hex_color:"Medan :attribute mesti warna heksadesimal yang sah.",image:"Medan :attribute mesti imej.",in:"Nilai :attribute yang dipilih tidak sah.",in_array:"Medan :attribute mesti wujud dalam :other.",integer:"Medan :attribute mesti nombor bulat.",ip:"Medan :attribute mesti alamat IP yang sah.",ipv4:"Medan :attribute mesti alamat IPv4 yang sah.",ipv6:"Medan :attribute mesti alamat IPv6 yang sah.",json:"Medan :attribute mesti rentetan JSON yang sah.",list:"Medan :attribute mesti berbentuk senarai.",lowercase:"Medan :attribute mesti dalam huruf kecil.",lt:{array:"Medan :attribute mesti mempunyai kurang daripada :value item.",file:"Medan :attribute mesti kurang daripada :value kilobait.",numeric:"Medan :attribute mesti kurang daripada :value.",string:"Medan :attribute mesti kurang daripada :value huruf."},lte:{array:"Medan :attribute tidak boleh mempunyai lebih daripada :value item.",file:"Medan :attribute mesti kurang daripada atau sama dengan :value kilobait.",numeric:"Medan :attribute mesti kurang daripada atau sama dengan :value.",string:"Medan :attribute mesti kurang daripada atau sama dengan :value huruf."},mac_address:"Medan :attribute mesti alamat MAC yang sah.",max:{array:"Medan :attribute tidak boleh mempunyai lebih daripada :max item.",file:"Medan :attribute tidak boleh lebih besar daripada :max kilobait.",numeric:"Medan :attribute tidak boleh melebihi :max.",string:"Medan :attribute tidak boleh melebihi :max huruf."},max_digits:"Medan :attribute tidak boleh mempunyai lebih daripada :max digit.",mimes:"Medan :attribute mesti jenis fail: :values.",mimetypes:"Medan :attribute mesti jenis fail: :values.",min:{array:"Medan :attribute mesti mempunyai sekurang-kurangnya :min item.",file:"Medan :attribute mesti sekurang-kurangnya :min kilobait.",numeric:"Medan :attribute mesti sekurang-kurangnya :min.",string:"Medan :attribute mesti sekurang-kurangnya :min huruf."},min_digits:"Medan :attribute mesti mempunyai sekurang-kurangnya :min digit.",missing:"Medan :attribute mesti tiada.",missing_if:"Medan :attribute mesti tiada apabila :other adalah :value.",missing_unless:"Medan :attribute mesti tiada kecuali :other adalah :value.",missing_with:"Medan :attribute mesti tiada apabila :values wujud.",missing_with_all:"Medan :attribute mesti tiada apabila :values wujud.",multiple_of:"Medan :attribute mesti gandaan :value.",not_in:"Nilai :attribute yang dipilih tidak sah.",not_regex:"Format medan :attribute tidak sah.",numeric:"Medan :attribute mesti nombor.",password:{letters:"Medan :attribute mesti mengandungi sekurang-kurangnya satu huruf.",mixed:"Medan :attribute mesti mengandungi sekurang-kurangnya satu huruf besar dan satu huruf kecil.",numbers:"Medan :attribute mesti mengandungi sekurang-kurangnya satu nombor.",symbols:"Medan :attribute mesti mengandungi sekurang-kurangnya satu simbol.",uncompromised:"Nilai :attribute yang diberikan telah muncul dalam kebocoran data. Sila pilih :attribute yang berbeza."},present:"Medan :attribute mesti wujud.",prohibited:"Medan :attribute dilarang.",prohibited_if:"Medan :attribute dilarang apabila :other adalah :value.",prohibited_unless:"Medan :attribute dilarang melainkan :other berada dalam :values.",prohibits:"Medan :attribute melarang :other daripada wujud.",regex:"Format medan :attribute tidak sah.",required:"Medan :attribute diperlukan.",required_array_keys:"Medan :attribute mesti mengandungi entri untuk: :values.",required_if:"Medan :attribute diperlukan apabila :other adalah :value.",required_if_accepted:"Medan :attribute diperlukan apabila :other diterima.",required_if_declined:"Medan :attribute diperlukan apabila :other ditolak.",required_unless:"Medan :attribute diperlukan melainkan :other berada dalam :values.",required_with:"Medan :attribute diperlukan apabila :values wujud.",required_with_all:"Medan :attribute diperlukan apabila semua :values wujud.",required_without:"Medan :attribute diperlukan apabila :values tidak wujud.",required_without_all:"Medan :attribute diperlukan apabila tiada satu pun daripada :values wujud.",same:"Medan :attribute mesti sepadan dengan :other.",size:{array:"Medan :attribute mesti mengandungi :size item.",file:"Medan :attribute mesti :size kilobait.",numeric:"Medan :attribute mesti :size.",string:"Medan :attribute mesti :size huruf."},starts_with:"Medan :attribute mesti bermula dengan salah satu dari berikut: :values.",string:"Medan :attribute mesti perkataan / rentetan aksara.",timezone:"Medan :attribute mesti zon masa yang sah.",unique:"Medan :attribute telah wujud.",uploaded:"Medan :attribute gagal dimuat naik.",uppercase:"Medan :attribute mesti dalam huruf besar.",url:"Medan :attribute mesti URL yang sah.",ulid:"Medan :attribute mesti ULID yang sah.",uuid:"Medan :attribute mesti UUID yang sah.",custom:{"attribute-name":{"rule-name":"custom-message"}},attributes:{},values:{}}}();
package/dist/quival.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * quival v0.4.2 (https://github.com/apih/quival)
2
+ * quival v0.5.1 (https://github.com/apih/quival)
3
3
  * (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
4
4
  * Released under the MIT License.
5
5
  */
@@ -240,10 +240,10 @@ var quival = (function (exports) {
240
240
  collectMissingsThenTest(attribute, value, parameters, callback) {
241
241
  let result = [];
242
242
  for (const other of parameters) {
243
- result.push(this.checkMissing(other));
243
+ result.push(this.checkMissing(other, this.validator.getValue(other)));
244
244
  }
245
245
  if (callback(result)) {
246
- return this.checkMissing(attribute);
246
+ return this.checkMissing(attribute, value);
247
247
  }
248
248
  return true;
249
249
  }
@@ -297,11 +297,11 @@ var quival = (function (exports) {
297
297
  return callback(value.getTime(), otherValue.getTime());
298
298
  }
299
299
  // Type
300
- checkArray(attribute, value, parameters) {
300
+ checkArray(attribute, value, parameters = []) {
301
301
  if (!(Array.isArray(value) || isPlainObject(value))) {
302
302
  return false;
303
303
  }
304
- if (parameters && parameters.length > 0) {
304
+ if (parameters.length > 0) {
305
305
  for (const key of Object.keys(value)) {
306
306
  if (!parameters.includes(key)) {
307
307
  return false;
@@ -313,7 +313,10 @@ var quival = (function (exports) {
313
313
  checkList(attribute, value, parameters) {
314
314
  return Array.isArray(value);
315
315
  }
316
- checkBoolean(attribute, value, parameters) {
316
+ checkBoolean(attribute, value, parameters = []) {
317
+ if (parameters.includes('strict')) {
318
+ return [true, false].includes(value);
319
+ }
317
320
  return [true, false, 0, 1, '0', '1'].includes(value);
318
321
  }
319
322
  checkDate(attribute, value, parameters) {
@@ -322,17 +325,23 @@ var quival = (function (exports) {
322
325
  checkFile(attribute, value, parameters) {
323
326
  return value instanceof File;
324
327
  }
325
- checkInteger(attribute, value, parameters) {
326
- return String(parseInt(value, 10)) === String(value);
328
+ checkInteger(attribute, value, parameters = []) {
329
+ if (!parameters.includes('strict') && typeof value === 'string') {
330
+ value = parseFloat(value);
331
+ }
332
+ return Number.isInteger(value);
327
333
  }
328
- checkNumeric(attribute, value, parameters) {
334
+ checkNumeric(attribute, value, parameters = []) {
335
+ if (parameters.includes('strict')) {
336
+ return typeof value === 'number';
337
+ }
329
338
  return isNumeric(value);
330
339
  }
331
340
  checkString(attribute, value, parameters) {
332
341
  return typeof value === 'string';
333
342
  }
334
343
  // Numeric
335
- checkDecimal(attribute, value, parameters) {
344
+ checkDecimal(attribute, value, parameters = []) {
336
345
  if (!this.checkNumeric(attribute, value)) {
337
346
  return false;
338
347
  }
@@ -388,7 +397,7 @@ var quival = (function (exports) {
388
397
  value = String(value).replace(/\s/g, '');
389
398
  return value.length > 0;
390
399
  }
391
- checkRequiredArrayKeys(attribute, value, parameters) {
400
+ checkRequiredArrayKeys(attribute, value, parameters = []) {
392
401
  if (!this.checkArray(attribute, value)) {
393
402
  return false;
394
403
  }
@@ -447,17 +456,17 @@ var quival = (function (exports) {
447
456
  }
448
457
  // Missing
449
458
  checkMissing(attribute, value, parameters) {
450
- return !this.validator.hasAttribute(attribute);
459
+ return typeof value === 'undefined';
451
460
  }
452
461
  checkMissingIf(attribute, value, parameters) {
453
462
  if (this.isDependent(parameters)) {
454
- return this.checkMissing(attribute);
463
+ return this.checkMissing(attribute, value);
455
464
  }
456
465
  return true;
457
466
  }
458
467
  checkMissingUnless(attribute, value, parameters) {
459
468
  if (!this.isDependent(parameters)) {
460
- return this.checkMissing(attribute);
469
+ return this.checkMissing(attribute, value);
461
470
  }
462
471
  return true;
463
472
  }
@@ -483,7 +492,7 @@ var quival = (function (exports) {
483
492
  }
484
493
  return true;
485
494
  }
486
- checkProhibits(attribute, value, parameters) {
495
+ checkProhibits(attribute, value, parameters = []) {
487
496
  if (this.checkRequired(attribute, value)) {
488
497
  for (const parameter of parameters) {
489
498
  if (this.checkRequired(parameter, this.validator.getValue(parameter))) {
@@ -564,7 +573,7 @@ var quival = (function (exports) {
564
573
  checkUppercase(attribute, value, parameters) {
565
574
  return value === String(value).toLocaleUpperCase();
566
575
  }
567
- checkStartsWith(attribute, value, parameters) {
576
+ checkStartsWith(attribute, value, parameters = []) {
568
577
  value = String(value);
569
578
  for (const parameter of parameters) {
570
579
  if (value.startsWith(parameter)) {
@@ -576,7 +585,7 @@ var quival = (function (exports) {
576
585
  checkDoesntStartWith(attribute, value, parameters) {
577
586
  return !this.checkStartsWith(attribute, value, parameters);
578
587
  }
579
- checkEndsWith(attribute, value, parameters) {
588
+ checkEndsWith(attribute, value, parameters = []) {
580
589
  value = String(value);
581
590
  for (const parameter of parameters) {
582
591
  if (value.endsWith(parameter)) {
@@ -593,7 +602,7 @@ var quival = (function (exports) {
593
602
  const other = this.validator.getValue(parameters[0]);
594
603
  return value === other;
595
604
  }
596
- checkDifferent(attribute, value, parameters) {
605
+ checkDifferent(attribute, value, parameters = []) {
597
606
  for (const parameter of parameters) {
598
607
  const other = this.validator.getValue(parameter);
599
608
  if (typeof other !== 'undefined' && value === other) {
@@ -663,7 +672,7 @@ var quival = (function (exports) {
663
672
  return new RegExp(pattern).test(value);
664
673
  }
665
674
  // Array / Object
666
- checkContains(attribute, value, parameters) {
675
+ checkContains(attribute, value, parameters = []) {
667
676
  if (!this.checkArray(attribute, value)) {
668
677
  return false;
669
678
  }
@@ -674,6 +683,17 @@ var quival = (function (exports) {
674
683
  }
675
684
  return true;
676
685
  }
686
+ checkDoesntContain(attribute, value, parameters = []) {
687
+ if (!this.checkArray(attribute, value)) {
688
+ return false;
689
+ }
690
+ for (const parameter of parameters) {
691
+ if (value.includes(parameter)) {
692
+ return false;
693
+ }
694
+ }
695
+ return true;
696
+ }
677
697
  checkDistinct(attribute, value, parameters) {
678
698
  const unparsed = this.validator.getPrimaryAttribute(attribute);
679
699
  if (!unparsed.includes('*')) {
@@ -735,7 +755,7 @@ var quival = (function (exports) {
735
755
  }
736
756
  return false;
737
757
  }
738
- checkMimes(attribute, value, parameters) {
758
+ checkMimes(attribute, value, parameters = []) {
739
759
  if (!this.checkFile(attribute, value)) {
740
760
  return false;
741
761
  }
@@ -750,8 +770,12 @@ var quival = (function (exports) {
750
770
  checkExtensions(attribute, value, parameters) {
751
771
  return this.checkMimes(attribute, value, parameters);
752
772
  }
753
- async checkImage(attribute, value, parameters) {
754
- let result = this.checkMimes(attribute, value, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp']);
773
+ async checkImage(attribute, value, parameters = []) {
774
+ const mimes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
775
+ if (parameters.includes('allow_svg')) {
776
+ mimes.push('svg');
777
+ }
778
+ let result = this.checkMimes(attribute, value, mimes);
755
779
  if (!result || typeof FileReader === 'undefined') {
756
780
  return result;
757
781
  }
@@ -772,7 +796,7 @@ var quival = (function (exports) {
772
796
  });
773
797
  return result;
774
798
  }
775
- async checkDimensions(attribute, value, parameters) {
799
+ async checkDimensions(attribute, value, parameters = []) {
776
800
  if (!this.checkImage(attribute, value) || !Object.hasOwn(this.#imageCache, attribute)) {
777
801
  return false;
778
802
  }
@@ -1215,6 +1239,9 @@ var quival = (function (exports) {
1215
1239
  replaceNotIn(message, attribute, rule, parameters) {
1216
1240
  return this.replaceRequiredArrayKeys(message, attribute, rule, parameters);
1217
1241
  }
1242
+ replaceDoesntContain(message, attribute, rule, parameters) {
1243
+ return this.replaceRequiredArrayKeys(message, attribute, rule, parameters);
1244
+ }
1218
1245
  // File
1219
1246
  replaceMimetypes(message, attribute, rule, parameters) {
1220
1247
  return this.replace(message, {
@@ -1437,7 +1464,7 @@ var quival = (function (exports) {
1437
1464
  this.#checkers.clearCaches();
1438
1465
  this.#errors = new ErrorBag();
1439
1466
  const tasks = [];
1440
- const skippedAttributes = [];
1467
+ const skippedAttributes = new Set();
1441
1468
  for (const [attribute, rules] of Object.entries(this.#rules)) {
1442
1469
  for (const [rule] of rules) {
1443
1470
  if (
@@ -1454,7 +1481,7 @@ var quival = (function (exports) {
1454
1481
  let value = this.getValue(attribute);
1455
1482
  const hasRule = (ruleName) => rules.some((rule) => rule[0] === ruleName);
1456
1483
  if (hasRule('sometimes') && typeof value === 'undefined') {
1457
- skippedAttributes.push(attribute);
1484
+ skippedAttributes.add(attribute);
1458
1485
  continue;
1459
1486
  }
1460
1487
  tasks.push(async () => {
@@ -1468,7 +1495,7 @@ var quival = (function (exports) {
1468
1495
  !Validator.#implicitRules.includes(rule) &&
1469
1496
  (typeof value === 'undefined' || (typeof value === 'string' && value.trim() === '') || (isNullable && value === null)))
1470
1497
  ) {
1471
- skippedAttributes.push(attribute);
1498
+ skippedAttributes.add(attribute);
1472
1499
  continue;
1473
1500
  }
1474
1501
  let result, success, message;
@@ -1520,7 +1547,7 @@ var quival = (function (exports) {
1520
1547
  });
1521
1548
  this.#errors.sortByKeys(Object.keys(this.#rules));
1522
1549
  }
1523
- this.#skippedAttributes = skippedAttributes.filter((value, index, array) => array.indexOf(value) === index);
1550
+ this.#skippedAttributes = [...skippedAttributes];
1524
1551
  return this.#errors;
1525
1552
  }
1526
1553
  async passes() {
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * quival v0.4.2 (https://github.com/apih/quival)
2
+ * quival v0.5.1 (https://github.com/apih/quival)
3
3
  * (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
4
4
  * Released under the MIT License.
5
5
  */
6
- var quival=function(e){"use strict";function t(e){return e.replace(/[-_]/g," ").replace(/\s+/," ").trim().replace(/(\s\w)/g,(e=>e[1].toUpperCase()))}function r(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(e,t=""){return Object.keys(e).reduce(((r,i)=>{const c=t?`${t}.${i}`:i;return"object"==typeof e[i]&&null!==e[i]?Object.assign(r,s(e[i],c)):r[c]=e[i],r}),{})}function i(e){if(a(e)||"string"!=typeof e)return new Date("");if(e instanceof Date)return e;let t,r,s,i,c,n,l,u;const h=e=>e&&/^\d*$/.test(e)?parseInt(e):e;if(null!==(t=e.match(/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{2,4})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i)))[,i,s,r,,c=0,n=0,,l=0,u="am"]=t.map(h);else if(null!==(t=e.match(/^(\d{2,4})[.\/-](\d{1,2})[.\/-](\d{1,2})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i))||null!==(t=e.match(/^(\d{4})(\d{2})(\d{2})\s?((\d{2})(\d{2})((\d{2}))?\s?(am|pm)?)?/i)))[,r,s,i,,c=0,n=0,,l=0,u="am"]=t.map(h);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{4})[.\/-](\d{2})[.\/-](\d{2})/i))[,c,n,,l,u="am",r,s,i]=t.map(h);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{2})[.\/-](\d{2})[.\/-](\d{4})/i))[,c,n,,l,u="am",i,s,r]=t.map(h);else{if(!(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?/i)))return new Date(e);{const e=new Date;r=e.getFullYear(),s=e.getMonth()+1,i=e.getDate(),[,c=0,n=0,,l=0,u="am"]=t.map(h)}}return r>=10&&r<100&&(r+=2e3),"pm"===u.toLowerCase()&&c<12&&(c+=12),new Date(`${r}-${s}-${i} ${c}:${n}:${l}`)}function c(e,t){if(a(e))return new Date("");t=t.split("");const r={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let s="^",i={years:-1,months:-1,days:-1,hours:-1,minutes:-1,seconds:-1,meridiem:-1},c=1;for(const e of t)Object.hasOwn(r,e)?(s+=r[e],-1!==["Y","y"].indexOf(e)?i.years=c++:-1!==["m","n"].indexOf(e)?i.months=c++:-1!==["d","j"].indexOf(e)?i.days=c++:-1!==["G","g","H","h"].indexOf(e)?i.hours=c++:"i"===e?i.minutes=c++:"s"===e?i.seconds=c++:-1!==["A","a"].indexOf(e)&&(i.meridiem=c++)):s+="\\"+e;s+="$";let n=e.match(new RegExp(s));if(null===n)return new Date("");n=n.map((e=>e&&/^\d*$/.test(e)?parseInt(e):e));const l=new Date;let u=n[i.years],h=n[i.months],o=n[i.days],p=n[i.hours]??0,d=n[i.minutes]??0,f=n[i.seconds]??0,g=n[i.meridiem]??"am";return u||h||o?!u||h||o?u||!h||o?u||h||!o||(u=l.getFullYear(),h=l.getMonth()+1):(u=l.getFullYear(),o=1):(h=1,o=1):(u=l.getFullYear(),h=l.getMonth()+1,o=l.getDate()),u>=10&&u<100&&(u+=2e3),"pm"===g.toLowerCase()&&p<12&&(p+=12),new Date(`${u}-${h}-${o} ${p}:${d}:${f}`)}function a(e){return""===e||null==e}function n(e){const t=Number(e);return null!==e&&"boolean"!=typeof e&&"number"==typeof t&&!isNaN(t)}function l(e){return"[object Object]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date&&"Invalid Date"!==e.toDateString()}class h{#e;#t;constructor(e){this.#e={},this.#t={},this.validator=e}clearCaches(){this.#e={},this.#t={}}isDependent(e){const t=this.validator.getValue(e[0]);return e.slice(1).some((e=>e==t))}collectRequiredsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkRequired(e,this.validator.getValue(e)));return!s(i)||this.checkRequired(e,t)}collectMissingsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkMissing(e));return!s(i)||this.checkMissing(e)}testStringUsingRegex(e,t,r,s,i=!1){return("string"==typeof t||"number"==typeof t)&&(t=String(t),i||this.validator.hasRule(e,"ascii")?r.test(t):s.test(t))}compareValues(e,t,r,s){if(a(t))return!1;const i=r[0]??"";let c=this.validator.getValue(i);return c=void 0===c?n(i)?parseFloat(i,10):null:this.validator.getSize(i,c),!a(c)&&s(this.validator.getSize(e,t),c)}compareDates(e,t,r,s){const a=this.validator.getRule(e);if(!u(t=Object.hasOwn(a,"date_format")?c(t,a.date_format[0]):i(t)))return!1;const n=r[0]??"";let l=this.validator.getValue(n);if(void 0===l)l=i(n);else{const e=this.validator.getRule(n);l=Object.hasOwn(e,"date_format")?c(l,e.date_format[0]):i(l)}return!!u(l)&&s(t.getTime(),l.getTime())}checkArray(e,t,r){if(!Array.isArray(t)&&!l(t))return!1;if(r&&r.length>0)for(const e of Object.keys(t))if(!r.includes(e))return!1;return!0}checkList(e,t,r){return Array.isArray(t)}checkBoolean(e,t,r){return[!0,!1,0,1,"0","1"].includes(t)}checkDate(e,t,r){return u(i(t))}checkFile(e,t,r){return t instanceof File}checkInteger(e,t,r){return String(parseInt(t,10))===String(t)}checkNumeric(e,t,r){return n(t)}checkString(e,t,r){return"string"==typeof t}checkDecimal(e,t,r){if(!this.checkNumeric(e,t))return!1;const s=(String(t).split(".")[1]??"").length;return 1===r.length?s==r[0]:s>=r[0]&&s<=r[1]}checkMultipleOf(e,t,r){if(!n(t)||!n(r[0]))return!1;const s=parseInt(t,10),i=parseInt(r[0],10);return(0!==s||0!==i)&&(0===s||0!==i&&s%i==0)}checkAccepted(e,t,r){return["yes","on","1",1,!0,"true"].includes(t)}checkAcceptedIf(e,t,r){return!this.isDependent(r)||this.checkAccepted(e,t,r)}checkDeclined(e,t,r){return["no","off","0",0,!1,"false"].includes(t)}checkDeclinedIf(e,t,r){return!this.isDependent(r)||this.checkDeclined(e,t,r)}checkRequired(e,t,r){return!a(t)&&(Array.isArray(t)?t.length>0:t instanceof File?t.size>0:(t=String(t).replace(/\s/g,"")).length>0)}checkRequiredArrayKeys(e,t,r){if(!this.checkArray(e,t))return!1;const s=Object.keys(t);for(const e of r)if(!s.includes(e))return!1;return!0}checkRequiredIf(e,t,r){return!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredIfAccepted(e,t,r){return!this.checkAccepted(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredIfDeclined(e,t,r){return!this.checkDeclined(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredUnless(e,t,r){return!!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredWith(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>e.includes(!0)))}checkRequiredWithAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>!e.includes(!1)))}checkRequiredWithout(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>e.includes(!1)))}checkRequiredWithoutAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>!e.includes(!0)))}checkFilled(e,t,r){return void 0===t||this.checkRequired(e,t)}checkPresent(e,t,r){return void 0!==t}checkMissing(e,t,r){return!this.validator.hasAttribute(e)}checkMissingIf(e,t,r){return!this.isDependent(r)||this.checkMissing(e)}checkMissingUnless(e,t,r){return!!this.isDependent(r)||this.checkMissing(e)}checkMissingWith(e,t,r){return this.collectMissingsThenTest(e,t,r,(e=>e.includes(!1)))}checkMissingWithAll(e,t,r){return this.collectMissingsThenTest(e,t,r,(e=>!e.includes(!0)))}checkProhibited(e,t,r){return!this.checkRequired(e,t)}checkProhibitedIf(e,t,r){return!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibitedUnless(e,t,r){return!!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibits(e,t,r){if(this.checkRequired(e,t))for(const e of r)if(this.checkRequired(e,this.validator.getValue(e)))return!1;return!0}checkSize(e,t,r){return this.validator.getSize(e,t)===parseFloat(r[0])}checkMin(e,t,r){return this.validator.getSize(e,t)>=parseFloat(r[0])}checkMax(e,t,r){return this.validator.getSize(e,t)<=parseFloat(r[0])}checkBetween(e,t,r){return this.checkMin(e,t,[r[0]])&&this.checkMax(e,t,[r[1]])}checkDigits(e,t,r,s=(e,t)=>e===t){return!!function(e){return-1===String(e).search(/[^0-9]/)}(t=String(t??""))&&s(t.length,parseInt(r[0],10),parseInt(r[1]??0,10))}checkMinDigits(e,t,r){return this.checkDigits(e,t,r,((e,t)=>e>=t))}checkMaxDigits(e,t,r){return this.checkDigits(e,t,r,((e,t)=>e<=t))}checkDigitsBetween(e,t,r){return this.checkDigits(e,t,r,((e,t,r)=>e>=t&&e<=r))}checkAlpha(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z]+$/i,/^[\p{L}\p{M}]+$/u,r.includes("ascii"))}checkAlphaDash(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9_-]+$/i,/^[\p{L}\p{M}\p{N}_-]+$/u,r.includes("ascii"))}checkAlphaNum(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9]+$/i,/^[\p{L}\p{M}\p{N}]+$/u,r.includes("ascii"))}checkAscii(e,t,r){return!/[^\x09\x10\x13\x0A\x0D\x20-\x7E]/.test(t)}checkRegex(e,t,r,s=!1){if("string"!=typeof t&&!n(t))return!1;const i=r.join(",");let[c,l,u]=i.match(/^\/(.*)\/([gimu]*)$/)??[];if(a(c))throw new Error(`Invalid regular expression pattern: ${i}`);u.includes("u")&&(l=l.replace(/\\A/g,"^").replace(/\\z/gi,"$").replace(/\\([pP])([CLMNPSZ])/g,"\\$1{$2}").replace(/\\\x\{([0-9a-f]+)\}/g,"\\u{$1}"));const h=new RegExp(l,u).test(t);return s?!h:h}checkNotRegex(e,t,r){return this.checkRegex(e,t,r,!0)}checkLowercase(e,t,r){return t===String(t).toLocaleLowerCase()}checkUppercase(e,t,r){return t===String(t).toLocaleUpperCase()}checkStartsWith(e,t,r){t=String(t);for(const e of r)if(t.startsWith(e))return!0;return!1}checkDoesntStartWith(e,t,r){return!this.checkStartsWith(e,t,r)}checkEndsWith(e,t,r){t=String(t);for(const e of r)if(t.endsWith(e))return!0;return!1}checkDoesntEndWith(e,t,r){return!this.checkEndsWith(e,t,r)}checkSame(e,t,r){return t===this.validator.getValue(r[0])}checkDifferent(e,t,r){for(const e of r){const r=this.validator.getValue(e);if(void 0!==r&&t===r)return!1}return!0}checkConfirmed(e,t,r){return this.checkSame(e,t,[r[0]??e+"_confirmation"])}checkGt(e,t,r){return this.compareValues(e,t,r,((e,t)=>e>t))}checkGte(e,t,r){return this.compareValues(e,t,r,((e,t)=>e>=t))}checkLt(e,t,r){return this.compareValues(e,t,r,((e,t)=>e<t))}checkLte(e,t,r){return this.compareValues(e,t,r,((e,t)=>e<=t))}checkAfter(e,t,r){return this.compareDates(e,t,r,((e,t)=>e>t))}checkAfterOrEqual(e,t,r){return this.compareDates(e,t,r,((e,t)=>e>=t))}checkBefore(e,t,r){return this.compareDates(e,t,r,((e,t)=>e<t))}checkBeforeOrEqual(e,t,r){return this.compareDates(e,t,r,((e,t)=>e<=t))}checkDateEquals(e,t,r){return this.compareDates(e,t,r,((e,t)=>e===t))}checkDateFormat(e,t,r){const s=r[0].split(""),i={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let c="^";for(const e of s)Object.hasOwn(i,e)?c+=i[e]:c+="\\"+e;return c+="$",new RegExp(c).test(t)}checkContains(e,t,r){if(!this.checkArray(e,t))return!1;for(const e of r)if(!t.includes(e))return!1;return!0}checkDistinct(e,t,i){const c=this.validator.getPrimaryAttribute(e);if(!c.includes("*"))return!0;const a=c.indexOf("*"),n=c.substring(0,a-1);let l;Object.hasOwn(this.#e,n)?l=this.#e[n]:(l=JSON.stringify(s(this.validator.getValue(n)??{})),this.#e[n]=l);const u=i.includes("ignore_case"),h=!u&&i.includes("strict"),o=r(String(t));let p=`"${r(c.substring(a)).replaceAll("\\*",'[^."]+')}":`,d=0;return p+=h?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,p+="[,}]+",d+=l.match(new RegExp(p,"g"+(u?"i":"")))?.length??0,1===d}checkInArray(e,t,r){const i=this.validator.getPrimaryAttribute(r[0]);if(!i.includes("*"))return!1;const c=this.validator.getValue(i.split(".*")[0])??{};return Object.values(s(c)).some((e=>e==t))}checkIn(e,t,r){if(!this.checkArray(e,t)||!this.validator.hasRule(e,"array"))return r.some((e=>e==t));for(const e of Object.values(t))if(!r.some((t=>t==e)))return!1;return!0}checkNotIn(e,t,r){return!this.checkIn(e,t,r)}checkMimetypes(e,t,r){return!!this.checkFile(e,t)&&r.includes(t.type)}checkMimes(e,t,r){return!!this.checkFile(e,t)&&(r.includes("jpg")&&!r.includes("jpeg")&&r.push("jpeg"),r.includes("jpeg")&&!r.includes("jpg")&&r.push("jpg"),r.includes(t.name.split(".").pop().toLowerCase()))}checkExtensions(e,t,r){return this.checkMimes(e,t,r)}async checkImage(e,t,r){let s=this.checkMimes(e,t,["jpg","jpeg","png","gif","bmp","svg","webp"]);return s&&"undefined"!=typeof FileReader?(await new Promise(((e,r)=>{const s=new FileReader;s.onload=t=>e(t.target.result),s.onerror=r,s.readAsDataURL(t)})).then((async t=>{const r=new Image;r.src=t,await r.decode(),this.#t[e]=r})).catch((()=>{s=!1})),s):s}async checkDimensions(e,t,r){if(!this.checkImage(e,t)||!Object.hasOwn(this.#t,e))return!1;const s={};for(const e of r){const[t,r]=e.split("=",2);if("ratio"===t&&r.includes("/")){const[e,i]=r.split("/",2).map((e=>parseFloat(e,10)));s[t]=e/i}else s[t]=parseFloat(r,10)}const i=this.#t[e],c=i.naturalWidth,a=i.naturalHeight;return!(Object.hasOwn(s,"width")&&s.width!==c||Object.hasOwn(s,"height")&&s.height!==a||Object.hasOwn(s,"min_width")&&s.min_width>c||Object.hasOwn(s,"min_height")&&s.min_height>a||Object.hasOwn(s,"max_width")&&s.max_width<c||Object.hasOwn(s,"max_height")&&s.max_height<a)&&(!Object.hasOwn(s,"ratio")||Math.abs(s.ratio-c/a)<=1/(Math.max(c,a)+1))}checkEmail(e,t,r){if(!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(t)){return/^((?:[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]|[^\u0000-\u007F])+@(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?(?:\.(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?)+)*$/.test(t)}return!0}checkJson(e,t,r){try{JSON.parse(t)}catch(e){return!1}return!0}checkHexColor(e,t,r){return/^#(?:(?:[0-9a-f]{3}){1,2}|(?:[0-9a-f]{4}){1,2})$/i.test(t)}checkMacAddress(e,t,r){t=String(t);const s={"-":2,":":2,".":4};let i,c;for([i,c]of Object.entries(s))if(t.includes(i))break;const a=t.split(i);if(a.length!==12/c)return!1;for(const e of a)if(!new RegExp("^[0-9a-f]{"+c+"}$","i").test(e))return!1;return!0}checkIpv4(e,t,r){if(/[^\d.]/.test(t))return!1;const s=String(t).split(".");if(4!==s.length)return!1;for(const e of s)if(e<0||e>255)return!1;return!0}checkIpv6(e,t,r){if((t=String(t)).includes(":::")||t.split("::").length>2)return!1;const s=t.split(":");if(s.length<3||s.length>8)return!1;for(const e of s)if(""!==e&&!/^[0-9a-f]{1,4}$/i.test(e))return!1;return!0}checkIp(e,t,r){return this.checkIpv4(e,t,r)||this.checkIpv6(e,t,r)}checkTimezone(e,t,r){try{Intl.DateTimeFormat(void 0,{timeZone:t})}catch(e){if(String(e).toLowerCase().includes("invalid time zone"))return!1}return!0}checkUrl(e,t,r){try{new URL(t)}catch(e){return!1}return!0}checkUlid(e,t,r){return/[0-7][0-9A-HJKMNP-TV-Z]{25}/.test(t)}checkUuid(e,t,r){return/[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}/.test(t)}}class o{#r;keys(){return Object.keys(this.#r)}values(){return Object.values(this.#r)}entries(){return Object.entries(this.#r)}add(e,t){Object.hasOwn(this.#r,e)?this.#r[e].push(t):this.#r[e]=[t]}get(e){if(!e.includes("*"))return Object.hasOwn(this.#r,e)?this.#r[e]:{};const t=new RegExp("^"+e.replaceAll("*",".*?")+"$"),r={};for(const[e,s]of this.entries())t.test(e)&&(r[e]=s);return r}first(e){for(const t of Object.values(this.get(e)))return Array.isArray(t)?t[0]:t;return""}has(e){return""!==this.first(e)}remove(e){delete this.#r[e]}messages(){return this.#r}all(){const e=[];return this.values().forEach((t=>e.push(...t))),e}count(){let e=0;return this.values().forEach((t=>e+=t.length)),e}isEmpty(){return 0===this.keys().length}isNotEmpty(){return!this.isEmpty()}sortByKeys(e){const t={};for(const r of e)Object.hasOwn(this.#r,r)&&(t[r]=this.#r[r]);this.#r=t}constructor(){this.#r={}}}class p{static#s;static#i={};static locale(e){this.#s=e}static setMessages(e,t){this.#i[e]=s(t)}static get(e){if(this.#i[this.#s]&&this.#i[this.#s][e])return this.#i[this.#s][e]}static has(e){return void 0!==this.get(e)}static set(e,t){l(t)?Object.assign(this.#i[this.#s],s(t,e)):"string"==typeof t&&(this.#i[this.#s][e]=t)}}class d{constructor(e){this.validator=e}replace(e,t){return Object.entries(t).forEach((([t,r])=>e=e.replaceAll(":"+t,r))),e}replaceDecimal(e,t,r,s){return this.replace(e,{decimal:s.join("-")})}replaceMultipleOf(e,t,r,s){return this.replace(e,{value:s[0]})}replaceAcceptedIf(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),value:this.validator.getDisplayableValue(s[0],this.validator.getValue(s[0]))})}replaceDeclinedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredArrayKeys(e,t,r,s){return this.replace(e,{values:s.map((e=>this.validator.getDisplayableValue(t,e))).join(", ")})}replaceRequiredIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfAccepted(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfDeclined(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredUnless(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),values:s.slice(1).map((e=>this.validator.getDisplayableValue(s[0],e))).join(", ")})}replaceRequiredWith(e,t,r,s){return this.replace(e,{values:s.map((e=>this.validator.getDisplayableAttribute(e))).join(" / ")})}replaceRequiredWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithout(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithoutAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceMissingUnless(e,t,r,s){return this.replace(this.replaceRequiredUnless(e,t,r,s),{value:this.validator.getDisplayableValue(s[0],s[1])})}replaceMissingWith(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceProhibitedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceProhibitedUnless(e,t,r,s){return this.replaceRequiredUnless(e,t,r,s)}replaceProhibits(e,t,r,s){return this.replace(e,{other:s.map((e=>this.validator.getDisplayableAttribute(e))).join(" / ")})}replaceSize(e,t,r,s){return this.replace(e,{size:s[0]})}replaceMin(e,t,r,s){return this.replace(e,{min:s[0]})}replaceMax(e,t,r,s){return this.replace(e,{max:s[0]})}replaceBetween(e,t,r,s){return this.replace(e,{min:s[0],max:s[1]})}replaceDigits(e,t,r,s){return this.replace(e,{digits:s[0]})}replaceMinDigits(e,t,r,s){return this.replaceMin(e,t,r,s)}replaceMaxDigits(e,t,r,s){return this.replaceMax(e,t,r,s)}replaceDigitsBetween(e,t,r,s){return this.replaceBetween(e,t,r,s)}replaceStartsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntStartWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceEndsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntEndWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceSame(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceDifferent(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceGt(e,t,r,s){const i=this.validator.getValue(s[0]);return this.replace(e,{value:i?this.validator.getSize(s[0],i):this.validator.getDisplayableAttribute(s[0])})}replaceGte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLt(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceAfter(e,t,r,s){const i=s[0];return this.replace(e,{date:this.validator.hasAttribute(i)?this.validator.getDisplayableAttribute(i):i})}replaceAfterOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBefore(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBeforeOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateEquals(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateFormat(e,t,r,s){return this.replace(e,{format:s[0]})}replaceInArray(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceNotIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceMimetypes(e,t,r,s){return this.replace(e,{values:s.join(", ")})}replaceMimes(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}replaceExtensions(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}}class f{static#c={};static#a={};static#n=["active_url","bail","can","current_password","enum","exclude","exclude_if","exclude_unless","exclude_with","exclude_without","exists","nullable","sometimes","unique"];static#l=["accepted","accepted_if","declined","declined_if","filled","missing","missing_if","missing_unless","missing_with","missing_with_all","present","required","required_if","required_if_accepted","required_if_declined","required_unless","required_with","required_with_all","required_without","required_without_all"];#r;#u;#h;#o;#p;#d;#f;#g;#m;#k;#b;#y;static setLocale(e){p.locale(e)}static setMessages(e,t){p.setMessages(e,t)}static addChecker(e,t,r){f.#c[e]=t,r&&p.set(e,r)}static addImplicitChecker(e,t,r){f.addChecker(e,t,r),f.#l.push(e)}static addReplacer(e,t){f.#a[e]=t}static addDummyRule(e){f.#n.push(e)}constructor(e={},r={},s={},i={},c={}){this.#m=[],this.#k={},this.#b=!1,this.#y=!1,this.arrayRules=["array","list"],this.fileRules=["file","image","mimetypes","mimes"],this.stringRules=["string","alpha","alpha_dash","alpha_num","ascii","email"],this.numericRules=["decimal","numeric","integer"],this.sizeRules=["size","between","min","max","gt","lt","gte","lte"],this.setProperties(e,r,s,i,c),this.#d=new h(this),this.#f=new d(this);for(const[e,r]of Object.entries(f.#c))this.#d[t("check_"+e)]=r;for(const[e,r]of Object.entries(f.#a))this.#f[t("replace_"+e)]=r;this.#g=new o}setProperties(e={},t={},r={},i={},c={}){return this.#r=e,this.#u=this.parseRules(t),this.#h=r,this.#o=i,this.#p=s(c),this}setData(e){return this.#r=e,this}setRules(e){return this.#u=this.parseRules(e),this}setCustomMessages(e){return this.#h=e,this}setCustomAttributes(e){return this.#o=e,this}setCustomValues(e){return this.#p=s(e),this}addImplicitAttribute(e,t){return this.#k[e]=t,this}stopOnFirstFailure(e=!0){return this.#b=e,this}alwaysBail(e=!0){return this.#y=e,this}parseRules(e){const t={};for(const[r,s]of Object.entries(e)){const e=r.includes("*")?this.parseWildcardAttribute(r):[r];for(const r of e){const e=[];for(const t of this.parseAttributeRules(s))e.push(this.parseAttributeRule(t));t[r]=e}}return t}parseWildcardAttribute(e){const t=[],r=e.indexOf("*"),s=e.substring(0,r-1),i=e.substring(r+2),c=this.getValue(s);return Array.isArray(c)||l(c)?(Object.entries(c).forEach((([r,c])=>{const a=`${s}.${r}.${i}`.replace(/\.$/,""),n=a.includes("*")?this.parseWildcardAttribute(a):[a];t.push(...n),n.forEach((t=>this.#k[t]=e))})),t):[e]}parseAttributeRules(e){return Array.isArray(e)?e:"function"==typeof e?[e]:String(e).split("|")}parseAttributeRule(e){if("function"==typeof e)return[e,[]];let t,r;if(Array.isArray(e))t=e[0]??"",r=e.slice(1);else{const s=e.indexOf(":");-1===s?(t=e,r=[]):(t=e.substring(0,s),r=function(e){const t=[];let r="",s=!1;for(let i=0;i<e.length;i++){const c=e[i];'"'===c?s&&'"'===e[i+1]?(r+='"',i++):(s=!s,s&&(r=r.trim())):","!==c||s?r+=c:(t.push(r),r="")}return t.push(r),t}(e.substring(s+1)))}return[this.normalizeRuleName(t),r]}normalizeRuleName(e){return{int:"integer",bool:"boolean"}[e]??e}async validate(){this.#d.clearCaches(),this.#g=new o;const e=[],r=[];for(const[e,r]of Object.entries(this.#u))for(const[e]of r)if(""!==e&&"function"!=typeof e&&"function"!=typeof this.#d[t("check_"+e)]&&!f.#n.includes(e))throw new Error(`Invalid validation rule: ${e}`);for(const[s,i]of Object.entries(this.#u)){let c=this.getValue(s);const n=e=>i.some((t=>t[0]===e));n("sometimes")&&void 0===c?r.push(s):e.push((async()=>{const e=this.#y||n("bail"),l=n("nullable");let u=!0;for(const[n,h]of i){if(""===n||"function"!=typeof n&&!f.#l.includes(n)&&(void 0===c||"string"==typeof c&&""===c.trim()||l&&null===c)){r.push(s);continue}let i,o,p;const d=(()=>{if("function"==typeof n)return n;{const e=this.#d[t("check_"+n)]??null;return null===e&&f.#n.includes(n)?()=>!0:e}})();if(null===d)throw new Error(`Invalid validation rule: ${n}`);if(i=await d.call(this.#d,s,c,h),"boolean"==typeof i&&(i={success:i}),({success:o,message:p=""}=i),!o&&(u=!1,p=a(p)?this.getMessage(s,n):p,p=this.makeReplacements(p,s,n,h),this.#g.add(s,p),e||f.#l.includes(n)))break}return u}))}if(this.#b){for(const t of e)if(!await t())break}else await Promise.allSettled(e.map((e=>e()))).then((e=>{for(const t of e)if("rejected"===t.status)throw t.reason})),this.#g.sortByKeys(Object.keys(this.#u));return this.#m=r.filter(((e,t,r)=>r.indexOf(e)===t)),this.#g}async passes(){return await this.validate(),!this.#g.isNotEmpty()}async fails(){return!await this.passes()}getMessage(e,t){if("function"==typeof t)return"";const r=this.getValue(e);let s;e=this.getPrimaryAttribute(e);for(const r of[`${e}.${t}`,t])if(Object.hasOwn(this.#h,r)){s=this.#h[r];break}if(!s){let i=t;this.sizeRules.includes(i)&&(Array.isArray(r)||l(r)||this.hasRule(e,this.arrayRules)?i+=".array":r instanceof File||this.hasRule(e,this.fileRules)?i+=".file":this.hasRule(e,this.stringRules)?i+=".string":n(r)||this.hasRule(e,this.numericRules)?i+=".numeric":i+=".string"),s=p.get(i)}return s??`validation.${t}`}makeReplacements(e,r,s,i){const c=this.getDisplayableAttribute(r),a=this.getValue(r),n={attribute:c,ATTRIBUTE:c.toLocaleUpperCase(),Attribute:c.charAt(0).toLocaleUpperCase()+c.substring(1),input:this.getDisplayableValue(r,a)};for(const[t,r]of Object.entries(n))e=e.replaceAll(":"+t,r);const l=r.match(/\.(\d+)\.?/),u=null===l?-1:parseInt(l[1],10);if(-1!==u&&(e=e.replaceAll(":index",u).replaceAll(":position",u+1)),"string"==typeof s){const c=this.#f[t("replace_"+s)]??null;c&&(e=c.call(this.#f,e,r,s,i))}return e}getDisplayableAttribute(e){const t=this.getPrimaryAttribute(e);for(const r of[e,t]){if(Object.hasOwn(this.#o,r))return this.#o[r];if(p.has(`attributes.${r}`))return p.get(`attributes.${r}`)}return Object.hasOwn(this.#k,e)?e:(r=e,r.replace(/(.)(?=[A-Z])/g,(e=>e+"_")).toLowerCase()).replaceAll("_"," ");var r}getDisplayableValue(e,t){const r=`${e=this.getPrimaryAttribute(e)}.${t}`;return a(t)?"empty":"boolean"==typeof t||this.hasRule(e,"boolean")?Number(t)?"true":"false":Object.hasOwn(this.#p,r)?this.#p[r]:p.has(`values.${r}`)?p.get(`values.${r}`):t}getSize(e,t){return a(t)?0:this.hasRule(e,this.stringRules)?String(t).length:n(t)&&this.hasRule(e,this.numericRules)?parseFloat("string"==typeof t?t.trim():t,10):t instanceof File?t.size/1024:l(t)?Object.keys(t).length:Object.hasOwn(t,"length")?t.length:t}getRule(e){return e=this.getPrimaryAttribute(e),this.#u[e]??{}}hasRule(e,t){if(e=this.getPrimaryAttribute(e),t="string"==typeof t?[t]:t,!Object.hasOwn(this.#u,e))return!1;for(const r of t)if(this.#u[e].some((e=>e[0]===r)))return!0;return!1}getPrimaryAttribute(e){return Object.hasOwn(this.#k,e)?this.#k[e]:e}hasAttribute(e){return void 0!==this.getValue(e)}getValue(e){return function(e,t,r){const s=t.split(".");let i=e;for(const e of s){if(!Object.hasOwn(i,e))return r;i=i[e]}return i}(this.#r,e)}errors(){return this.#g}skippedAttributes(){return this.#m}}return e.Checkers=h,e.ErrorBag=o,e.Lang=p,e.Replacers=d,e.Validator=f,e}({});
6
+ var quival=function(e){"use strict";function t(e){return e.replace(/[-_]/g," ").replace(/\s+/," ").trim().replace(/(\s\w)/g,e=>e[1].toUpperCase())}function r(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(e,t=""){return Object.keys(e).reduce((r,i)=>{const c=t?`${t}.${i}`:i;return"object"==typeof e[i]&&null!==e[i]?Object.assign(r,s(e[i],c)):r[c]=e[i],r},{})}function i(e){if(a(e)||"string"!=typeof e)return new Date("");if(e instanceof Date)return e;let t,r,s,i,c,n,l,u;const h=e=>e&&/^\d*$/.test(e)?parseInt(e):e;if(null!==(t=e.match(/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{2,4})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i)))[,i,s,r,,c=0,n=0,,l=0,u="am"]=t.map(h);else if(null!==(t=e.match(/^(\d{2,4})[.\/-](\d{1,2})[.\/-](\d{1,2})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i))||null!==(t=e.match(/^(\d{4})(\d{2})(\d{2})\s?((\d{2})(\d{2})((\d{2}))?\s?(am|pm)?)?/i)))[,r,s,i,,c=0,n=0,,l=0,u="am"]=t.map(h);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{4})[.\/-](\d{2})[.\/-](\d{2})/i))[,c,n,,l,u="am",r,s,i]=t.map(h);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{2})[.\/-](\d{2})[.\/-](\d{4})/i))[,c,n,,l,u="am",i,s,r]=t.map(h);else{if(!(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?/i)))return new Date(e);{const e=new Date;r=e.getFullYear(),s=e.getMonth()+1,i=e.getDate(),[,c=0,n=0,,l=0,u="am"]=t.map(h)}}return r>=10&&r<100&&(r+=2e3),"pm"===u.toLowerCase()&&c<12&&(c+=12),new Date(`${r}-${s}-${i} ${c}:${n}:${l}`)}function c(e,t){if(a(e))return new Date("");t=t.split("");const r={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let s="^",i={years:-1,months:-1,days:-1,hours:-1,minutes:-1,seconds:-1,meridiem:-1},c=1;for(const e of t)Object.hasOwn(r,e)?(s+=r[e],-1!==["Y","y"].indexOf(e)?i.years=c++:-1!==["m","n"].indexOf(e)?i.months=c++:-1!==["d","j"].indexOf(e)?i.days=c++:-1!==["G","g","H","h"].indexOf(e)?i.hours=c++:"i"===e?i.minutes=c++:"s"===e?i.seconds=c++:-1!==["A","a"].indexOf(e)&&(i.meridiem=c++)):s+="\\"+e;s+="$";let n=e.match(new RegExp(s));if(null===n)return new Date("");n=n.map(e=>e&&/^\d*$/.test(e)?parseInt(e):e);const l=new Date;let u=n[i.years],h=n[i.months],o=n[i.days],d=n[i.hours]??0,p=n[i.minutes]??0,f=n[i.seconds]??0,g=n[i.meridiem]??"am";return u||h||o?!u||h||o?u||!h||o?u||h||!o||(u=l.getFullYear(),h=l.getMonth()+1):(u=l.getFullYear(),o=1):(h=1,o=1):(u=l.getFullYear(),h=l.getMonth()+1,o=l.getDate()),u>=10&&u<100&&(u+=2e3),"pm"===g.toLowerCase()&&d<12&&(d+=12),new Date(`${u}-${h}-${o} ${d}:${p}:${f}`)}function a(e){return""===e||null==e}function n(e){const t=Number(e);return null!==e&&"boolean"!=typeof e&&"number"==typeof t&&!isNaN(t)}function l(e){return"[object Object]"===Object.prototype.toString.call(e)}function u(e){return e instanceof Date&&"Invalid Date"!==e.toDateString()}class h{#e;#t;constructor(e){this.#e={},this.#t={},this.validator=e}clearCaches(){this.#e={},this.#t={}}isDependent(e){const t=this.validator.getValue(e[0]);return e.slice(1).some(e=>e==t)}collectRequiredsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkRequired(e,this.validator.getValue(e)));return!s(i)||this.checkRequired(e,t)}collectMissingsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkMissing(e,this.validator.getValue(e)));return!s(i)||this.checkMissing(e,t)}testStringUsingRegex(e,t,r,s,i=!1){return("string"==typeof t||"number"==typeof t)&&(t=String(t),i||this.validator.hasRule(e,"ascii")?r.test(t):s.test(t))}compareValues(e,t,r,s){if(a(t))return!1;const i=r[0]??"";let c=this.validator.getValue(i);return c=void 0===c?n(i)?parseFloat(i,10):null:this.validator.getSize(i,c),!a(c)&&s(this.validator.getSize(e,t),c)}compareDates(e,t,r,s){const a=this.validator.getRule(e);if(!u(t=Object.hasOwn(a,"date_format")?c(t,a.date_format[0]):i(t)))return!1;const n=r[0]??"";let l=this.validator.getValue(n);if(void 0===l)l=i(n);else{const e=this.validator.getRule(n);l=Object.hasOwn(e,"date_format")?c(l,e.date_format[0]):i(l)}return!!u(l)&&s(t.getTime(),l.getTime())}checkArray(e,t,r=[]){if(!Array.isArray(t)&&!l(t))return!1;if(r.length>0)for(const e of Object.keys(t))if(!r.includes(e))return!1;return!0}checkList(e,t,r){return Array.isArray(t)}checkBoolean(e,t,r=[]){return r.includes("strict")?[!0,!1].includes(t):[!0,!1,0,1,"0","1"].includes(t)}checkDate(e,t,r){return u(i(t))}checkFile(e,t,r){return t instanceof File}checkInteger(e,t,r=[]){return r.includes("strict")||"string"!=typeof t||(t=parseFloat(t)),Number.isInteger(t)}checkNumeric(e,t,r=[]){return r.includes("strict")?"number"==typeof t:n(t)}checkString(e,t,r){return"string"==typeof t}checkDecimal(e,t,r=[]){if(!this.checkNumeric(e,t))return!1;const s=(String(t).split(".")[1]??"").length;return 1===r.length?s==r[0]:s>=r[0]&&s<=r[1]}checkMultipleOf(e,t,r){if(!n(t)||!n(r[0]))return!1;const s=parseInt(t,10),i=parseInt(r[0],10);return(0!==s||0!==i)&&(0===s||0!==i&&s%i===0)}checkAccepted(e,t,r){return["yes","on","1",1,!0,"true"].includes(t)}checkAcceptedIf(e,t,r){return!this.isDependent(r)||this.checkAccepted(e,t,r)}checkDeclined(e,t,r){return["no","off","0",0,!1,"false"].includes(t)}checkDeclinedIf(e,t,r){return!this.isDependent(r)||this.checkDeclined(e,t,r)}checkRequired(e,t,r){return!a(t)&&(Array.isArray(t)?t.length>0:t instanceof File?t.size>0:(t=String(t).replace(/\s/g,"")).length>0)}checkRequiredArrayKeys(e,t,r=[]){if(!this.checkArray(e,t))return!1;const s=Object.keys(t);for(const e of r)if(!s.includes(e))return!1;return!0}checkRequiredIf(e,t,r){return!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredIfAccepted(e,t,r){return!this.checkAccepted(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredIfDeclined(e,t,r){return!this.checkDeclined(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredUnless(e,t,r){return!!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredWith(e,t,r){return this.collectRequiredsThenTest(e,t,r,e=>e.includes(!0))}checkRequiredWithAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,e=>!e.includes(!1))}checkRequiredWithout(e,t,r){return this.collectRequiredsThenTest(e,t,r,e=>e.includes(!1))}checkRequiredWithoutAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,e=>!e.includes(!0))}checkFilled(e,t,r){return void 0===t||this.checkRequired(e,t)}checkPresent(e,t,r){return void 0!==t}checkMissing(e,t,r){return void 0===t}checkMissingIf(e,t,r){return!this.isDependent(r)||this.checkMissing(e,t)}checkMissingUnless(e,t,r){return!!this.isDependent(r)||this.checkMissing(e,t)}checkMissingWith(e,t,r){return this.collectMissingsThenTest(e,t,r,e=>e.includes(!1))}checkMissingWithAll(e,t,r){return this.collectMissingsThenTest(e,t,r,e=>!e.includes(!0))}checkProhibited(e,t,r){return!this.checkRequired(e,t)}checkProhibitedIf(e,t,r){return!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibitedUnless(e,t,r){return!!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibits(e,t,r=[]){if(this.checkRequired(e,t))for(const e of r)if(this.checkRequired(e,this.validator.getValue(e)))return!1;return!0}checkSize(e,t,r){return this.validator.getSize(e,t)===parseFloat(r[0])}checkMin(e,t,r){return this.validator.getSize(e,t)>=parseFloat(r[0])}checkMax(e,t,r){return this.validator.getSize(e,t)<=parseFloat(r[0])}checkBetween(e,t,r){return this.checkMin(e,t,[r[0]])&&this.checkMax(e,t,[r[1]])}checkDigits(e,t,r,s=(e,t)=>e===t){return!!function(e){return-1===String(e).search(/[^0-9]/)}(t=String(t??""))&&s(t.length,parseInt(r[0],10),parseInt(r[1]??0,10))}checkMinDigits(e,t,r){return this.checkDigits(e,t,r,(e,t)=>e>=t)}checkMaxDigits(e,t,r){return this.checkDigits(e,t,r,(e,t)=>e<=t)}checkDigitsBetween(e,t,r){return this.checkDigits(e,t,r,(e,t,r)=>e>=t&&e<=r)}checkAlpha(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z]+$/i,/^[\p{L}\p{M}]+$/u,r.includes("ascii"))}checkAlphaDash(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9_-]+$/i,/^[\p{L}\p{M}\p{N}_-]+$/u,r.includes("ascii"))}checkAlphaNum(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9]+$/i,/^[\p{L}\p{M}\p{N}]+$/u,r.includes("ascii"))}checkAscii(e,t,r){return!/[^\x09\x10\x13\x0A\x0D\x20-\x7E]/.test(t)}checkRegex(e,t,r,s=!1){if("string"!=typeof t&&!n(t))return!1;const i=r.join(",");let[c,l,u]=i.match(/^\/(.*)\/([gimu]*)$/)??[];if(a(c))throw new Error(`Invalid regular expression pattern: ${i}`);u.includes("u")&&(l=l.replace(/\\A/g,"^").replace(/\\z/gi,"$").replace(/\\([pP])([CLMNPSZ])/g,"\\$1{$2}").replace(/\\\x\{([0-9a-f]+)\}/g,"\\u{$1}"));const h=new RegExp(l,u).test(t);return s?!h:h}checkNotRegex(e,t,r){return this.checkRegex(e,t,r,!0)}checkLowercase(e,t,r){return t===String(t).toLocaleLowerCase()}checkUppercase(e,t,r){return t===String(t).toLocaleUpperCase()}checkStartsWith(e,t,r=[]){t=String(t);for(const e of r)if(t.startsWith(e))return!0;return!1}checkDoesntStartWith(e,t,r){return!this.checkStartsWith(e,t,r)}checkEndsWith(e,t,r=[]){t=String(t);for(const e of r)if(t.endsWith(e))return!0;return!1}checkDoesntEndWith(e,t,r){return!this.checkEndsWith(e,t,r)}checkSame(e,t,r){return t===this.validator.getValue(r[0])}checkDifferent(e,t,r=[]){for(const e of r){const r=this.validator.getValue(e);if(void 0!==r&&t===r)return!1}return!0}checkConfirmed(e,t,r){return this.checkSame(e,t,[r[0]??e+"_confirmation"])}checkGt(e,t,r){return this.compareValues(e,t,r,(e,t)=>e>t)}checkGte(e,t,r){return this.compareValues(e,t,r,(e,t)=>e>=t)}checkLt(e,t,r){return this.compareValues(e,t,r,(e,t)=>e<t)}checkLte(e,t,r){return this.compareValues(e,t,r,(e,t)=>e<=t)}checkAfter(e,t,r){return this.compareDates(e,t,r,(e,t)=>e>t)}checkAfterOrEqual(e,t,r){return this.compareDates(e,t,r,(e,t)=>e>=t)}checkBefore(e,t,r){return this.compareDates(e,t,r,(e,t)=>e<t)}checkBeforeOrEqual(e,t,r){return this.compareDates(e,t,r,(e,t)=>e<=t)}checkDateEquals(e,t,r){return this.compareDates(e,t,r,(e,t)=>e===t)}checkDateFormat(e,t,r){const s=r[0].split(""),i={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let c="^";for(const e of s)Object.hasOwn(i,e)?c+=i[e]:c+="\\"+e;return c+="$",new RegExp(c).test(t)}checkContains(e,t,r=[]){if(!this.checkArray(e,t))return!1;for(const e of r)if(!t.includes(e))return!1;return!0}checkDoesntContain(e,t,r=[]){if(!this.checkArray(e,t))return!1;for(const e of r)if(t.includes(e))return!1;return!0}checkDistinct(e,t,i){const c=this.validator.getPrimaryAttribute(e);if(!c.includes("*"))return!0;const a=c.indexOf("*"),n=c.substring(0,a-1);let l;Object.hasOwn(this.#e,n)?l=this.#e[n]:(l=JSON.stringify(s(this.validator.getValue(n)??{})),this.#e[n]=l);const u=i.includes("ignore_case"),h=!u&&i.includes("strict"),o=r(String(t));let d=`"${r(c.substring(a)).replaceAll("\\*",'[^."]+')}":`,p=0;return d+=h?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,d+="[,}]+",p+=l.match(new RegExp(d,"g"+(u?"i":"")))?.length??0,1===p}checkInArray(e,t,r){const i=this.validator.getPrimaryAttribute(r[0]);if(!i.includes("*"))return!1;const c=this.validator.getValue(i.split(".*")[0])??{};return Object.values(s(c)).some(e=>e==t)}checkIn(e,t,r){if(!this.checkArray(e,t)||!this.validator.hasRule(e,"array"))return r.some(e=>e==t);for(const e of Object.values(t))if(!r.some(t=>t==e))return!1;return!0}checkNotIn(e,t,r){return!this.checkIn(e,t,r)}checkMimetypes(e,t,r){return!!this.checkFile(e,t)&&r.includes(t.type)}checkMimes(e,t,r=[]){return!!this.checkFile(e,t)&&(r.includes("jpg")&&!r.includes("jpeg")&&r.push("jpeg"),r.includes("jpeg")&&!r.includes("jpg")&&r.push("jpg"),r.includes(t.name.split(".").pop().toLowerCase()))}checkExtensions(e,t,r){return this.checkMimes(e,t,r)}async checkImage(e,t,r=[]){const s=["jpg","jpeg","png","gif","bmp","webp"];r.includes("allow_svg")&&s.push("svg");let i=this.checkMimes(e,t,s);return i&&"undefined"!=typeof FileReader?(await new Promise((e,r)=>{const s=new FileReader;s.onload=t=>e(t.target.result),s.onerror=r,s.readAsDataURL(t)}).then(async t=>{const r=new Image;r.src=t,await r.decode(),this.#t[e]=r}).catch(()=>{i=!1}),i):i}async checkDimensions(e,t,r=[]){if(!this.checkImage(e,t)||!Object.hasOwn(this.#t,e))return!1;const s={};for(const e of r){const[t,r]=e.split("=",2);if("ratio"===t&&r.includes("/")){const[e,i]=r.split("/",2).map(e=>parseFloat(e,10));s[t]=e/i}else s[t]=parseFloat(r,10)}const i=this.#t[e],c=i.naturalWidth,a=i.naturalHeight;return!(Object.hasOwn(s,"width")&&s.width!==c||Object.hasOwn(s,"height")&&s.height!==a||Object.hasOwn(s,"min_width")&&s.min_width>c||Object.hasOwn(s,"min_height")&&s.min_height>a||Object.hasOwn(s,"max_width")&&s.max_width<c||Object.hasOwn(s,"max_height")&&s.max_height<a)&&(!Object.hasOwn(s,"ratio")||Math.abs(s.ratio-c/a)<=1/(Math.max(c,a)+1))}checkEmail(e,t,r){if(!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(t)){return/^((?:[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]|[^\u0000-\u007F])+@(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?(?:\.(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?)+)*$/.test(t)}return!0}checkJson(e,t,r){try{JSON.parse(t)}catch(e){return!1}return!0}checkHexColor(e,t,r){return/^#(?:(?:[0-9a-f]{3}){1,2}|(?:[0-9a-f]{4}){1,2})$/i.test(t)}checkMacAddress(e,t,r){t=String(t);const s={"-":2,":":2,".":4};let i,c;for([i,c]of Object.entries(s))if(t.includes(i))break;const a=t.split(i);if(a.length!==12/c)return!1;for(const e of a)if(!new RegExp("^[0-9a-f]{"+c+"}$","i").test(e))return!1;return!0}checkIpv4(e,t,r){if(/[^\d.]/.test(t))return!1;const s=String(t).split(".");if(4!==s.length)return!1;for(const e of s)if(e<0||e>255)return!1;return!0}checkIpv6(e,t,r){if((t=String(t)).includes(":::")||t.split("::").length>2)return!1;const s=t.split(":");if(s.length<3||s.length>8)return!1;for(const e of s)if(""!==e&&!/^[0-9a-f]{1,4}$/i.test(e))return!1;return!0}checkIp(e,t,r){return this.checkIpv4(e,t,r)||this.checkIpv6(e,t,r)}checkTimezone(e,t,r){try{Intl.DateTimeFormat(void 0,{timeZone:t})}catch(e){if(String(e).toLowerCase().includes("invalid time zone"))return!1}return!0}checkUrl(e,t,r){try{new URL(t)}catch(e){return!1}return!0}checkUlid(e,t,r){return/[0-7][0-9A-HJKMNP-TV-Z]{25}/.test(t)}checkUuid(e,t,r){return/[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}/.test(t)}}class o{#r;keys(){return Object.keys(this.#r)}values(){return Object.values(this.#r)}entries(){return Object.entries(this.#r)}add(e,t){Object.hasOwn(this.#r,e)?this.#r[e].push(t):this.#r[e]=[t]}get(e){if(!e.includes("*"))return Object.hasOwn(this.#r,e)?this.#r[e]:{};const t=new RegExp("^"+e.replaceAll("*",".*?")+"$"),r={};for(const[e,s]of this.entries())t.test(e)&&(r[e]=s);return r}first(e){for(const t of Object.values(this.get(e)))return Array.isArray(t)?t[0]:t;return""}has(e){return""!==this.first(e)}remove(e){delete this.#r[e]}messages(){return this.#r}all(){const e=[];return this.values().forEach(t=>e.push(...t)),e}count(){let e=0;return this.values().forEach(t=>e+=t.length),e}isEmpty(){return 0===this.keys().length}isNotEmpty(){return!this.isEmpty()}sortByKeys(e){const t={};for(const r of e)Object.hasOwn(this.#r,r)&&(t[r]=this.#r[r]);this.#r=t}constructor(){this.#r={}}}class d{static#s;static#i={};static locale(e){this.#s=e}static setMessages(e,t){this.#i[e]=s(t)}static get(e){if(this.#i[this.#s]&&this.#i[this.#s][e])return this.#i[this.#s][e]}static has(e){return void 0!==this.get(e)}static set(e,t){l(t)?Object.assign(this.#i[this.#s],s(t,e)):"string"==typeof t&&(this.#i[this.#s][e]=t)}}class p{constructor(e){this.validator=e}replace(e,t){return Object.entries(t).forEach(([t,r])=>e=e.replaceAll(":"+t,r)),e}replaceDecimal(e,t,r,s){return this.replace(e,{decimal:s.join("-")})}replaceMultipleOf(e,t,r,s){return this.replace(e,{value:s[0]})}replaceAcceptedIf(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),value:this.validator.getDisplayableValue(s[0],this.validator.getValue(s[0]))})}replaceDeclinedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredArrayKeys(e,t,r,s){return this.replace(e,{values:s.map(e=>this.validator.getDisplayableValue(t,e)).join(", ")})}replaceRequiredIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfAccepted(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfDeclined(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredUnless(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),values:s.slice(1).map(e=>this.validator.getDisplayableValue(s[0],e)).join(", ")})}replaceRequiredWith(e,t,r,s){return this.replace(e,{values:s.map(e=>this.validator.getDisplayableAttribute(e)).join(" / ")})}replaceRequiredWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithout(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithoutAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceMissingUnless(e,t,r,s){return this.replace(this.replaceRequiredUnless(e,t,r,s),{value:this.validator.getDisplayableValue(s[0],s[1])})}replaceMissingWith(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceProhibitedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceProhibitedUnless(e,t,r,s){return this.replaceRequiredUnless(e,t,r,s)}replaceProhibits(e,t,r,s){return this.replace(e,{other:s.map(e=>this.validator.getDisplayableAttribute(e)).join(" / ")})}replaceSize(e,t,r,s){return this.replace(e,{size:s[0]})}replaceMin(e,t,r,s){return this.replace(e,{min:s[0]})}replaceMax(e,t,r,s){return this.replace(e,{max:s[0]})}replaceBetween(e,t,r,s){return this.replace(e,{min:s[0],max:s[1]})}replaceDigits(e,t,r,s){return this.replace(e,{digits:s[0]})}replaceMinDigits(e,t,r,s){return this.replaceMin(e,t,r,s)}replaceMaxDigits(e,t,r,s){return this.replaceMax(e,t,r,s)}replaceDigitsBetween(e,t,r,s){return this.replaceBetween(e,t,r,s)}replaceStartsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntStartWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceEndsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntEndWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceSame(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceDifferent(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceGt(e,t,r,s){const i=this.validator.getValue(s[0]);return this.replace(e,{value:i?this.validator.getSize(s[0],i):this.validator.getDisplayableAttribute(s[0])})}replaceGte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLt(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceAfter(e,t,r,s){const i=s[0];return this.replace(e,{date:this.validator.hasAttribute(i)?this.validator.getDisplayableAttribute(i):i})}replaceAfterOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBefore(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBeforeOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateEquals(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateFormat(e,t,r,s){return this.replace(e,{format:s[0]})}replaceInArray(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceNotIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntContain(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceMimetypes(e,t,r,s){return this.replace(e,{values:s.join(", ")})}replaceMimes(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}replaceExtensions(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}}class f{static#c={};static#a={};static#n=["active_url","bail","can","current_password","enum","exclude","exclude_if","exclude_unless","exclude_with","exclude_without","exists","nullable","sometimes","unique"];static#l=["accepted","accepted_if","declined","declined_if","filled","missing","missing_if","missing_unless","missing_with","missing_with_all","present","required","required_if","required_if_accepted","required_if_declined","required_unless","required_with","required_with_all","required_without","required_without_all"];#r;#u;#h;#o;#d;#p;#f;#g;#m;#k;#b;#y;static setLocale(e){d.locale(e)}static setMessages(e,t){d.setMessages(e,t)}static addChecker(e,t,r){f.#c[e]=t,r&&d.set(e,r)}static addImplicitChecker(e,t,r){f.addChecker(e,t,r),f.#l.push(e)}static addReplacer(e,t){f.#a[e]=t}static addDummyRule(e){f.#n.push(e)}constructor(e={},r={},s={},i={},c={}){this.#m=[],this.#k={},this.#b=!1,this.#y=!1,this.arrayRules=["array","list"],this.fileRules=["file","image","mimetypes","mimes"],this.stringRules=["string","alpha","alpha_dash","alpha_num","ascii","email"],this.numericRules=["decimal","numeric","integer"],this.sizeRules=["size","between","min","max","gt","lt","gte","lte"],this.setProperties(e,r,s,i,c),this.#p=new h(this),this.#f=new p(this);for(const[e,r]of Object.entries(f.#c))this.#p[t("check_"+e)]=r;for(const[e,r]of Object.entries(f.#a))this.#f[t("replace_"+e)]=r;this.#g=new o}setProperties(e={},t={},r={},i={},c={}){return this.#r=e,this.#u=this.parseRules(t),this.#h=r,this.#o=i,this.#d=s(c),this}setData(e){return this.#r=e,this}setRules(e){return this.#u=this.parseRules(e),this}setCustomMessages(e){return this.#h=e,this}setCustomAttributes(e){return this.#o=e,this}setCustomValues(e){return this.#d=s(e),this}addImplicitAttribute(e,t){return this.#k[e]=t,this}stopOnFirstFailure(e=!0){return this.#b=e,this}alwaysBail(e=!0){return this.#y=e,this}parseRules(e){const t={};for(const[r,s]of Object.entries(e)){const e=r.includes("*")?this.parseWildcardAttribute(r):[r];for(const r of e){const e=[];for(const t of this.parseAttributeRules(s))e.push(this.parseAttributeRule(t));t[r]=e}}return t}parseWildcardAttribute(e){const t=[],r=e.indexOf("*"),s=e.substring(0,r-1),i=e.substring(r+2),c=this.getValue(s);return Array.isArray(c)||l(c)?(Object.entries(c).forEach(([r,c])=>{const a=`${s}.${r}.${i}`.replace(/\.$/,""),n=a.includes("*")?this.parseWildcardAttribute(a):[a];t.push(...n),n.forEach(t=>this.#k[t]=e)}),t):[e]}parseAttributeRules(e){return Array.isArray(e)?e:"function"==typeof e?[e]:String(e).split("|")}parseAttributeRule(e){if("function"==typeof e)return[e,[]];let t,r;if(Array.isArray(e))t=e[0]??"",r=e.slice(1);else{const s=e.indexOf(":");-1===s?(t=e,r=[]):(t=e.substring(0,s),r=function(e){const t=[];let r="",s=!1;for(let i=0;i<e.length;i++){const c=e[i];'"'===c?s&&'"'===e[i+1]?(r+='"',i++):(s=!s,s&&(r=r.trim())):","!==c||s?r+=c:(t.push(r),r="")}return t.push(r),t}(e.substring(s+1)))}return[this.normalizeRuleName(t),r]}normalizeRuleName(e){return{int:"integer",bool:"boolean"}[e]??e}async validate(){this.#p.clearCaches(),this.#g=new o;const e=[],r=new Set;for(const[e,r]of Object.entries(this.#u))for(const[e]of r)if(""!==e&&"function"!=typeof e&&"function"!=typeof this.#p[t("check_"+e)]&&!f.#n.includes(e))throw new Error(`Invalid validation rule: ${e}`);for(const[s,i]of Object.entries(this.#u)){let c=this.getValue(s);const n=e=>i.some(t=>t[0]===e);n("sometimes")&&void 0===c?r.add(s):e.push(async()=>{const e=this.#y||n("bail"),l=n("nullable");let u=!0;for(const[n,h]of i){if(""===n||"function"!=typeof n&&!f.#l.includes(n)&&(void 0===c||"string"==typeof c&&""===c.trim()||l&&null===c)){r.add(s);continue}let i,o,d;const p=(()=>{if("function"==typeof n)return n;{const e=this.#p[t("check_"+n)]??null;return null===e&&f.#n.includes(n)?()=>!0:e}})();if(null===p)throw new Error(`Invalid validation rule: ${n}`);if(i=await p.call(this.#p,s,c,h),"boolean"==typeof i&&(i={success:i}),({success:o,message:d=""}=i),!o&&(u=!1,d=a(d)?this.getMessage(s,n):d,d=this.makeReplacements(d,s,n,h),this.#g.add(s,d),e||f.#l.includes(n)))break}return u})}if(this.#b){for(const t of e)if(!await t())break}else await Promise.allSettled(e.map(e=>e())).then(e=>{for(const t of e)if("rejected"===t.status)throw t.reason}),this.#g.sortByKeys(Object.keys(this.#u));return this.#m=[...r],this.#g}async passes(){return await this.validate(),!this.#g.isNotEmpty()}async fails(){return!await this.passes()}getMessage(e,t){if("function"==typeof t)return"";const r=this.getValue(e);let s;e=this.getPrimaryAttribute(e);for(const r of[`${e}.${t}`,t])if(Object.hasOwn(this.#h,r)){s=this.#h[r];break}if(!s){let i=t;this.sizeRules.includes(i)&&(Array.isArray(r)||l(r)||this.hasRule(e,this.arrayRules)?i+=".array":r instanceof File||this.hasRule(e,this.fileRules)?i+=".file":this.hasRule(e,this.stringRules)?i+=".string":n(r)||this.hasRule(e,this.numericRules)?i+=".numeric":i+=".string"),s=d.get(i)}return s??`validation.${t}`}makeReplacements(e,r,s,i){const c=this.getDisplayableAttribute(r),a=this.getValue(r),n={attribute:c,ATTRIBUTE:c.toLocaleUpperCase(),Attribute:c.charAt(0).toLocaleUpperCase()+c.substring(1),input:this.getDisplayableValue(r,a)};for(const[t,r]of Object.entries(n))e=e.replaceAll(":"+t,r);const l=r.match(/\.(\d+)\.?/),u=null===l?-1:parseInt(l[1],10);if(-1!==u&&(e=e.replaceAll(":index",u).replaceAll(":position",u+1)),"string"==typeof s){const c=this.#f[t("replace_"+s)]??null;c&&(e=c.call(this.#f,e,r,s,i))}return e}getDisplayableAttribute(e){const t=this.getPrimaryAttribute(e);for(const r of[e,t]){if(Object.hasOwn(this.#o,r))return this.#o[r];if(d.has(`attributes.${r}`))return d.get(`attributes.${r}`)}return Object.hasOwn(this.#k,e)?e:(r=e,r.replace(/(.)(?=[A-Z])/g,e=>e+"_").toLowerCase()).replaceAll("_"," ");var r}getDisplayableValue(e,t){const r=`${e=this.getPrimaryAttribute(e)}.${t}`;return a(t)?"empty":"boolean"==typeof t||this.hasRule(e,"boolean")?Number(t)?"true":"false":Object.hasOwn(this.#d,r)?this.#d[r]:d.has(`values.${r}`)?d.get(`values.${r}`):t}getSize(e,t){return a(t)?0:this.hasRule(e,this.stringRules)?String(t).length:n(t)&&this.hasRule(e,this.numericRules)?parseFloat("string"==typeof t?t.trim():t,10):t instanceof File?t.size/1024:l(t)?Object.keys(t).length:Object.hasOwn(t,"length")?t.length:t}getRule(e){return e=this.getPrimaryAttribute(e),this.#u[e]??{}}hasRule(e,t){if(e=this.getPrimaryAttribute(e),t="string"==typeof t?[t]:t,!Object.hasOwn(this.#u,e))return!1;for(const r of t)if(this.#u[e].some(e=>e[0]===r))return!0;return!1}getPrimaryAttribute(e){return Object.hasOwn(this.#k,e)?this.#k[e]:e}hasAttribute(e){return void 0!==this.getValue(e)}getValue(e){return function(e,t,r){const s=t.split(".");let i=e;for(const e of s){if(!Object.hasOwn(i,e))return r;i=i[e]}return i}(this.#r,e)}errors(){return this.#g}skippedAttributes(){return this.#m}}return e.Checkers=h,e.ErrorBag=o,e.Lang=d,e.Replacers=p,e.Validator=f,e}({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quival",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "description": "Data validation à la Laravel Validation",
5
5
  "author": "Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>",
6
6
  "license": "MIT",
@@ -23,10 +23,10 @@
23
23
  "url": "https://github.com/apih/quival"
24
24
  },
25
25
  "devDependencies": {
26
- "@rollup/plugin-node-resolve": "^15.0.2",
26
+ "@rollup/plugin-node-resolve": "^16.0.1",
27
27
  "@rollup/plugin-swc": "^0.4.0",
28
28
  "@rollup/plugin-terser": "^0.4.1",
29
- "mocha": "^10.2.0",
29
+ "mocha": "^11.1.0",
30
30
  "prettier": "^3.2.5",
31
31
  "rollup": "^4.6.1",
32
32
  "rollup-plugin-prettier": "^4.1.1"
package/src/Checkers.js CHANGED
@@ -39,11 +39,11 @@ export default class Checkers {
39
39
  let result = [];
40
40
 
41
41
  for (const other of parameters) {
42
- result.push(this.checkMissing(other));
42
+ result.push(this.checkMissing(other, this.validator.getValue(other)));
43
43
  }
44
44
 
45
45
  if (callback(result)) {
46
- return this.checkMissing(attribute);
46
+ return this.checkMissing(attribute, value);
47
47
  }
48
48
 
49
49
  return true;
@@ -116,12 +116,12 @@ export default class Checkers {
116
116
  }
117
117
 
118
118
  // Type
119
- checkArray(attribute, value, parameters) {
119
+ checkArray(attribute, value, parameters = []) {
120
120
  if (!(Array.isArray(value) || isPlainObject(value))) {
121
121
  return false;
122
122
  }
123
123
 
124
- if (parameters && parameters.length > 0) {
124
+ if (parameters.length > 0) {
125
125
  for (const key of Object.keys(value)) {
126
126
  if (!parameters.includes(key)) {
127
127
  return false;
@@ -136,7 +136,11 @@ export default class Checkers {
136
136
  return Array.isArray(value);
137
137
  }
138
138
 
139
- checkBoolean(attribute, value, parameters) {
139
+ checkBoolean(attribute, value, parameters = []) {
140
+ if (parameters.includes('strict')) {
141
+ return [true, false].includes(value);
142
+ }
143
+
140
144
  return [true, false, 0, 1, '0', '1'].includes(value);
141
145
  }
142
146
 
@@ -148,11 +152,19 @@ export default class Checkers {
148
152
  return value instanceof File;
149
153
  }
150
154
 
151
- checkInteger(attribute, value, parameters) {
152
- return String(parseInt(value, 10)) === String(value);
155
+ checkInteger(attribute, value, parameters = []) {
156
+ if (!parameters.includes('strict') && typeof value === 'string') {
157
+ value = parseFloat(value);
158
+ }
159
+
160
+ return Number.isInteger(value);
153
161
  }
154
162
 
155
- checkNumeric(attribute, value, parameters) {
163
+ checkNumeric(attribute, value, parameters = []) {
164
+ if (parameters.includes('strict')) {
165
+ return typeof value === 'number';
166
+ }
167
+
156
168
  return isNumeric(value);
157
169
  }
158
170
 
@@ -161,7 +173,7 @@ export default class Checkers {
161
173
  }
162
174
 
163
175
  // Numeric
164
- checkDecimal(attribute, value, parameters) {
176
+ checkDecimal(attribute, value, parameters = []) {
165
177
  if (!this.checkNumeric(attribute, value)) {
166
178
  return false;
167
179
  }
@@ -234,7 +246,7 @@ export default class Checkers {
234
246
  return value.length > 0;
235
247
  }
236
248
 
237
- checkRequiredArrayKeys(attribute, value, parameters) {
249
+ checkRequiredArrayKeys(attribute, value, parameters = []) {
238
250
  if (!this.checkArray(attribute, value)) {
239
251
  return false;
240
252
  }
@@ -312,12 +324,12 @@ export default class Checkers {
312
324
 
313
325
  // Missing
314
326
  checkMissing(attribute, value, parameters) {
315
- return !this.validator.hasAttribute(attribute);
327
+ return typeof value === 'undefined';
316
328
  }
317
329
 
318
330
  checkMissingIf(attribute, value, parameters) {
319
331
  if (this.isDependent(parameters)) {
320
- return this.checkMissing(attribute);
332
+ return this.checkMissing(attribute, value);
321
333
  }
322
334
 
323
335
  return true;
@@ -325,7 +337,7 @@ export default class Checkers {
325
337
 
326
338
  checkMissingUnless(attribute, value, parameters) {
327
339
  if (!this.isDependent(parameters)) {
328
- return this.checkMissing(attribute);
340
+ return this.checkMissing(attribute, value);
329
341
  }
330
342
 
331
343
  return true;
@@ -360,7 +372,7 @@ export default class Checkers {
360
372
  return true;
361
373
  }
362
374
 
363
- checkProhibits(attribute, value, parameters) {
375
+ checkProhibits(attribute, value, parameters = []) {
364
376
  if (this.checkRequired(attribute, value)) {
365
377
  for (const parameter of parameters) {
366
378
  if (this.checkRequired(parameter, this.validator.getValue(parameter))) {
@@ -466,7 +478,7 @@ export default class Checkers {
466
478
  return value === String(value).toLocaleUpperCase();
467
479
  }
468
480
 
469
- checkStartsWith(attribute, value, parameters) {
481
+ checkStartsWith(attribute, value, parameters = []) {
470
482
  value = String(value);
471
483
 
472
484
  for (const parameter of parameters) {
@@ -482,7 +494,7 @@ export default class Checkers {
482
494
  return !this.checkStartsWith(attribute, value, parameters);
483
495
  }
484
496
 
485
- checkEndsWith(attribute, value, parameters) {
497
+ checkEndsWith(attribute, value, parameters = []) {
486
498
  value = String(value);
487
499
 
488
500
  for (const parameter of parameters) {
@@ -505,7 +517,7 @@ export default class Checkers {
505
517
  return value === other;
506
518
  }
507
519
 
508
- checkDifferent(attribute, value, parameters) {
520
+ checkDifferent(attribute, value, parameters = []) {
509
521
  for (const parameter of parameters) {
510
522
  const other = this.validator.getValue(parameter);
511
523
 
@@ -594,7 +606,7 @@ export default class Checkers {
594
606
  }
595
607
 
596
608
  // Array / Object
597
- checkContains(attribute, value, parameters) {
609
+ checkContains(attribute, value, parameters = []) {
598
610
  if (!this.checkArray(attribute, value)) {
599
611
  return false;
600
612
  }
@@ -608,6 +620,20 @@ export default class Checkers {
608
620
  return true;
609
621
  }
610
622
 
623
+ checkDoesntContain(attribute, value, parameters = []) {
624
+ if (!this.checkArray(attribute, value)) {
625
+ return false;
626
+ }
627
+
628
+ for (const parameter of parameters) {
629
+ if (value.includes(parameter)) {
630
+ return false;
631
+ }
632
+ }
633
+
634
+ return true;
635
+ }
636
+
611
637
  checkDistinct(attribute, value, parameters) {
612
638
  const unparsed = this.validator.getPrimaryAttribute(attribute);
613
639
 
@@ -690,7 +716,7 @@ export default class Checkers {
690
716
  return false;
691
717
  }
692
718
 
693
- checkMimes(attribute, value, parameters) {
719
+ checkMimes(attribute, value, parameters = []) {
694
720
  if (!this.checkFile(attribute, value)) {
695
721
  return false;
696
722
  }
@@ -710,8 +736,14 @@ export default class Checkers {
710
736
  return this.checkMimes(attribute, value, parameters);
711
737
  }
712
738
 
713
- async checkImage(attribute, value, parameters) {
714
- let result = this.checkMimes(attribute, value, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp']);
739
+ async checkImage(attribute, value, parameters = []) {
740
+ const mimes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
741
+
742
+ if (parameters.includes('allow_svg')) {
743
+ mimes.push('svg');
744
+ }
745
+
746
+ let result = this.checkMimes(attribute, value, mimes);
715
747
 
716
748
  if (!result || typeof FileReader === 'undefined') {
717
749
  return result;
@@ -738,7 +770,7 @@ export default class Checkers {
738
770
  return result;
739
771
  }
740
772
 
741
- async checkDimensions(attribute, value, parameters) {
773
+ async checkDimensions(attribute, value, parameters = []) {
742
774
  if (!this.checkImage(attribute, value) || !Object.hasOwn(this.#imageCache, attribute)) {
743
775
  return false;
744
776
  }
package/src/Replacers.js CHANGED
@@ -251,6 +251,10 @@ export default class Replacers {
251
251
  return this.replaceRequiredArrayKeys(message, attribute, rule, parameters);
252
252
  }
253
253
 
254
+ replaceDoesntContain(message, attribute, rule, parameters) {
255
+ return this.replaceRequiredArrayKeys(message, attribute, rule, parameters);
256
+ }
257
+
254
258
  // File
255
259
  replaceMimetypes(message, attribute, rule, parameters) {
256
260
  return this.replace(message, {
package/src/Validator.js CHANGED
@@ -264,7 +264,7 @@ export default class Validator {
264
264
  this.#errors = new ErrorBag();
265
265
 
266
266
  const tasks = [];
267
- const skippedAttributes = [];
267
+ const skippedAttributes = new Set();
268
268
 
269
269
  for (const [attribute, rules] of Object.entries(this.#rules)) {
270
270
  for (const [rule] of rules) {
@@ -285,7 +285,7 @@ export default class Validator {
285
285
  const hasRule = (ruleName) => rules.some((rule) => rule[0] === ruleName);
286
286
 
287
287
  if (hasRule('sometimes') && typeof value === 'undefined') {
288
- skippedAttributes.push(attribute);
288
+ skippedAttributes.add(attribute);
289
289
  continue;
290
290
  }
291
291
 
@@ -301,7 +301,7 @@ export default class Validator {
301
301
  !Validator.#implicitRules.includes(rule) &&
302
302
  (typeof value === 'undefined' || (typeof value === 'string' && value.trim() === '') || (isNullable && value === null)))
303
303
  ) {
304
- skippedAttributes.push(attribute);
304
+ skippedAttributes.add(attribute);
305
305
  continue;
306
306
  }
307
307
 
@@ -366,7 +366,7 @@ export default class Validator {
366
366
  this.#errors.sortByKeys(Object.keys(this.#rules));
367
367
  }
368
368
 
369
- this.#skippedAttributes = skippedAttributes.filter((value, index, array) => array.indexOf(value) === index);
369
+ this.#skippedAttributes = [...skippedAttributes];
370
370
 
371
371
  return this.#errors;
372
372
  }
package/src/locales/en.js CHANGED
@@ -36,6 +36,7 @@ export default {
36
36
  digits_between: 'The :attribute field must be between :min and :max digits.',
37
37
  dimensions: 'The :attribute field has invalid image dimensions.',
38
38
  distinct: 'The :attribute field has a duplicate value.',
39
+ doesnt_contain: 'The :attribute field must not contain any of the following: :values.',
39
40
  doesnt_end_with: 'The :attribute field must not end with one of the following: :values.',
40
41
  doesnt_start_with: 'The :attribute field must not start with one of the following: :values.',
41
42
  email: 'The :attribute field must be a valid email address.',
package/src/locales/ms.js CHANGED
@@ -36,6 +36,7 @@ export default {
36
36
  digits_between: 'Medan :attribute mesti mengandungi antara :min dan :max digit.',
37
37
  dimensions: 'Medan :attribute mempunyai dimensi imej yang tidak sah.',
38
38
  distinct: 'Medan :attribute mempunyai nilai yang berulang.',
39
+ doesnt_contain: 'Medan :attribute tidak boleh mengandungi salah satu daripada berikut: :values.',
39
40
  doesnt_end_with: 'Medan :attribute tidak boleh berakhir dengan salah satu daripada berikut: :values.',
40
41
  doesnt_start_with: 'Medan :attribute tidak boleh bermula dengan salah satu daripada berikut: :values.',
41
42
  email: 'Medan :attribute mesti alamat emel yang sah.',
@@ -508,6 +508,26 @@ describe('Validation', () => {
508
508
  assert(await validator.passes());
509
509
  }
510
510
  });
511
+
512
+ const rules2 = { field: 'boolean:strict' };
513
+
514
+ it(`Passes when the field is a boolean in strict mode`, async () => {
515
+ const validator = new Validator({}, rules2);
516
+
517
+ for (const field of [true, false]) {
518
+ validator.setData({ field });
519
+ assert(await validator.passes());
520
+ }
521
+ });
522
+
523
+ it(`Fails when the field is not a boolean in strict mode`, async () => {
524
+ const validator = new Validator({}, rules2);
525
+
526
+ for (const field of [0, 1, '0', '1']) {
527
+ validator.setData({ field });
528
+ assert(await validator.fails());
529
+ }
530
+ });
511
531
  });
512
532
 
513
533
  describe(`Rule 'confirmed'`, () => {
@@ -842,6 +862,25 @@ describe('Validation', () => {
842
862
  });
843
863
  });
844
864
 
865
+ describe(`Rule 'doesnt_contain'`, () => {
866
+ const rules = { field: 'doesnt_contain:abc,def' };
867
+
868
+ it(`Passes when the field does not contain provided values`, async () => {
869
+ const validator = new Validator({ field: ['ghi', 'jkl', 'mno'] }, rules);
870
+ assert(await validator.passes());
871
+ });
872
+
873
+ it(`Fails when the field contains provided values`, async () => {
874
+ const validator = new Validator({ field: ['def', 'ghi'] }, rules);
875
+ assert(await validator.fails());
876
+ });
877
+
878
+ it(`Fails when the field is not an array`, async () => {
879
+ const validator = new Validator({ field: 'abc' }, rules);
880
+ assert(await validator.fails());
881
+ });
882
+ });
883
+
845
884
  describe(`Rule 'doesnt_end_with'`, () => {
846
885
  const rules = { field: 'doesnt_end_with:foo,bar' };
847
886
 
@@ -1311,6 +1350,16 @@ describe('Validation', () => {
1311
1350
  const validator = new Validator({ field: new File('hello.txt', 5 * 1024, 'text/plain') }, rules);
1312
1351
  assert(await validator.fails());
1313
1352
  });
1353
+
1354
+ it(`Passes when the field is an SVG image and the 'allow_svg' flag is set`, async () => {
1355
+ const validator = new Validator({ field: new File('hello.svg', 5 * 1024, 'image/svg+xml') }, { field: 'image:allow_svg' });
1356
+ assert(await validator.passes());
1357
+ });
1358
+
1359
+ it(`Fails when the field is an SVG image and the 'allow_svg' flag is not set`, async () => {
1360
+ const validator = new Validator({ field: new File('hello.svg', 5 * 1024, 'image/svg+xml') }, { field: 'image' });
1361
+ assert(await validator.fails());
1362
+ });
1314
1363
  });
1315
1364
 
1316
1365
  describe(`Rule 'in'`, () => {
@@ -1363,6 +1412,9 @@ describe('Validation', () => {
1363
1412
  it(`Fails when the field is a decimal`, async () => {
1364
1413
  const validator = new Validator({ field: 123.45 }, rules);
1365
1414
  assert(await validator.fails());
1415
+
1416
+ validator.setData({ field: '123.45' });
1417
+ assert(await validator.fails());
1366
1418
  });
1367
1419
 
1368
1420
  it(`Fails when the field is not a number`, async () => {
@@ -1386,6 +1438,18 @@ describe('Validation', () => {
1386
1438
  validator.setData({ field: '123' });
1387
1439
  assert(await validator.passes());
1388
1440
  });
1441
+
1442
+ const rules2 = { field: 'integer:strict' };
1443
+
1444
+ it(`Passes when the field is an integer in strict mode`, async () => {
1445
+ const validator = new Validator({ field: 123 }, rules2);
1446
+ assert(await validator.passes());
1447
+ });
1448
+
1449
+ it(`Fails when the field is not an integer in strict mode`, async () => {
1450
+ const validator = new Validator({ field: '123' }, rules2);
1451
+ assert(await validator.fails());
1452
+ });
1389
1453
  });
1390
1454
 
1391
1455
  describe(`Rule 'ip'`, () => {
@@ -2256,6 +2320,24 @@ describe('Validation', () => {
2256
2320
  validator.setData({ field: [1, 2, 3] });
2257
2321
  assert(await validator.fails());
2258
2322
  });
2323
+
2324
+ const rules2 = { field: 'numeric:strict' };
2325
+
2326
+ it(`Passes when the field is a number in strict mode`, async () => {
2327
+ const validator = new Validator({ field: 123 }, rules2);
2328
+ assert(await validator.passes());
2329
+
2330
+ validator.setData({ field: 123.45 });
2331
+ assert(await validator.passes());
2332
+ });
2333
+
2334
+ it(`Fails when the field is not a number in strict mode`, async () => {
2335
+ const validator = new Validator({ field: '123' }, rules2);
2336
+ assert(await validator.fails());
2337
+
2338
+ validator.setData({ field: '123.45' });
2339
+ assert(await validator.fails());
2340
+ });
2259
2341
  });
2260
2342
 
2261
2343
  describe(`Rule 'present'`, () => {