@warlock.js/seal 5.45.0 → 5.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to `@warlock.js/seal` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.47.0 - 2026-11-06
8
+
9
+ ### Fixed
10
+
11
+ - **`v.array()` accepts one uploaded file** — a lone uploaded file (a multipart part sent without `[]`) is wrapped into a one-element array before validation, and the validated output carries the array. Strings and other scalars are not wrapped and still fail the array rule.
12
+
13
+ ## 5.46.0 - 2026-11-06
14
+
15
+ ### Changed
16
+
17
+ - `requiredWith`, `requiredWithout` and the rest of the unsuffixed `required*` rules now say, in their JSDoc and in the docs, that the other field is looked up from the root of the validated data. Inside a nested object such as `address: { en, ar }`, use the `Sibling` variant (`requiredWithoutSibling("ar")`). Behaviour is unchanged.
18
+
7
19
  ## 5.40.0 - 2026-10-29
8
20
 
9
21
  ### Changed
package/cjs/index.cjs CHANGED
@@ -562,6 +562,20 @@ const stringMutator = async (value) => {
562
562
  //#endregion
563
563
  //#region ../../packages/seal/src/validators/array-validator.ts
564
564
  /**
565
+ * Brand carried by uploaded file objects (see core's `UploadedFile`). Seal does
566
+ * not depend on core, so it recognises an upload by this registered symbol.
567
+ */
568
+ const UPLOADED_FILE_BRAND = Symbol.for("warlock.uploadedFile");
569
+ /**
570
+ * A multipart request with one part named `files` (no `[]`) delivers a single
571
+ * uploaded file, because browsers cannot express a one-element list otherwise.
572
+ * Only uploaded files are wrapped — strings and other scalars stay as they are
573
+ * so they still fail the array rule.
574
+ */
575
+ function wrapSingleUpload(value) {
576
+ return value !== null && typeof value === "object" && value[UPLOADED_FILE_BRAND] === true ? [value] : value;
577
+ }
578
+ /**
565
579
  * Array validator class
566
580
  */
567
581
  var ArrayValidator = class extends require_required_methods.BaseValidator {
@@ -669,7 +683,8 @@ var ArrayValidator = class extends require_required_methods.BaseValidator {
669
683
  * so the parent ObjectValidator can omit the key. Without this, optional array
670
684
  * fields would silently materialise as `[]` in the validated output.
671
685
  */
672
- async validate(data, context) {
686
+ async validate(input, context) {
687
+ const data = wrapSingleUpload(input);
673
688
  const valueForRules = data ?? this.getDefaultValue();
674
689
  const mutatedData = await this.mutate(valueForRules, context);
675
690
  const result = await this.validateRules(data, context);