xdbc 1.0.217 → 1.0.218

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 (89) hide show
  1. package/.gitattributes +8 -0
  2. package/.vscode/settings.json +3 -3
  3. package/.vscode/tasks.json +23 -23
  4. package/ASSESSMENT.md +249 -0
  5. package/README.md +131 -1
  6. package/__tests__/DBC/AE.test.ts +62 -62
  7. package/__tests__/DBC/ARRAY.test.ts +91 -91
  8. package/__tests__/DBC/DEFINED.test.ts +53 -53
  9. package/__tests__/DBC/DOM.test.ts +481 -0
  10. package/__tests__/DBC/Decorators.test.ts +367 -367
  11. package/__tests__/DBC/EQ.test.ts +13 -13
  12. package/__tests__/DBC/GREATER.test.ts +31 -31
  13. package/__tests__/DBC/HasAttribute.test.ts +60 -60
  14. package/__tests__/DBC/IF.test.ts +62 -62
  15. package/__tests__/DBC/INSTANCE.test.ts +13 -13
  16. package/__tests__/DBC/JSON.OP.test.ts +47 -47
  17. package/__tests__/DBC/JSON.Parse.test.ts +17 -17
  18. package/__tests__/DBC/OR.test.ts +14 -14
  19. package/__tests__/DBC/PLAIN_OBJECT.test.ts +109 -109
  20. package/__tests__/DBC/REGEX.test.ts +17 -17
  21. package/__tests__/DBC/TYPE.test.ts +13 -13
  22. package/__tests__/DBC/UNDEFINED.test.ts +45 -45
  23. package/__tests__/DBC/ZOD.test.ts +54 -54
  24. package/__tests__/DBC/onInfringement.test.ts +262 -0
  25. package/biome.json +40 -40
  26. package/dist/DBC/AE.js +172 -0
  27. package/dist/DBC/ARR/PLAIN_OBJECT.d.ts +0 -3
  28. package/dist/DBC/ARR/PLAIN_OBJECT.js +95 -0
  29. package/dist/DBC/ARRAY.d.ts +0 -3
  30. package/dist/DBC/ARRAY.js +90 -0
  31. package/dist/DBC/COMPARISON/GREATER.js +21 -0
  32. package/dist/DBC/COMPARISON/GREATER_OR_EQUAL.js +21 -0
  33. package/dist/DBC/COMPARISON/LESS.js +21 -0
  34. package/dist/DBC/COMPARISON/LESS_OR_EQUAL.js +21 -0
  35. package/dist/DBC/COMPARISON.js +98 -0
  36. package/dist/DBC/DEFINED.js +87 -0
  37. package/dist/DBC/DOM.d.ts +87 -0
  38. package/dist/DBC/DOM.js +223 -0
  39. package/dist/DBC/EQ/DIFFERENT.js +34 -0
  40. package/dist/DBC/EQ.js +101 -0
  41. package/dist/DBC/HasAttribute.js +101 -0
  42. package/dist/DBC/IF.js +96 -0
  43. package/dist/DBC/INSTANCE.js +122 -0
  44. package/dist/DBC/JSON.OP.js +120 -0
  45. package/dist/DBC/JSON.Parse.js +104 -0
  46. package/dist/DBC/OR.js +125 -0
  47. package/dist/DBC/REGEX.js +136 -0
  48. package/dist/DBC/TYPE.js +112 -0
  49. package/dist/DBC/UNDEFINED.js +87 -0
  50. package/dist/DBC/ZOD.js +99 -0
  51. package/dist/DBC.d.ts +18 -4
  52. package/dist/DBC.js +645 -0
  53. package/dist/Demo.d.ts +10 -0
  54. package/dist/Demo.js +713 -0
  55. package/dist/bundle.js +6140 -405
  56. package/dist/index.d.ts +22 -0
  57. package/dist/index.js +22 -0
  58. package/jest.config.js +32 -32
  59. package/package.json +71 -55
  60. package/src/DBC/AE.ts +269 -288
  61. package/src/DBC/ARR/PLAIN_OBJECT.ts +122 -133
  62. package/src/DBC/ARRAY.ts +117 -127
  63. package/src/DBC/COMPARISON/GREATER.ts +41 -46
  64. package/src/DBC/COMPARISON/GREATER_OR_EQUAL.ts +41 -45
  65. package/src/DBC/COMPARISON/LESS.ts +41 -45
  66. package/src/DBC/COMPARISON/LESS_OR_EQUAL.ts +41 -45
  67. package/src/DBC/COMPARISON.ts +149 -159
  68. package/src/DBC/DEFINED.ts +117 -122
  69. package/src/DBC/DOM.ts +291 -0
  70. package/src/DBC/EQ/DIFFERENT.ts +51 -57
  71. package/src/DBC/EQ.ts +154 -163
  72. package/src/DBC/HasAttribute.ts +149 -154
  73. package/src/DBC/IF.ts +173 -179
  74. package/src/DBC/INSTANCE.ts +168 -171
  75. package/src/DBC/JSON.OP.ts +178 -186
  76. package/src/DBC/JSON.Parse.ts +150 -157
  77. package/src/DBC/OR.ts +183 -187
  78. package/src/DBC/REGEX.ts +195 -196
  79. package/src/DBC/TYPE.ts +142 -149
  80. package/src/DBC/UNDEFINED.ts +115 -117
  81. package/src/DBC/ZOD.ts +130 -135
  82. package/src/DBC.ts +902 -904
  83. package/src/Demo.ts +537 -404
  84. package/src/index.ts +22 -0
  85. package/tsconfig.json +18 -18
  86. package/tsconfig.test.json +7 -7
  87. package/typedoc.json +16 -16
  88. package/webpack.config.js +27 -27
  89. package/Assessment.md +0 -507
