@platecms/delta-validation 0.13.0 → 1.3.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.
Files changed (35) hide show
  1. package/package.json +4 -4
  2. package/src/index.ts +8 -7
  3. package/src/lib/enums/validation-rule-update-impact.enum.ts +5 -0
  4. package/src/lib/helpers/fields-to-schema.spec.ts +184 -0
  5. package/src/lib/helpers/fields-to-schema.ts +141 -0
  6. package/src/lib/helpers/get-content-value-type-name.ts +26 -0
  7. package/src/lib/helpers/is-superset.helper.ts +4 -0
  8. package/src/lib/helpers/rule-to-schema.spec.ts +4 -4
  9. package/src/lib/helpers/schema-builder.ts +5 -0
  10. package/src/lib/helpers/validate-with-function.spec.ts +3 -3
  11. package/src/lib/schemas/array.schema.spec.ts +1 -1
  12. package/src/lib/schemas/content-value.schema.spec.ts +5 -5
  13. package/src/lib/schemas/content-value.schema.ts +27 -2
  14. package/src/lib/schemas/date.schema.spec.ts +1 -1
  15. package/src/lib/schemas/object.schema.spec.ts +223 -0
  16. package/src/lib/schemas/object.schema.ts +106 -0
  17. package/src/lib/schemas/string.schema.spec.ts +1 -1
  18. package/src/lib/types/validation-schema.interface.ts +1 -1
  19. package/src/lib/validation-rules/allowed-values.validation-rule.spec.ts +30 -5
  20. package/src/lib/validation-rules/allowed-values.validation-rule.ts +15 -0
  21. package/src/lib/validation-rules/base.validation-rule.ts +21 -4
  22. package/src/lib/validation-rules/count.validation-rule.spec.ts +39 -1
  23. package/src/lib/validation-rules/count.validation-rule.ts +35 -0
  24. package/src/lib/validation-rules/date-between.validation-rule.spec.ts +84 -1
  25. package/src/lib/validation-rules/date-between.validation-rule.ts +19 -4
  26. package/src/lib/validation-rules/decimal-count.validation-rule.spec.ts +27 -1
  27. package/src/lib/validation-rules/decimal-count.validation-rule.ts +12 -0
  28. package/src/lib/validation-rules/number-between.validation-rule.spec.ts +45 -1
  29. package/src/lib/validation-rules/number-between.validation-rule.ts +14 -0
  30. package/src/lib/validation-rules/relatable-content-types.validation-rule.spec.ts +38 -13
  31. package/src/lib/validation-rules/relatable-content-types.validation-rule.ts +17 -0
  32. package/src/lib/validation-rules/string-format.validation-rule.spec.ts +48 -22
  33. package/src/lib/validation-rules/string-format.validation-rule.ts +14 -0
  34. package/src/lib/validation-rules/value-type.validation-rule.spec.ts +105 -75
  35. package/src/lib/validation-rules/value-type.validation-rule.ts +17 -2
@@ -1,108 +1,138 @@
1
1
  import { PRN } from "@platecms/delta-plate-resource-notation";
2
- import { ContentValueType, ContentValueTypeNames } from "@platecms/delta-types";
2
+ import { ContentValueType, ContentValueTypeName, ContentValueTypeNames } from "@platecms/delta-types";
3
+ import { ValidationRuleUpdateImpact } from "../enums/validation-rule-update-impact.enum";
3
4
  import { ValueTypeValidationRule, ValueTypeValidationRuleSettings } from "./value-type.validation-rule";
4
5
 
