kanun 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -49,10 +49,12 @@ function getValidatorContext() {
49
49
  * @returns
50
50
  */
51
51
  function useValidatorContext(context = {}) {
52
- const nextContext = {
53
- ...getValidatorContext(),
54
- ...context
55
- };
52
+ const currentContext = validatorContextStorage.getStore();
53
+ if (currentContext) {
54
+ Object.assign(currentContext, context);
55
+ return currentContext;
56
+ }
57
+ const nextContext = { ...context };
56
58
  validatorContextStorage.enterWith(nextContext);
57
59
  return nextContext;
58
60
  }
@@ -1087,6 +1089,7 @@ var validateAttributes = class {
1087
1089
  */
1088
1090
  validateRequired(value) {
1089
1091
  if (value === null || typeof value === "undefined") return false;
1092
+ else if (typeof Blob !== "undefined" && value instanceof Blob) return true;
1090
1093
  else if (typeof value === "string" && value.trim() === "") return false;
1091
1094
  else if (Array.isArray(value) && value.length < 1) return false;
1092
1095
  else if (typeof value === "object" && Object.keys(value).length < 1) return false;
@@ -2355,7 +2358,7 @@ var BaseValidator = class BaseValidator {
2355
2358
  [rule, parameters] = validationRuleParser.parse(rule);
2356
2359
  const keys = this.getExplicitKeys(attribute);
2357
2360
  if (keys.length > 0 && parameters.length > 0) parameters = this.replaceAsterisksInParameters(parameters, keys);
2358
- const value = deepFind(this.data, attribute);
2361
+ const value = this.getAttributeValue(attribute);
2359
2362
  const validatable = this.isValidatable(attribute, value, rule);
2360
2363
  if (rule instanceof IRuleContract) return validatable ? this.validateUsingCustomRule(attribute, value, rule) : void 0;
2361
2364
  const method = `validate${buildValidationMethodName(rule)}`;
@@ -2423,14 +2426,14 @@ var BaseValidator = class BaseValidator {
2423
2426
  * Determine if the attribute is validatable.
2424
2427
  */
2425
2428
  isValidatable(attribute, value, rule) {
2426
- return this.presentOrRuleIsImplicit(attribute, value, rule) && this.passesOptionalCheck(attribute) && this.isNotNullIfMarkedAsNullable(attribute, rule);
2429
+ return this.presentOrRuleIsImplicit(attribute, value, rule) && this.passesOptionalCheck(attribute) && this.isNotNullIfMarkedAsNullable(attribute, value, rule);
2427
2430
  }
2428
2431
  /**
2429
2432
  * Determine if the field is present, or the rule implies required.
2430
2433
  */
2431
2434
  presentOrRuleIsImplicit(attribute, value, rule) {
2432
2435
  if (typeof value === "string" && value.trim() === "") return isImplicitRule(rule);
2433
- return typeof deepFind(this.data, attribute) !== "undefined" || isImplicitRule(rule);
2436
+ return typeof value !== "undefined" || isImplicitRule(rule);
2434
2437
  }
2435
2438
  /**
2436
2439
  * Determine if the attribute passes any optional check.
@@ -2438,14 +2441,23 @@ var BaseValidator = class BaseValidator {
2438
2441
  passesOptionalCheck(attribute) {
2439
2442
  if (!validationRuleParser.hasRule(attribute, ["sometimes"], this.rules)) return true;
2440
2443
  const data = validationData.initializeAndGatherData(attribute, this.data);
2441
- return Object.prototype.hasOwnProperty.call(data, attribute) || Object.prototype.hasOwnProperty.call(this.data, attribute);
2444
+ const requestFiles = validationData.initializeAndGatherData(attribute, this.getContext().requestFiles ?? {});
2445
+ return Object.prototype.hasOwnProperty.call(data, attribute) || Object.prototype.hasOwnProperty.call(this.data, attribute) || Object.prototype.hasOwnProperty.call(requestFiles, attribute) || Object.prototype.hasOwnProperty.call(this.getContext().requestFiles ?? {}, attribute);
2442
2446
  }
2443
2447
  /**
2444
2448
  * Determine if the attribute fails the nullable check.
2445
2449
  */
2446
- isNotNullIfMarkedAsNullable(attribute, rule) {
2450
+ isNotNullIfMarkedAsNullable(attribute, value, rule) {
2447
2451
  if (isImplicitRule(rule) || !validationRuleParser.hasRule(attribute, ["nullable"], this.rules)) return true;
2448
- return deepFind(this.data, attribute) !== null;
2452
+ return value !== null;
2453
+ }
2454
+ /**
2455
+ * Resolve an attribute value from validator data first, then request-scoped file context.
2456
+ */
2457
+ getAttributeValue(attribute) {
2458
+ const dataValue = deepFind(this.data, attribute);
2459
+ if (typeof dataValue !== "undefined") return dataValue;
2460
+ return deepFind(this.getContext().requestFiles ?? {}, attribute);
2449
2461
  }
2450
2462
  /**
2451
2463
  * Get the primary attribute name
package/dist/index.d.ts CHANGED
@@ -603,6 +603,10 @@ declare class BaseValidator<D extends GenericObject = GenericObject> {
603
603
  * Determine if the attribute fails the nullable check.
604
604
  */
605
605
  private isNotNullIfMarkedAsNullable;
606
+ /**
607
+ * Resolve an attribute value from validator data first, then request-scoped file context.
608
+ */
609
+ private getAttributeValue;
606
610
  /**
607
611
  * Get the primary attribute name
608
612
  *
package/dist/index.js CHANGED
@@ -19,10 +19,12 @@ function getValidatorContext() {
19
19
  * @returns
20
20
  */
21
21
  function useValidatorContext(context = {}) {
22
- const nextContext = {
23
- ...getValidatorContext(),
24
- ...context
25
- };
22
+ const currentContext = validatorContextStorage.getStore();
23
+ if (currentContext) {
24
+ Object.assign(currentContext, context);
25
+ return currentContext;
26
+ }
27
+ const nextContext = { ...context };
26
28
  validatorContextStorage.enterWith(nextContext);
27
29
  return nextContext;
28
30
  }
@@ -1057,6 +1059,7 @@ var validateAttributes = class {
1057
1059
  */
1058
1060
  validateRequired(value) {
1059
1061
  if (value === null || typeof value === "undefined") return false;
1062
+ else if (typeof Blob !== "undefined" && value instanceof Blob) return true;
1060
1063
  else if (typeof value === "string" && value.trim() === "") return false;
1061
1064
  else if (Array.isArray(value) && value.length < 1) return false;
1062
1065
  else if (typeof value === "object" && Object.keys(value).length < 1) return false;
@@ -2325,7 +2328,7 @@ var BaseValidator = class BaseValidator {
2325
2328
  [rule, parameters] = validationRuleParser.parse(rule);
2326
2329
  const keys = this.getExplicitKeys(attribute);
2327
2330
  if (keys.length > 0 && parameters.length > 0) parameters = this.replaceAsterisksInParameters(parameters, keys);
2328
- const value = deepFind(this.data, attribute);
2331
+ const value = this.getAttributeValue(attribute);
2329
2332
  const validatable = this.isValidatable(attribute, value, rule);
2330
2333
  if (rule instanceof IRuleContract) return validatable ? this.validateUsingCustomRule(attribute, value, rule) : void 0;
2331
2334
  const method = `validate${buildValidationMethodName(rule)}`;
@@ -2393,14 +2396,14 @@ var BaseValidator = class BaseValidator {
2393
2396
  * Determine if the attribute is validatable.
2394
2397
  */
2395
2398
  isValidatable(attribute, value, rule) {
2396
- return this.presentOrRuleIsImplicit(attribute, value, rule) && this.passesOptionalCheck(attribute) && this.isNotNullIfMarkedAsNullable(attribute, rule);
2399
+ return this.presentOrRuleIsImplicit(attribute, value, rule) && this.passesOptionalCheck(attribute) && this.isNotNullIfMarkedAsNullable(attribute, value, rule);
2397
2400
  }
2398
2401
  /**
2399
2402
  * Determine if the field is present, or the rule implies required.
2400
2403
  */
2401
2404
  presentOrRuleIsImplicit(attribute, value, rule) {
2402
2405
  if (typeof value === "string" && value.trim() === "") return isImplicitRule(rule);
2403
- return typeof deepFind(this.data, attribute) !== "undefined" || isImplicitRule(rule);
2406
+ return typeof value !== "undefined" || isImplicitRule(rule);
2404
2407
  }
2405
2408
  /**
2406
2409
  * Determine if the attribute passes any optional check.
@@ -2408,14 +2411,23 @@ var BaseValidator = class BaseValidator {
2408
2411
  passesOptionalCheck(attribute) {
2409
2412
  if (!validationRuleParser.hasRule(attribute, ["sometimes"], this.rules)) return true;
2410
2413
  const data = validationData.initializeAndGatherData(attribute, this.data);
2411
- return Object.prototype.hasOwnProperty.call(data, attribute) || Object.prototype.hasOwnProperty.call(this.data, attribute);
2414
+ const requestFiles = validationData.initializeAndGatherData(attribute, this.getContext().requestFiles ?? {});
2415
+ return Object.prototype.hasOwnProperty.call(data, attribute) || Object.prototype.hasOwnProperty.call(this.data, attribute) || Object.prototype.hasOwnProperty.call(requestFiles, attribute) || Object.prototype.hasOwnProperty.call(this.getContext().requestFiles ?? {}, attribute);
2412
2416
  }
2413
2417
  /**
2414
2418
  * Determine if the attribute fails the nullable check.
2415
2419
  */
2416
- isNotNullIfMarkedAsNullable(attribute, rule) {
2420
+ isNotNullIfMarkedAsNullable(attribute, value, rule) {
2417
2421
  if (isImplicitRule(rule) || !validationRuleParser.hasRule(attribute, ["nullable"], this.rules)) return true;
2418
- return deepFind(this.data, attribute) !== null;
2422
+ return value !== null;
2423
+ }
2424
+ /**
2425
+ * Resolve an attribute value from validator data first, then request-scoped file context.
2426
+ */
2427
+ getAttributeValue(attribute) {
2428
+ const dataValue = deepFind(this.data, attribute);
2429
+ if (typeof dataValue !== "undefined") return dataValue;
2430
+ return deepFind(this.getContext().requestFiles ?? {}, attribute);
2419
2431
  }
2420
2432
  /**
2421
2433
  * Get the primary attribute name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kanun",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Framework-agnostic TypeScript-first validation library.",
5
5
  "type": "module",
6
6
  "files": [