@@ -0,0 +1,90 @@
1
+ import { DBC } from "../DBC";
2
+ /**
3
+ * A {@link DBC } defining that a value must be an array.
4
+ *
5
+ * @remarks
6
+ * Maintainer: Salvatore Callari (XDBC@WaXCode.net) */
7
+ export class ARRAY extends DBC {
8
+ /**
9
+ * Checks if the value **toCheck** is an array.
10
+ *
11
+ * @param toCheck The value to check.
12
+ *
13
+ * @returns TRUE if the value **toCheck** is an array, otherwise a string describing the infringement. */
14
+ static checkAlgorithm(toCheck) {
15
+ if (toCheck === undefined || toCheck === null)
16
+ return true;
17
+ if (!Array.isArray(toCheck)) {
18
+ return `Value has to be an ARRAY but is of type "${typeof toCheck}"`;
19
+ }
20
+ return true;
21
+ }
22
+ /**
23
+ * A parameter-decorator factory using the {@link ARRAY.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
24
+ * by the tagged parameter.
25
+ *
26
+ * @param path See {@link DBC.decPrecondition }.
27
+ * @param hint See {@link DBC.decPrecondition }.
28
+ * @param dbc See {@link DBC.decPrecondition }.
29
+ *
30
+ * @returns See {@link DBC.decPrecondition }. */
31
+ static PRE(path = undefined, hint = undefined, dbc = undefined) {
32
+ return DBC.createPRE(ARRAY.checkAlgorithm, [], dbc, path, hint);
33
+ }
34
+ /**
35
+ * A method-decorator factory using the {@link ARRAY.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
36
+ * by the tagged method's returnvalue.
37
+ *
38
+ * @param path See {@link DBC.decPostcondition }.
39
+ * @param hint See {@link DBC.decPostcondition }.
40
+ * @param dbc See {@link DBC.decPostcondition }.
41
+ *
42
+ * @returns See {@link DBC.decPostcondition }. */
43
+ static POST(path = undefined, hint = undefined, dbc = undefined) {
44
+ return DBC.createPOST(ARRAY.checkAlgorithm, [], dbc, path, hint);
45
+ }
46
+ /**
47
+ * A field-decorator factory using the {@link ARRAY.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
48
+ * by the tagged field.
49
+ *
50
+ * @param path See {@link DBC.decInvariant }.
51
+ * @param hint See {@link DBC.decInvariant }.
52
+ * @param dbc See {@link DBC.decInvariant }.
53
+ *
54
+ * @returns See {@link DBC.decInvariant }. */
55
+ static INVARIANT(path = undefined, hint = undefined, dbc = undefined) {
56
+ return DBC.createINVARIANT(ARRAY, [], dbc, path, hint);
57
+ }
58
+ // #endregion Condition checking.
59
+ // #region Referenced Condition checking.
60
+ //
61
+ // For usage in dynamic scenarios (like with AE-DBC).
62
+ //
63
+ /**
64
+ * Invokes the {@link ARRAY.checkAlgorithm } passing the value **toCheck**.
65
+ *
66
+ * @param toCheck See {@link ARRAY.checkAlgorithm }.
67
+ *
68
+ * @returns See {@link ARRAY.checkAlgorithm}. */
69
+ check(toCheck) {
70
+ return ARRAY.checkAlgorithm(toCheck);
71
+ }
72
+ /**
73
+ * Invokes the {@link ARRAY.checkAlgorithm } passing the value **toCheck**.
74
+ *
75
+ * @param toCheck See {@link ARRAY.checkAlgorithm }.
76
+ * @param hint An optional {@link string } providing extra information in case of an infringement.
77
+ * @param id A {@link string } identifying this {@link ARRAY } via the {@link DBC.Infringement }-Message.
78
+ *
79
+ * @returns The **CANDIDATE** **toCheck** if this {@link ARRAY } is fulfilled.
80
+ *
81
+ * @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link ARRAY }. */
82
+ static tsCheck(toCheck, hint = undefined, id = undefined, dbc = undefined) {
83
+ const result = ARRAY.checkAlgorithm(toCheck);
84
+ if (result === true) {
85
+ return toCheck;
86
+ }
87
+ DBC.reportTsCheckInfringement(`${id ? `(${id}) ` : ""}${result}${hint ? ` ✨ ${hint} ✨` : ""}`, dbc);
88
+ return toCheck;
89
+ }
90
+ }
@@ -0,0 +1,21 @@
1
+ import { COMPARISON } from "../COMPARISON";
2
+ /** See {@link COMPARISON }. */
3
+ export class GREATER extends COMPARISON {
4
+ /** See {@link COMPARISON.PRE }. */
5
+ static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
6
+ return COMPARISON.PRE(equivalent, false, false, path, hint, dbc);
7
+ }
8
+ /** See {@link COMPARISON.POST }. */
9
+ static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
10
+ return COMPARISON.POST(equivalent, false, false, path, hint, dbc);
11
+ }
12
+ /** See {@link COMPARISON.INVARIANT }. */
13
+ static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
14
+ return COMPARISON.INVARIANT(equivalent, false, false, path, hint, dbc);
15
+ }
16
+ /** See {@link COMPARISON.constructor }. */
17
+ constructor(equivalent) {
18
+ super(equivalent, false, false);
19
+ this.equivalent = equivalent;
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ import { COMPARISON } from "../COMPARISON";
2
+ /** See {@link COMPARISON }. */
3
+ export class GREATER_OR_EQUAL extends COMPARISON {
4
+ /** See {@link COMPARISON.PRE }. */
5
+ static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
6
+ return COMPARISON.PRE(equivalent, true, false, path, hint, dbc);
7
+ }
8
+ /** See {@link COMPARISON.POST }. */
9
+ static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
10
+ return COMPARISON.POST(equivalent, true, false, path, hint, dbc);
11
+ }
12
+ /** See {@link COMPARISON.INVARIANT }. */
13
+ static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
14
+ return COMPARISON.INVARIANT(equivalent, true, false, path, hint, dbc);
15
+ }
16
+ /** See {@link COMPARISON.constructor }. */
17
+ constructor(equivalent) {
18
+ super(equivalent, true, false);
19
+ this.equivalent = equivalent;
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ import { COMPARISON } from "../COMPARISON";
2
+ /** See {@link COMPARISON }. */
3
+ export class LESS extends COMPARISON {
4
+ /** See {@link COMPARISON.PRE }. */
5
+ static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
6
+ return COMPARISON.PRE(equivalent, false, true, path, hint, dbc);
7
+ }
8
+ /** See {@link COMPARISON.POST }. */
9
+ static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
10
+ return COMPARISON.POST(equivalent, false, true, path, hint, dbc);
11
+ }
12
+ /** See {@link COMPARISON.INVARIANT }. */
13
+ static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
14
+ return COMPARISON.INVARIANT(equivalent, false, true, path, hint, dbc);
15
+ }
16
+ /** See {@link COMPARISON.constructor }. */
17
+ constructor(equivalent) {
18
+ super(equivalent, false, true);
19
+ this.equivalent = equivalent;
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ import { COMPARISON } from "../COMPARISON";
2
+ /** See {@link COMPARISON }. */
3
+ export class LESS_OR_EQUAL extends COMPARISON {
4
+ /** See {@link COMPARISON.PRE }. */
5
+ static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
6
+ return COMPARISON.PRE(equivalent, true, true, path, hint, dbc);
7
+ }
8
+ /** See {@link COMPARISON.POST }. */
9
+ static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
10
+ return COMPARISON.POST(equivalent, true, true, path, hint, dbc);
11
+ }
12
+ /** See {@link COMPARISON.INVARIANT }. */
13
+ static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
14
+ return COMPARISON.INVARIANT(equivalent, true, true, path, hint, dbc);
15
+ }
16
+ /** See {@link COMPARISON.constructor }. */
17
+ constructor(equivalent) {
18
+ super(equivalent, true, true);
19
+ this.equivalent = equivalent;
20
+ }
21
+ }
@@ -0,0 +1,98 @@
1
+ import { DBC } from "../DBC";
2
+ /**
3
+ * A {@link DBC } defining a comparison between two {@link object }s.
4
+ *
5
+ * @remarks
6
+ * Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
7
+ export class COMPARISON extends DBC {
8
+ // #region Condition checking.
9
+ /**
10
+ * Does a comparison between the {@link object } **toCheck** and the **equivalent**.
11
+ *
12
+ * @param toCheck The value that has to be equal to it's possible **equivalent** for this {@link DBC } to be fulfilled.
13
+ * @param equivalent The {@link object } the one **toCheck** has to be equal to in order for this {@link DBC } to be
14
+ * fulfilled.
15
+ *
16
+ * @returns TRUE if the value **toCheck** and the **equivalent** are equal to each other, otherwise FALSE. */
17
+ static checkAlgorithm(toCheck, equivalent, equalityPermitted, invert) {
18
+ if (equalityPermitted && !invert && toCheck < equivalent) {
19
+ return `Value has to be greater than or equal to "${equivalent}"`;
20
+ }
21
+ if (equalityPermitted && invert && toCheck > equivalent) {
22
+ return `Value has to be less than or equal to "${equivalent}"`;
23
+ }
24
+ if (!equalityPermitted && !invert && toCheck <= equivalent) {
25
+ return `Value has to be greater than "${equivalent}"`;
26
+ }
27
+ if (!equalityPermitted && invert && toCheck >= equivalent) {
28
+ return `Value has to be less than "${equivalent}"`;
29
+ }
30
+ return true;
31
+ }
32
+ /**
33
+ * A parameter-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
34
+ * by the tagged parameter.
35
+ *
36
+ * @param equivalent See {@link COMPARISON.checkAlgorithm }.
37
+ * @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
38
+ * @param path See {@link DBC.decPrecondition }.
39
+ * @param hint See {@link DBC.decPrecondition }.
40
+ * @param dbc See {@link DBC.decPrecondition }.
41
+ *
42
+ * @returns See {@link DBC.decPrecondition }. */
43
+ static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
44
+ return DBC.createPRE(COMPARISON.checkAlgorithm, [equivalent, equalityPermitted, invert], dbc, path, hint);
45
+ }
46
+ /**
47
+ * A method-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
48
+ * by the tagged method's returnvalue.
49
+ *
50
+ * @param equivalent See {@link COMPARISON.checkAlgorithm }.
51
+ * @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
52
+ * @param path See {@link DBC.Postcondition }.
53
+ * @param hint See {@link DBC.decPostcondition }.
54
+ * @param dbc See {@link DBC.decPostcondition }.
55
+ *
56
+ * @returns See {@link DBC.decPostcondition }. */
57
+ static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
58
+ return DBC.createPOST(COMPARISON.checkAlgorithm, [equivalent, equalityPermitted, invert], dbc, path, hint);
59
+ }
60
+ /**
61
+ * A field-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
62
+ * by the tagged field.
63
+ *
64
+ * @param equivalent See {@link COMPARISON.checkAlgorithm }.
65
+ * @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
66
+ * @param path See {@link DBC.decInvariant }.
67
+ * @param hint See {@link DBC.decInvariant }.
68
+ * @param dbc See {@link DBC.decInvariant }.
69
+ *
70
+ * @returns See {@link DBC.decInvariant }. */
71
+ static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
72
+ return DBC.createINVARIANT(COMPARISON, [equivalent, equalityPermitted, invert], dbc, path, hint);
73
+ }
74
+ // #endregion Condition checking.
75
+ // #region Referenced Condition checking.
76
+ // #region Dynamic usage.
77
+ /**
78
+ * Invokes the {@link COMPARISON.checkAlgorithm } passing the value **toCheck**, {@link COMPARISON.equivalent } and {@link COMPARISON.invert }.
79
+ *
80
+ * @param toCheck See {@link COMPARISON.checkAlgorithm }.
81
+ *
82
+ * @returns See {@link COMPARISON.checkAlgorithm}. */
83
+ check(toCheck) {
84
+ return COMPARISON.checkAlgorithm(toCheck, this.equivalent, this.equalityPermitted, this.invert);
85
+ }
86
+ /**
87
+ * Creates this {@link COMPARISON } by setting the protected property {@link COMPARISON.equivalent }, {@link COMPARISON.equalityPermitted } and {@link COMPARISON.invert } used by {@link COMPARISON.check }.
88
+ *
89
+ * @param equivalent See {@link COMPARISON.check }.
90
+ * @param equalityPermitted See {@link COMPARISON.check }.
91
+ * @param invert See {@link COMPARISON.check }. */
92
+ constructor(equivalent, equalityPermitted = false, invert = false) {
93
+ super();
94
+ this.equivalent = equivalent;
95
+ this.equalityPermitted = equalityPermitted;
96
+ this.invert = invert;
97
+ }
98
+ }
@@ -0,0 +1,87 @@
1
+ import { DBC } from "../DBC";
2
+ /**
3
+ * A {@link DBC } defining that an {@link object }s must be defined thus it's value may not be **null** or **undefined**.
4
+ *
5
+ * @remarks
6
+ * Maintainer: Salvatore Callari (XDBC@WaXCode.net) */
7
+ export class DEFINED extends DBC {
8
+ /**
9
+ * Checks if the value **toCheck** is null or undefined.
10
+ *
11
+ * @param toCheck The {@link Object } to check.
12
+ *
13
+ * @returns TRUE if the value **toCheck** is of the specified **type**, otherwise FALSE. */
14
+ static checkAlgorithm(toCheck) {
15
+ if (toCheck === undefined || toCheck === null) {
16
+ return `Value may not be UNDEFINED or NULL but it is ${toCheck === undefined ? "UNDEFINED" : "NULL"}`;
17
+ }
18
+ return true;
19
+ }
20
+ /**
21
+ * A parameter-decorator factory using the {@link DEFINED.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
22
+ * by the tagged parameter.
23
+ *
24
+ * @param type See {@link DEFINED.checkAlgorithm }.
25
+ * @param path See {@link DBC.decPrecondition }.
26
+ * @param dbc See {@link DBC.decPrecondition }.
27
+ *
28
+ * @returns See {@link DBC.decPrecondition }. */
29
+ static PRE(path = undefined, hint = undefined, dbc = undefined) {
30
+ return DBC.createPRE(DEFINED.checkAlgorithm, [], dbc, path, hint);
31
+ }
32
+ /**
33
+ * A method-decorator factory using the {@link DEFINED.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
34
+ * by the tagged method's returnvalue.
35
+ *
36
+ * @param type See {@link DEFINED.checkAlgorithm }.
37
+ * @param path See {@link DBC.Postcondition }.
38
+ * @param dbc See {@link DBC.decPostcondition }.
39
+ *
40
+ * @returns See {@link DBC.decPostcondition }. */
41
+ static POST(type, path = undefined, hint = undefined, dbc = undefined) {
42
+ return DBC.createPOST(DEFINED.checkAlgorithm, [], dbc, path, hint);
43
+ }
44
+ /**
45
+ * A field-decorator factory using the {@link DEFINED.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
46
+ * by the tagged field.
47
+ *
48
+ * @param type See {@link DEFINED.checkAlgorithm }.
49
+ * @param path See {@link DBC.decInvariant }.
50
+ * @param dbc See {@link DBC.decInvariant }.
51
+ *
52
+ * @returns See {@link DBC.decInvariant }. */
53
+ static INVARIANT(type, path = undefined, hint = undefined, dbc = undefined) {
54
+ return DBC.createINVARIANT(DEFINED, [], dbc, path, hint);
55
+ }
56
+ // #endregion Condition checking.
57
+ // #region Referenced Condition checking.
58
+ //
59
+ // For usage in dynamic scenarios (like with AE-DBC).
60
+ //
61
+ /**
62
+ * Invokes the {@link DEFINED.checkAlgorithm } passing the value **toCheck** and the {@link DEFINED.type } .
63
+ *
64
+ * @param toCheck See {@link DEFINED.checkAlgorithm }.
65
+ *
66
+ * @returns See {@link DEFINED.checkAlgorithm}. */
67
+ check(toCheck) {
68
+ return DEFINED.checkAlgorithm(toCheck);
69
+ }
70
+ /**
71
+ * Invokes the {@link DEFINED.checkAlgorithm } passing the value **toCheck** and the {@link DEFINED.type } .
72
+ *
73
+ * @param toCheck See {@link DEFINED.checkAlgorithm }.
74
+ * @param id A {@link string } identifying this {@link INSTANCE } via the {@link DBC.Infringement }-Message.
75
+ *
76
+ * @returns The **CANDIDATE** **toCheck** doesn't fulfill this {@link DEFINED }.
77
+ *
78
+ * @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link DEFINED }.*/
79
+ static tsCheck(toCheck, hint = undefined, id = undefined, dbc = undefined) {
80
+ const result = DEFINED.checkAlgorithm(toCheck);
81
+ if (result === true) {
82
+ return toCheck;
83
+ }
84
+ DBC.reportTsCheckInfringement(`${id ? `(${id}) ` : ""}${result}${hint ? ` ✨ ${hint} ✨` : ""}`, dbc);
85
+ return toCheck;
86
+ }
87
+ }
@@ -0,0 +1,87 @@
1
+ /** A check function that receives the current field value and the raw attribute string. */
2
+ export type DOMContractCheck = (value: string, attrValue: string) => boolean | string;
3
+ /**
4
+ * Registers a check function for a `data-xdbc-<key>` attribute.
5
+ * Call this before {@link scanDOM } to make a contract available declaratively.
6
+ *
7
+ * @param key The attribute suffix (e.g. `"type"` → `data-xdbc-type`).
8
+ * @param checkFn Receives the live field value and the raw attribute string.
9
+ * Return `true` when the value is valid, or a `string` message when it is not.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { registerDOMContract } from "xdbc/DBC/DOM";
14
+ * import { MY_CONTRACT } from "./MY_CONTRACT";
15
+ *
16
+ * registerDOMContract("my-contract", (value, attr) =>
17
+ * MY_CONTRACT.checkAlgorithm(value, attr),
18
+ * );
19
+ * ```
20
+ */
21
+ export declare function registerDOMContract(key: string, checkFn: DOMContractCheck): void;
22
+ /**
23
+ * Scans the given **root** for `<input>` and `<textarea>` elements marked with the
24
+ * `data-xdbc` attribute, and binds XDBC contracts to their `input` events (covering
25
+ * keyboard, paste, IME / mobile on-screen keyboard, voice input, and autofill).
26
+ *
27
+ * ### Supported attributes
28
+ *
29
+ * | Attribute | Example value | Contract |
30
+ * |----------------------------|----------------------------|-----------------|
31
+ * | `data-xdbc` | *(path or empty)* | marker / DBC path |
32
+ * | `data-xdbc-regex` | `^\d*$` | {@link REGEX} |
33
+ * | `data-xdbc-type` | `string\|number` | {@link TYPE} |
34
+ * | `data-xdbc-eq` | `hello` | {@link EQ} |
35
+ * | `data-xdbc-different` | `forbidden` | {@link EQ} (inverted) |
36
+ * | `data-xdbc-defined` | *(no value needed)* | {@link DEFINED} |
37
+ * | `data-xdbc-undefined` | *(no value needed)* | {@link UNDEFINED} |
38
+ * | `data-xdbc-greater` | `5` | {@link COMPARISON} |
39
+ * | `data-xdbc-greater-or-equal` | `5` | {@link COMPARISON} |
40
+ * | `data-xdbc-less` | `100` | {@link COMPARISON} |
41
+ * | `data-xdbc-less-or-equal` | `100` | {@link COMPARISON} |
42
+ * | `data-xdbc-or` | `regex:^\d+$;;type:string` | {@link OR} (fragment syntax) |
43
+ *
44
+ * Use {@link registerDOMContract } to add further contracts at any time.
45
+ *
46
+ * ### OR fragment syntax
47
+ *
48
+ * Fragments are separated by `;;`. Each fragment is `<contract-key>:<value>`, where the
49
+ * split is on the **first** `:` only, so colons inside values (e.g. regex) are safe.
50
+ * The OR passes as long as **at least one** fragment passes.
51
+ *
52
+ * ```html
53
+ * <!-- digits OR exactly "N/A" -->
54
+ * <input data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
55
+ * ```
56
+ *
57
+ * ### Behaviour on infringement
58
+ *
59
+ * 1. The element's value is **reverted** to the last accepted state (blocking the invalid input).
60
+ * 2. The configured DBC instance's infringement settings are honoured — `logToConsole`,
61
+ * `onInfringement`, and `throwException` all fire in the usual order. Any throw is caught
62
+ * internally so it cannot propagate out of the DOM event handler.
63
+ *
64
+ * ### IME / composition awareness
65
+ *
66
+ * Validation is suspended during IME composition (e.g. CJK input) and runs once after
67
+ * `compositionend`, so partially composed characters are never incorrectly rejected.
68
+ *
69
+ * @param root Element or Document to scan (default: `document`).
70
+ * @returns A cleanup function that removes all bound event listeners.
71
+ *
72
+ * @example
73
+ * ```html
74
+ * <input type="text" data-xdbc data-xdbc-regex="^\d*$" />
75
+ * <input type="text" data-xdbc="MyApp.DBC" data-xdbc-type="string" data-xdbc-greater="0" />
76
+ * <input type="text" data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
77
+ * <textarea data-xdbc data-xdbc-regex="^[\w\s]*$"></textarea>
78
+ * ```
79
+ * ```ts
80
+ * import { scanDOM, registerDOMContract } from "xdbc/DBC/DOM";
81
+ *
82
+ * const cleanup = scanDOM();
83
+ * // later:
84
+ * cleanup();
85
+ * ```
86
+ */
87
+ export declare function scanDOM(root?: Element | Document): () => void;
@@ -0,0 +1,223 @@
1
+ import { DBC } from "../DBC";
2
+ import { COMPARISON } from "./COMPARISON";
3
+ import { DEFINED } from "./DEFINED";
4
+ import { EQ } from "./EQ";
5
+ import { REGEX } from "./REGEX";
6
+ import { TYPE } from "./TYPE";
7
+ import { UNDEFINED } from "./UNDEFINED";
8
+ // ─── Contract registry ────────────────────────────────────────────────────────
9
+ /**
10
+ * Maps a `data-xdbc-<key>` attribute suffix to a check function.
11
+ * Populated by {@link registerDOMContract } and the built-in defaults below.
12
+ */
13
+ const registry = new Map();
14
+ /**
15
+ * Registers a check function for a `data-xdbc-<key>` attribute.
16
+ * Call this before {@link scanDOM } to make a contract available declaratively.
17
+ *
18
+ * @param key The attribute suffix (e.g. `"type"` → `data-xdbc-type`).
19
+ * @param checkFn Receives the live field value and the raw attribute string.
20
+ * Return `true` when the value is valid, or a `string` message when it is not.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { registerDOMContract } from "xdbc/DBC/DOM";
25
+ * import { MY_CONTRACT } from "./MY_CONTRACT";
26
+ *
27
+ * registerDOMContract("my-contract", (value, attr) =>
28
+ * MY_CONTRACT.checkAlgorithm(value, attr),
29
+ * );
30
+ * ```
31
+ */
32
+ export function registerDOMContract(key, checkFn) {
33
+ registry.set(key, checkFn);
34
+ }
35
+ // ─── Built-in registrations ───────────────────────────────────────────────────
36
+ // data-xdbc-regex="^\d*$"
37
+ registerDOMContract("regex", (value, attr) => {
38
+ let rx;
39
+ try {
40
+ rx = new RegExp(attr);
41
+ }
42
+ catch (_a) {
43
+ return `[XDBC] Invalid RegExp pattern: "${attr}"`;
44
+ }
45
+ return REGEX.checkAlgorithm(value, rx);
46
+ });
47
+ // data-xdbc-type="string|number"
48
+ registerDOMContract("type", (value, attr) => TYPE.checkAlgorithm(value, attr));
49
+ // data-xdbc-eq="hello"
50
+ registerDOMContract("eq", (value, attr) => EQ.checkAlgorithm(value, attr, false));
51
+ // data-xdbc-different="forbidden"
52
+ registerDOMContract("different", (value, attr) => EQ.checkAlgorithm(value, attr, true));
53
+ // data-xdbc-defined (attribute presence is enough; value ignored)
54
+ registerDOMContract("defined", (value) => DEFINED.checkAlgorithm(value));
55
+ // data-xdbc-undefined
56
+ registerDOMContract("undefined", (value) => UNDEFINED.checkAlgorithm(value));
57
+ // data-xdbc-greater="5"
58
+ registerDOMContract("greater", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), false, false));
59
+ // data-xdbc-greater-or-equal="5"
60
+ registerDOMContract("greater-or-equal", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), true, false));
61
+ // data-xdbc-less="100"
62
+ registerDOMContract("less", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), false, true));
63
+ // data-xdbc-less-or-equal="100"
64
+ registerDOMContract("less-or-equal", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), true, true));
65
+ // data-xdbc-or="regex:^\d+$;;type:string;;eq:42"
66
+ // Fragments are separated by ";;". Each fragment is "<contract-key>:<attr-value>",
67
+ // where the split is on the FIRST ":" only, so colons in the value (e.g. regex) are safe.
68
+ // The OR passes as long as at least one fragment passes.
69
+ registerDOMContract("or", (value, attr) => {
70
+ const fragments = attr.split(";;");
71
+ const messages = [];
72
+ for (const fragment of fragments) {
73
+ const colonIdx = fragment.indexOf(":");
74
+ const key = colonIdx === -1 ? fragment.trim() : fragment.slice(0, colonIdx).trim();
75
+ const fragAttr = colonIdx === -1 ? "" : fragment.slice(colonIdx + 1);
76
+ const checkFn = registry.get(key);
77
+ if (!checkFn) {
78
+ console.warn(`[XDBC] data-xdbc-or: unknown contract key "${key}"`);
79
+ continue;
80
+ }
81
+ const result = checkFn(value, fragAttr);
82
+ if (result === true)
83
+ return true; // short-circuit on first pass
84
+ if (typeof result === "string")
85
+ messages.push(result);
86
+ }
87
+ return messages.length > 0
88
+ ? `Value did not satisfy any of: ${messages.join(" | ")}`
89
+ : true;
90
+ });
91
+ // ─── scanDOM ──────────────────────────────────────────────────────────────────
92
+ /**
93
+ * Scans the given **root** for `<input>` and `<textarea>` elements marked with the
94
+ * `data-xdbc` attribute, and binds XDBC contracts to their `input` events (covering
95
+ * keyboard, paste, IME / mobile on-screen keyboard, voice input, and autofill).
96
+ *
97
+ * ### Supported attributes
98
+ *
99
+ * | Attribute | Example value | Contract |
100
+ * |----------------------------|----------------------------|-----------------|
101
+ * | `data-xdbc` | *(path or empty)* | marker / DBC path |
102
+ * | `data-xdbc-regex` | `^\d*$` | {@link REGEX} |
103
+ * | `data-xdbc-type` | `string\|number` | {@link TYPE} |
104
+ * | `data-xdbc-eq` | `hello` | {@link EQ} |
105
+ * | `data-xdbc-different` | `forbidden` | {@link EQ} (inverted) |
106
+ * | `data-xdbc-defined` | *(no value needed)* | {@link DEFINED} |
107
+ * | `data-xdbc-undefined` | *(no value needed)* | {@link UNDEFINED} |
108
+ * | `data-xdbc-greater` | `5` | {@link COMPARISON} |
109
+ * | `data-xdbc-greater-or-equal` | `5` | {@link COMPARISON} |
110
+ * | `data-xdbc-less` | `100` | {@link COMPARISON} |
111
+ * | `data-xdbc-less-or-equal` | `100` | {@link COMPARISON} |
112
+ * | `data-xdbc-or` | `regex:^\d+$;;type:string` | {@link OR} (fragment syntax) |
113
+ *
114
+ * Use {@link registerDOMContract } to add further contracts at any time.
115
+ *
116
+ * ### OR fragment syntax
117
+ *
118
+ * Fragments are separated by `;;`. Each fragment is `<contract-key>:<value>`, where the
119
+ * split is on the **first** `:` only, so colons inside values (e.g. regex) are safe.
120
+ * The OR passes as long as **at least one** fragment passes.
121
+ *
122
+ * ```html
123
+ * <!-- digits OR exactly "N/A" -->
124
+ * <input data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
125
+ * ```
126
+ *
127
+ * ### Behaviour on infringement
128
+ *
129
+ * 1. The element's value is **reverted** to the last accepted state (blocking the invalid input).
130
+ * 2. The configured DBC instance's infringement settings are honoured — `logToConsole`,
131
+ * `onInfringement`, and `throwException` all fire in the usual order. Any throw is caught
132
+ * internally so it cannot propagate out of the DOM event handler.
133
+ *
134
+ * ### IME / composition awareness
135
+ *
136
+ * Validation is suspended during IME composition (e.g. CJK input) and runs once after
137
+ * `compositionend`, so partially composed characters are never incorrectly rejected.
138
+ *
139
+ * @param root Element or Document to scan (default: `document`).
140
+ * @returns A cleanup function that removes all bound event listeners.
141
+ *
142
+ * @example
143
+ * ```html
144
+ * <input type="text" data-xdbc data-xdbc-regex="^\d*$" />
145
+ * <input type="text" data-xdbc="MyApp.DBC" data-xdbc-type="string" data-xdbc-greater="0" />
146
+ * <input type="text" data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
147
+ * <textarea data-xdbc data-xdbc-regex="^[\w\s]*$"></textarea>
148
+ * ```
149
+ * ```ts
150
+ * import { scanDOM, registerDOMContract } from "xdbc/DBC/DOM";
151
+ *
152
+ * const cleanup = scanDOM();
153
+ * // later:
154
+ * cleanup();
155
+ * ```
156
+ */
157
+ export function scanDOM(root = document) {
158
+ var _a;
159
+ const bound = [];
160
+ const elements = Array.from(root.querySelectorAll("[data-xdbc]"));
161
+ for (const el of elements) {
162
+ const dbcPath = el.dataset.xdbc || "WaXCode.DBC";
163
+ // Collect every registered contract that has a corresponding attribute on this element.
164
+ const checks = [];
165
+ for (const [key, checkFn] of registry) {
166
+ // dataset converts "xdbc-greater-or-equal" → "xdbcGreaterOrEqual" via camelCase.
167
+ // Build the camelCase key from the registry key.
168
+ const datasetKey = `xdbc${key
169
+ .split("-")
170
+ .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
171
+ .join("")}`;
172
+ if (datasetKey in el.dataset) {
173
+ checks.push({ checkFn, attrValue: (_a = el.dataset[datasetKey]) !== null && _a !== void 0 ? _a : "" });
174
+ }
175
+ }
176
+ if (checks.length === 0)
177
+ continue;
178
+ let lastValid = el.value;
179
+ let composing = false;
180
+ const inputListener = () => {
181
+ if (composing)
182
+ return;
183
+ const value = el.value;
184
+ for (const { checkFn, attrValue } of checks) {
185
+ const result = checkFn(value, attrValue);
186
+ if (typeof result === "string") {
187
+ el.value = lastValid;
188
+ try {
189
+ DBC.getRegistered(dbcPath).reportParameterInfringement(result, el, undefined, el.name || el.id || "input", 0, value);
190
+ }
191
+ catch (_a) {
192
+ // swallowed — throwException must not propagate out of a DOM event handler
193
+ }
194
+ return; // stop checking further contracts once one fails
195
+ }
196
+ }
197
+ lastValid = value;
198
+ };
199
+ const compositionStartListener = () => {
200
+ composing = true;
201
+ };
202
+ const compositionEndListener = () => {
203
+ composing = false;
204
+ inputListener();
205
+ };
206
+ el.addEventListener("input", inputListener);
207
+ el.addEventListener("compositionstart", compositionStartListener);
208
+ el.addEventListener("compositionend", compositionEndListener);
209
+ bound.push({
210
+ element: el,
211
+ inputListener,
212
+ compositionStartListener,
213
+ compositionEndListener,
214
+ });
215
+ }
216
+ return () => {
217
+ for (const { element, inputListener, compositionStartListener, compositionEndListener, } of bound) {
218
+ element.removeEventListener("input", inputListener);
219
+ element.removeEventListener("compositionstart", compositionStartListener);
220
+ element.removeEventListener("compositionend", compositionEndListener);
221
+ }
222
+ };
223
+ }