5
6
  describe("ValueTypeValidationRule", () => {
6
- const rulePrn = PRN.fromString("prn:plate:-1:cxc:validation-rule:value-type");
7
+ const rulePrn = PRN.fromString("prn:plate:-1:cms:validation-rule:value-type");
7
8
 
8
- describe.each([
9
- [
10
- "with allowed string type",
11
- { allowedTypes: [ContentValueTypeNames.STRING] },
9
+ describe("validate", () => {
10
+ describe.each([
12
11
  [
13
- ["foo", true],
14
- [123, false],
12
+ "with allowed string type",
13
+ { allowedTypes: [ContentValueTypeNames.STRING] },
14
+ [
15
+ ["foo", true],
16
+ [123, false],
17
+ ],
15
18
  ],
16
- ],
17
- [
18
- "with allowed number type",
19
- { allowedTypes: [ContentValueTypeNames.NUMBER] },
20
19
  [
21
- [123, true],
22
- ["foo", false],
20
+ "with allowed number type",
21
+ { allowedTypes: [ContentValueTypeNames.NUMBER] },
22
+ [
23
+ [123, true],
24
+ ["foo", false],
25
+ ],
23
26
  ],
24
- ],
25
- [
26
- "with allowed boolean type",
27
- { allowedTypes: [ContentValueTypeNames.BOOLEAN] },
28
27
  [
29
- [true, true],
30
- ["foo", false],
28
+ "with allowed boolean type",
29
+ { allowedTypes: [ContentValueTypeNames.BOOLEAN] },
30
+ [
31
+ [true, true],
32
+ ["foo", false],
33
+ ],
31
34
  ],
32
- ],
33
- [
34
- "with allowed date type",
35
- { allowedTypes: [ContentValueTypeNames.DATE] },
36
35
  [
37
- [new Date(), true],
38
- ["foo", false],
36
+ "with allowed date type",
37
+ { allowedTypes: [ContentValueTypeNames.DATE] },
38
+ [
39
+ [new Date(), true],
40
+ ["foo", false],
41
+ ],
39
42
  ],
40
- ],
41
- [
42
- "with allowed content item type",
43
- { allowedTypes: [ContentValueTypeNames.CONTENT_ITEM] },
44
43
  [
45
- [PRN.fromString("prn:plate:-1:cxc:content-item:1"), true],
46
- ["foo", false],
44
+ "with allowed content item type",
45
+ { allowedTypes: [ContentValueTypeNames.CONTENT_ITEM] },
46
+ [
47
+ [PRN.fromString("prn:plate:-1:cms:content-item:1"), true],
48
+ ["foo", false],
49
+ ],
47
50
  ],
48
- ],
49
- [
50
- "with allowed asset type",
51
- { allowedTypes: [ContentValueTypeNames.ASSET] },
52
51
  [
53
- [PRN.fromString("prn:plate:-1:am:asset:1"), true],
54
- ["foo", false],
52
+ "with allowed asset type",
53
+ { allowedTypes: [ContentValueTypeNames.ASSET] },
54
+ [
55
+ [PRN.fromString("prn:plate:-1:ps:asset:1"), true],
56
+ ["foo", false],
57
+ ],
55
58
  ],
56
- ],
57
- [
58
- "with allowed path part type",
59
- { allowedTypes: [ContentValueTypeNames.PATH_PART] },
60
59
  [
61
- [PRN.fromString("prn:plate:-1:cxc:path-part:1"), true],
62
- ["foo", false],
60
+ "with allowed path part type",
61
+ { allowedTypes: [ContentValueTypeNames.PATH_PART] },
62
+ [
63
+ [PRN.fromString("prn:plate:-1:cms:path-part:1"), true],
64
+ ["foo", false],
65
+ ],
63
66
  ],
64
- ],
65
- [
66
- "with allowed grid placement type",
67
- { allowedTypes: [ContentValueTypeNames.GRID_PLACEMENT] },
68
67
  [
69
- [PRN.fromString("prn:plate:-1:cxc:grid-placement:1"), true],
70
- ["foo", false],
68
+ "with allowed grid placement type",
69
+ { allowedTypes: [ContentValueTypeNames.GRID_PLACEMENT] },
70
+ [
71
+ [PRN.fromString("prn:plate:-1:cms:grid-placement:1"), true],
72
+ ["foo", false],
73
+ ],
71
74
  ],
72
- ],
73
- [
74
- "with allowed smart text type",
75
- { allowedTypes: [ContentValueTypeNames.SMART_TEXT] },
76
75
  [
77
- [{ type: "root", children: [] }, true],
78
- [PRN.fromString("prn:plate:-1:cxc:grid-placement:1"), false],
76
+ "with allowed smart text type",
77
+ { allowedTypes: [ContentValueTypeNames.SMART_TEXT] },
78
+ [
79
+ [{ type: "root", children: [] }, true],
80
+ [PRN.fromString("prn:plate:-1:cms:grid-placement:1"), false],
81
+ ],
79
82
  ],
80
- ],
81
- [
82
- "with incorrect prn",
83
- { allowedTypes: [ContentValueTypeNames.CONTENT_ITEM] },
84
- [[PRN.fromString("prn:plate:-1:am:asset:1"), false]],
85
- ],
86
- [
87
- "with multiple types",
88
- {
89
- allowedTypes: [ContentValueTypeNames.STRING, ContentValueTypeNames.CONTENT_ITEM],
90
- },
91
83
  [
92
- ["foo", true],
93
- [PRN.fromString("prn:plate:-1:cxc:content-item:1"), true],
94
- [new Date(), false],
84
+ "with incorrect prn",
85
+ { allowedTypes: [ContentValueTypeNames.CONTENT_ITEM] },
86
+ [[PRN.fromString("prn:plate:-1:ps:asset:1"), false]],
95
87
  ],
96
- ],
97
- ])("%s", (_, ruleConfig, testCases: unknown[]) => {
88
+ [
89
+ "with multiple types",
90
+ {
91
+ allowedTypes: [ContentValueTypeNames.STRING, ContentValueTypeNames.CONTENT_ITEM],
92
+ },
93
+ [
94
+ ["foo", true],
95
+ [PRN.fromString("prn:plate:-1:cms:content-item:1"), true],
96
+ [new Date(), false],
97
+ ],
98
+ ],
99
+ ])("%s", (_, ruleConfig, testCases: unknown[]) => {
100
+ let rule: ValueTypeValidationRule;
101
+
102
+ beforeEach(() => {
103
+ rule = new ValueTypeValidationRule(rulePrn, ruleConfig as ValueTypeValidationRuleSettings);
104
+ });
105
+
106
+ it.each(testCases)("returns %s for the provided value", (value, expected) => {
107
+ expect(rule.validate([value as ContentValueType])).toBeContentValidationResult([expected as boolean]);
108
+ });
109
+ });
110
+ });
111
+
112
+ describe("classifyUpdate", () => {
98
113
  let rule: ValueTypeValidationRule;
114
+ const allowedTypes: ContentValueTypeName<ContentValueType>[] = [
115
+ ContentValueTypeNames.STRING,
116
+ ContentValueTypeNames.NUMBER,
117
+ ];
99
118
 
100
119
  beforeEach(() => {
101
- rule = new ValueTypeValidationRule(rulePrn, ruleConfig as ValueTypeValidationRuleSettings);
120
+ rule = new ValueTypeValidationRule(rulePrn, { allowedTypes });
102
121
  });
103
122
 
104
- it.each(testCases)("returns %s for the provided value", (value, expected) => {
105
- expect(rule.validate([value as ContentValueType])).toBeContentValidationResult([expected]);
123
+ it.each([
124
+ [ValidationRuleUpdateImpact.NONE, { allowedTypes: [...allowedTypes, ContentValueTypeNames.BOOLEAN] }], // extending
125
+ [ValidationRuleUpdateImpact.NONE, { allowedTypes: [...allowedTypes] }], // unchanged
126
+ [ValidationRuleUpdateImpact.BREAKS, { allowedTypes: [ContentValueTypeNames.BOOLEAN] }], // tightening
127
+ ])("returns %s when the new allowed types are %s", (expected, newSettings) => {
128
+ expect(rule.classifyUpdate(newSettings as ValueTypeValidationRuleSettings)).toBe(expected);
129
+ });
130
+ });
131
+
132
+ describe("classifyCreate", () => {
133
+ it("returns BREAKS", () => {
134
+ const rule = new ValueTypeValidationRule(rulePrn, { allowedTypes: [ContentValueTypeNames.STRING] });
135
+ expect(rule.classifyCreate()).toBe(ValidationRuleUpdateImpact.BREAKS);
106
136
  });
107
137
  });
108
138
  });
@@ -1,16 +1,18 @@
1
1
  import { InvalidCastError, validateCast } from "@platecms/delta-cast";
2
2
  import { PRN } from "@platecms/delta-plate-resource-notation";
3
3
  import { ContentValueType, ContentValueTypeName, ContentValueTypeNames } from "@platecms/delta-types";
4
+ import { RuleType } from "../enums/rule-types.enum";
5
+ import { ValidationRuleUpdateImpact } from "../enums/validation-rule-update-impact.enum";
4
6
  import { ValidationErrorDetails } from "../errors/validation-error-details";
7
+ import { isSuperset } from "../helpers/is-superset.helper";
5
8
  import { RuleInstance } from "../types/rule-instance.interface";
6
- import { RuleType } from "../enums/rule-types.enum";
7
9
  import { BaseValidationRule, ContentValidationResultType } from "./base.validation-rule";
8
10
  import { validationFunctionFromValidateValue } from "./validation-rule-function.factory";
9
11
 
10
12
  /**
11
13
  * Mapping of PRN resource type to Content Value Type Name.
12
14
  */
13
- const prnResourceTypeToContentValueTypeNameMap: Record<string, ContentValueTypeNames> = {
15
+ const prnResourceTypeToContentValueTypeNameMap: Record<string, ContentValueTypeName<PRN>> = {
14
16
  /* eslint-disable @typescript-eslint/naming-convention */
15
17
  "content-item": ContentValueTypeNames.CONTENT_ITEM,
16
18
  asset: ContentValueTypeNames.ASSET,
@@ -68,6 +70,19 @@ export class ValueTypeValidationRule extends BaseValidationRule<ValueTypeValidat
68
70
  public override validate(values: ContentValueType[]): ContentValidationResultType[] {
69
71
  return validateValueType(values, this);
70
72
  }
73
+
74
+ public override classifyCreate(): ValidationRuleUpdateImpact {
75
+ return ValidationRuleUpdateImpact.BREAKS;
76
+ }
77
+
78
+ public override classifyUpdate(newSettings: ValueTypeValidationRuleSettings): ValidationRuleUpdateImpact {
79
+ const oldAllowedTypes = this.settings.allowedTypes;
80
+ const newAllowedTypes = newSettings.allowedTypes;
81
+
82
+ return isSuperset(newAllowedTypes, oldAllowedTypes)
83
+ ? ValidationRuleUpdateImpact.NONE
84
+ : ValidationRuleUpdateImpact.BREAKS;
85
+ }
71
86
  }
72
87
 
73
88
  // The value type can be one or more of the types specified in the ContentValueType type