@rippling/rippling-sdk 0.2.0-alpha.105 → 0.2.0-alpha.106

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 (175) hide show
  1. package/client.d.mts +6 -0
  2. package/client.d.mts.map +1 -1
  3. package/client.d.ts +6 -0
  4. package/client.d.ts.map +1 -1
  5. package/client.js +6 -0
  6. package/client.js.map +1 -1
  7. package/client.mjs +6 -0
  8. package/client.mjs.map +1 -1
  9. package/lib/charts/builders.d.mts +43 -0
  10. package/lib/charts/builders.d.mts.map +1 -0
  11. package/lib/charts/builders.d.ts +43 -0
  12. package/lib/charts/builders.d.ts.map +1 -0
  13. package/lib/charts/builders.js +77 -0
  14. package/lib/charts/builders.js.map +1 -0
  15. package/lib/charts/builders.mjs +70 -0
  16. package/lib/charts/builders.mjs.map +1 -0
  17. package/lib/charts/describe.d.mts +12 -0
  18. package/lib/charts/describe.d.mts.map +1 -0
  19. package/lib/charts/describe.d.ts +12 -0
  20. package/lib/charts/describe.d.ts.map +1 -0
  21. package/lib/charts/describe.js +64 -0
  22. package/lib/charts/describe.js.map +1 -0
  23. package/lib/charts/describe.mjs +61 -0
  24. package/lib/charts/describe.mjs.map +1 -0
  25. package/lib/charts/errors.d.mts +35 -0
  26. package/lib/charts/errors.d.mts.map +1 -0
  27. package/lib/charts/errors.d.ts +35 -0
  28. package/lib/charts/errors.d.ts.map +1 -0
  29. package/lib/charts/errors.js +55 -0
  30. package/lib/charts/errors.js.map +1 -0
  31. package/lib/charts/errors.mjs +47 -0
  32. package/lib/charts/errors.mjs.map +1 -0
  33. package/lib/charts/evaluate.d.mts +16 -0
  34. package/lib/charts/evaluate.d.mts.map +1 -0
  35. package/lib/charts/evaluate.d.ts +16 -0
  36. package/lib/charts/evaluate.d.ts.map +1 -0
  37. package/lib/charts/evaluate.js +99 -0
  38. package/lib/charts/evaluate.js.map +1 -0
  39. package/lib/charts/evaluate.mjs +96 -0
  40. package/lib/charts/evaluate.mjs.map +1 -0
  41. package/lib/charts/guards.d.mts +15 -0
  42. package/lib/charts/guards.d.mts.map +1 -0
  43. package/lib/charts/guards.d.ts +15 -0
  44. package/lib/charts/guards.d.ts.map +1 -0
  45. package/lib/charts/guards.js +38 -0
  46. package/lib/charts/guards.js.map +1 -0
  47. package/lib/charts/guards.mjs +34 -0
  48. package/lib/charts/guards.mjs.map +1 -0
  49. package/lib/charts/schema.d.mts +101 -0
  50. package/lib/charts/schema.d.mts.map +1 -0
  51. package/lib/charts/schema.d.ts +101 -0
  52. package/lib/charts/schema.d.ts.map +1 -0
  53. package/lib/charts/schema.js +74 -0
  54. package/lib/charts/schema.js.map +1 -0
  55. package/lib/charts/schema.mjs +71 -0
  56. package/lib/charts/schema.mjs.map +1 -0
  57. package/lib/charts/types.d.mts +79 -0
  58. package/lib/charts/types.d.mts.map +1 -0
  59. package/lib/charts/types.d.ts +79 -0
  60. package/lib/charts/types.d.ts.map +1 -0
  61. package/lib/charts/types.js +25 -0
  62. package/lib/charts/types.js.map +1 -0
  63. package/lib/charts/types.mjs +22 -0
  64. package/lib/charts/types.mjs.map +1 -0
  65. package/lib/charts.d.mts +7 -0
  66. package/lib/charts.d.mts.map +1 -0
  67. package/lib/charts.d.ts +7 -0
  68. package/lib/charts.d.ts.map +1 -0
  69. package/lib/charts.js +32 -0
  70. package/lib/charts.js.map +1 -0
  71. package/lib/charts.mjs +7 -0
  72. package/lib/charts.mjs.map +1 -0
  73. package/package.json +1 -1
  74. package/resources/hire-requirements.d.mts +8 -74
  75. package/resources/hire-requirements.d.mts.map +1 -1
  76. package/resources/hire-requirements.d.ts +8 -74
  77. package/resources/hire-requirements.d.ts.map +1 -1
  78. package/resources/hire-requirements.js +3 -19
  79. package/resources/hire-requirements.js.map +1 -1
  80. package/resources/hire-requirements.mjs +3 -19
  81. package/resources/hire-requirements.mjs.map +1 -1
  82. package/resources/hires.d.mts +677 -142
  83. package/resources/hires.d.mts.map +1 -1
  84. package/resources/hires.d.ts +677 -142
  85. package/resources/hires.d.ts.map +1 -1
  86. package/resources/hires.js +3 -4
  87. package/resources/hires.js.map +1 -1
  88. package/resources/hires.mjs +3 -4
  89. package/resources/hires.mjs.map +1 -1
  90. package/resources/index.d.mts +1 -0
  91. package/resources/index.d.mts.map +1 -1
  92. package/resources/index.d.ts +1 -0
  93. package/resources/index.d.ts.map +1 -1
  94. package/resources/index.js +4 -2
  95. package/resources/index.js.map +1 -1
  96. package/resources/index.mjs +1 -0
  97. package/resources/index.mjs.map +1 -1
  98. package/resources/payroll-payment-mode-changes.d.mts +102 -0
  99. package/resources/payroll-payment-mode-changes.d.mts.map +1 -0
  100. package/resources/payroll-payment-mode-changes.d.ts +102 -0
  101. package/resources/payroll-payment-mode-changes.d.ts.map +1 -0
  102. package/resources/payroll-payment-mode-changes.js +54 -0
  103. package/resources/payroll-payment-mode-changes.js.map +1 -0
  104. package/resources/payroll-payment-mode-changes.mjs +50 -0
  105. package/resources/payroll-payment-mode-changes.mjs.map +1 -0
  106. package/resources/payroll-runs/index.d.mts +1 -0
  107. package/resources/payroll-runs/index.d.mts.map +1 -1
  108. package/resources/payroll-runs/index.d.ts +1 -0
  109. package/resources/payroll-runs/index.d.ts.map +1 -1
  110. package/resources/payroll-runs/index.js +3 -1
  111. package/resources/payroll-runs/index.js.map +1 -1
  112. package/resources/payroll-runs/index.mjs +1 -0
  113. package/resources/payroll-runs/index.mjs.map +1 -1
  114. package/resources/payroll-runs/off-cycle.d.mts +322 -0
  115. package/resources/payroll-runs/off-cycle.d.mts.map +1 -0
  116. package/resources/payroll-runs/off-cycle.d.ts +322 -0
  117. package/resources/payroll-runs/off-cycle.d.ts.map +1 -0
  118. package/resources/payroll-runs/off-cycle.js +112 -0
  119. package/resources/payroll-runs/off-cycle.js.map +1 -0
  120. package/resources/payroll-runs/off-cycle.mjs +108 -0
  121. package/resources/payroll-runs/off-cycle.mjs.map +1 -0
  122. package/resources/payroll-runs/payroll-runs.d.mts +4 -0
  123. package/resources/payroll-runs/payroll-runs.d.mts.map +1 -1
  124. package/resources/payroll-runs/payroll-runs.d.ts +4 -0
  125. package/resources/payroll-runs/payroll-runs.d.ts.map +1 -1
  126. package/resources/payroll-runs/payroll-runs.js +4 -0
  127. package/resources/payroll-runs/payroll-runs.js.map +1 -1
  128. package/resources/payroll-runs/payroll-runs.mjs +4 -0
  129. package/resources/payroll-runs/payroll-runs.mjs.map +1 -1
  130. package/resources/sandboxes.d.mts +17 -11
  131. package/resources/sandboxes.d.mts.map +1 -1
  132. package/resources/sandboxes.d.ts +17 -11
  133. package/resources/sandboxes.d.ts.map +1 -1
  134. package/resources/sandboxes.js +1 -3
  135. package/resources/sandboxes.js.map +1 -1
  136. package/resources/sandboxes.mjs +1 -3
  137. package/resources/sandboxes.mjs.map +1 -1
  138. package/resources/variable-compensation-payout-labels.d.mts +1 -1
  139. package/resources/variable-compensation-payout-labels.d.ts +1 -1
  140. package/resources/variable-compensation-payout-labels.js +1 -1
  141. package/resources/variable-compensation-payout-labels.mjs +1 -1
  142. package/resources/variable-compensation-payout-types.d.mts +1 -1
  143. package/resources/variable-compensation-payout-types.d.ts +1 -1
  144. package/resources/variable-compensation-payout-types.js +1 -1
  145. package/resources/variable-compensation-payout-types.mjs +1 -1
  146. package/resources/variable-compensation-payouts.d.mts +1 -1
  147. package/resources/variable-compensation-payouts.d.ts +1 -1
  148. package/resources/variable-compensation-payouts.js +1 -1
  149. package/resources/variable-compensation-payouts.mjs +1 -1
  150. package/src/client.ts +16 -0
  151. package/src/lib/charts/README.md +114 -0
  152. package/src/lib/charts/builders.ts +90 -0
  153. package/src/lib/charts/describe.ts +67 -0
  154. package/src/lib/charts/errors.ts +48 -0
  155. package/src/lib/charts/evaluate.ts +114 -0
  156. package/src/lib/charts/guards.ts +42 -0
  157. package/src/lib/charts/schema.ts +72 -0
  158. package/src/lib/charts/types.ts +113 -0
  159. package/src/lib/charts.ts +43 -0
  160. package/src/resources/hire-requirements.ts +8 -85
  161. package/src/resources/hires.ts +866 -213
  162. package/src/resources/index.ts +5 -0
  163. package/src/resources/payroll-payment-mode-changes.ts +121 -0
  164. package/src/resources/payroll-runs/index.ts +1 -0
  165. package/src/resources/payroll-runs/off-cycle.ts +372 -0
  166. package/src/resources/payroll-runs/payroll-runs.ts +10 -0
  167. package/src/resources/sandboxes.ts +17 -11
  168. package/src/resources/variable-compensation-payout-labels.ts +1 -1
  169. package/src/resources/variable-compensation-payout-types.ts +1 -1
  170. package/src/resources/variable-compensation-payouts.ts +1 -1
  171. package/src/version.ts +1 -1
  172. package/version.d.mts +1 -1
  173. package/version.d.ts +1 -1
  174. package/version.js +1 -1
  175. package/version.mjs +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/lib/charts/describe.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,OAAO,EAAE,KAAK,IAAI,EAAiB,mBAAgB;AAEjF;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAK5C"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describe = describe;
4
+ const builders_1 = require("./builders.js");
5
+ const errors_1 = require("./errors.js");
6
+ const guards_1 = require("./guards.js");
7
+ const types_1 = require("./types.js");
8
+ /**
9
+ * Turn a rule into the shape the settings panel renders: a label plus its
10
+ * editable parts. Accepts a `{$rule}` placeholder or a bare tree. Walks the same
11
+ * tree `evaluate` runs — and validates each node the same way — so a malformed or
12
+ * unknown node throws a `ChartRuleError` here too, never a native `TypeError`.
13
+ * The unwrap is gated on `isRulePlaceholder` (not a raw `'$rule' in rule`) so a
14
+ * `null`/primitive rule reaches `assertRuleNode` instead of throwing on `in`.
15
+ * A tree nested past `MAX_RULE_DEPTH` throws `RuleDepthError`.
16
+ */
17
+ function describe(rule) {
18
+ if ((0, builders_1.isRulePlaceholder)(rule)) {
19
+ return visit(rule.$rule, 0);
20
+ }
21
+ return visit(rule, 0);
22
+ }
23
+ function visit(node, depth) {
24
+ if (depth > types_1.MAX_RULE_DEPTH) {
25
+ throw new errors_1.RuleDepthError(types_1.MAX_RULE_DEPTH);
26
+ }
27
+ (0, guards_1.assertRuleNode)(node);
28
+ const next = depth + 1;
29
+ switch (node.kind) {
30
+ case 'value':
31
+ return { role: 'ref', label: "this row's value" };
32
+ case 'literal': {
33
+ const scalar = (0, guards_1.literalValue)(node);
34
+ return { role: 'literal', label: String(scalar), value: scalar };
35
+ }
36
+ case 'equals':
37
+ return comparison('is', node.left, node.right, next);
38
+ case 'isNot':
39
+ return comparison('is not', node.left, node.right, next);
40
+ case 'lessThan':
41
+ return comparison('is under', node.left, node.right, next);
42
+ case 'greaterThan':
43
+ return comparison('is over', node.left, node.right, next);
44
+ case 'lessOrEqual':
45
+ return comparison('is at most', node.left, node.right, next);
46
+ case 'greaterOrEqual':
47
+ return comparison('is at least', node.left, node.right, next);
48
+ case 'ifElse':
49
+ return {
50
+ role: 'rule',
51
+ label: 'when',
52
+ parts: [visit(node.cond, next), visit(node.then, next), visit(node.else, next)],
53
+ };
54
+ default:
55
+ return unreachable(node);
56
+ }
57
+ }
58
+ function comparison(label, left, right, depth) {
59
+ return { role: 'comparison', label, parts: [visit(left, depth), visit(right, depth)] };
60
+ }
61
+ function unreachable(node) {
62
+ throw new errors_1.UnknownNodeError(node.kind);
63
+ }
64
+ //# sourceMappingURL=describe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/lib/charts/describe.ts"],"names":[],"mappings":";;AAcA,4BAKC;AAnBD,4CAA+C;AAC/C,wCAA4D;AAC5D,wCAAwD;AACxD,sCAAiF;AAEjF;;;;;;;;GAQG;AACH,SAAgB,QAAQ,CAAC,IAAU;IACjC,IAAI,IAAA,4BAAiB,EAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,KAAK,CAAC,IAAc,EAAE,KAAa;IAC1C,IAAI,KAAK,GAAG,sBAAc,EAAE,CAAC;QAC3B,MAAM,IAAI,uBAAc,CAAC,sBAAc,CAAC,CAAC;IAC3C,CAAC;IACD,IAAA,uBAAc,EAAC,IAAI,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;IACvB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;QACpD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,IAAI,CAAC,CAAC;YAClC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACnE,CAAC;QAED,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACvD,KAAK,OAAO;YACV,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3D,KAAK,UAAU;YACb,OAAO,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7D,KAAK,aAAa;YAChB,OAAO,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5D,KAAK,aAAa;YAChB,OAAO,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC/D,KAAK,gBAAgB;YACnB,OAAO,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAEhE,KAAK,QAAQ;YACX,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;aAChF,CAAC;QAEJ;YACE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,IAAc,EAAE,KAAe,EAAE,KAAa;IAC/E,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;AACzF,CAAC;AAED,SAAS,WAAW,CAAC,IAAW;IAC9B,MAAM,IAAI,yBAAgB,CAAE,IAA0B,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { isRulePlaceholder } from "./builders.mjs";
2
+ import { RuleDepthError, UnknownNodeError } from "./errors.mjs";
3
+ import { assertRuleNode, literalValue } from "./guards.mjs";
4
+ import { MAX_RULE_DEPTH } from "./types.mjs";
5
+ /**
6
+ * Turn a rule into the shape the settings panel renders: a label plus its
7
+ * editable parts. Accepts a `{$rule}` placeholder or a bare tree. Walks the same
8
+ * tree `evaluate` runs — and validates each node the same way — so a malformed or
9
+ * unknown node throws a `ChartRuleError` here too, never a native `TypeError`.
10
+ * The unwrap is gated on `isRulePlaceholder` (not a raw `'$rule' in rule`) so a
11
+ * `null`/primitive rule reaches `assertRuleNode` instead of throwing on `in`.
12
+ * A tree nested past `MAX_RULE_DEPTH` throws `RuleDepthError`.
13
+ */
14
+ export function describe(rule) {
15
+ if (isRulePlaceholder(rule)) {
16
+ return visit(rule.$rule, 0);
17
+ }
18
+ return visit(rule, 0);
19
+ }
20
+ function visit(node, depth) {
21
+ if (depth > MAX_RULE_DEPTH) {
22
+ throw new RuleDepthError(MAX_RULE_DEPTH);
23
+ }
24
+ assertRuleNode(node);
25
+ const next = depth + 1;
26
+ switch (node.kind) {
27
+ case 'value':
28
+ return { role: 'ref', label: "this row's value" };
29
+ case 'literal': {
30
+ const scalar = literalValue(node);
31
+ return { role: 'literal', label: String(scalar), value: scalar };
32
+ }
33
+ case 'equals':
34
+ return comparison('is', node.left, node.right, next);
35
+ case 'isNot':
36
+ return comparison('is not', node.left, node.right, next);
37
+ case 'lessThan':
38
+ return comparison('is under', node.left, node.right, next);
39
+ case 'greaterThan':
40
+ return comparison('is over', node.left, node.right, next);
41
+ case 'lessOrEqual':
42
+ return comparison('is at most', node.left, node.right, next);
43
+ case 'greaterOrEqual':
44
+ return comparison('is at least', node.left, node.right, next);
45
+ case 'ifElse':
46
+ return {
47
+ role: 'rule',
48
+ label: 'when',
49
+ parts: [visit(node.cond, next), visit(node.then, next), visit(node.else, next)],
50
+ };
51
+ default:
52
+ return unreachable(node);
53
+ }
54
+ }
55
+ function comparison(label, left, right, depth) {
56
+ return { role: 'comparison', label, parts: [visit(left, depth), visit(right, depth)] };
57
+ }
58
+ function unreachable(node) {
59
+ throw new UnknownNodeError(node.kind);
60
+ }
61
+ //# sourceMappingURL=describe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe.mjs","sourceRoot":"","sources":["../../src/lib/charts/describe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /** Base class for every error the chart-rule evaluator can throw. */
2
+ export declare class ChartRuleError extends Error {
3
+ }
4
+ /**
5
+ * A node whose `kind` is not in the vocabulary. The caller catches this and
6
+ * shows the setting as "configured in code", read-only.
7
+ */
8
+ export declare class UnknownNodeError extends ChartRuleError {
9
+ readonly kind?: string | undefined;
10
+ constructor(kind?: string | undefined);
11
+ }
12
+ /** A node evaluated to the wrong type of value (e.g. comparing non-numbers). */
13
+ export declare class RuleTypeError extends ChartRuleError {
14
+ constructor(message: string);
15
+ }
16
+ /**
17
+ * A structurally invalid node in a deserialized tree: not an object, no string
18
+ * `kind`, or a `literal` without a scalar `value`. Distinct from
19
+ * `UnknownNodeError` (a well-formed node whose `kind` is simply not in the
20
+ * vocabulary — the intentional escape hatch). Like the others it is a
21
+ * `ChartRuleError`, so a caller reading an untrusted rule catches it instead of
22
+ * a native `TypeError` (or, worse, an `undefined` slipping through silently).
23
+ */
24
+ export declare class MalformedRuleError extends ChartRuleError {
25
+ constructor(message: string);
26
+ }
27
+ /**
28
+ * A rule nested deeper than the evaluator will walk. Guards against a
29
+ * stack-overflowing tree from untrusted, deserialized input; like the others it
30
+ * is a `ChartRuleError`, so the caller's escape hatch catches it.
31
+ */
32
+ export declare class RuleDepthError extends ChartRuleError {
33
+ constructor(maxDepth: number);
34
+ }
35
+ //# sourceMappingURL=errors.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.mts","sourceRoot":"","sources":["../../src/lib/charts/errors.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,cAAc;aACtB,IAAI,CAAC,EAAE,MAAM;gBAAb,IAAI,CAAC,EAAE,MAAM,YAAA;CAI1C;AAED,gFAAgF;AAChF,qBAAa,aAAc,SAAQ,cAAc;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,cAAc;gBACpC,QAAQ,EAAE,MAAM;CAI7B"}
@@ -0,0 +1,35 @@
1
+ /** Base class for every error the chart-rule evaluator can throw. */
2
+ export declare class ChartRuleError extends Error {
3
+ }
4
+ /**
5
+ * A node whose `kind` is not in the vocabulary. The caller catches this and
6
+ * shows the setting as "configured in code", read-only.
7
+ */
8
+ export declare class UnknownNodeError extends ChartRuleError {
9
+ readonly kind?: string | undefined;
10
+ constructor(kind?: string | undefined);
11
+ }
12
+ /** A node evaluated to the wrong type of value (e.g. comparing non-numbers). */
13
+ export declare class RuleTypeError extends ChartRuleError {
14
+ constructor(message: string);
15
+ }
16
+ /**
17
+ * A structurally invalid node in a deserialized tree: not an object, no string
18
+ * `kind`, or a `literal` without a scalar `value`. Distinct from
19
+ * `UnknownNodeError` (a well-formed node whose `kind` is simply not in the
20
+ * vocabulary — the intentional escape hatch). Like the others it is a
21
+ * `ChartRuleError`, so a caller reading an untrusted rule catches it instead of
22
+ * a native `TypeError` (or, worse, an `undefined` slipping through silently).
23
+ */
24
+ export declare class MalformedRuleError extends ChartRuleError {
25
+ constructor(message: string);
26
+ }
27
+ /**
28
+ * A rule nested deeper than the evaluator will walk. Guards against a
29
+ * stack-overflowing tree from untrusted, deserialized input; like the others it
30
+ * is a `ChartRuleError`, so the caller's escape hatch catches it.
31
+ */
32
+ export declare class RuleDepthError extends ChartRuleError {
33
+ constructor(maxDepth: number);
34
+ }
35
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/charts/errors.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,cAAc;aACtB,IAAI,CAAC,EAAE,MAAM;gBAAb,IAAI,CAAC,EAAE,MAAM,YAAA;CAI1C;AAED,gFAAgF;AAChF,qBAAa,aAAc,SAAQ,cAAc;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,cAAc;gBACpC,QAAQ,EAAE,MAAM;CAI7B"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuleDepthError = exports.MalformedRuleError = exports.RuleTypeError = exports.UnknownNodeError = exports.ChartRuleError = void 0;
4
+ /** Base class for every error the chart-rule evaluator can throw. */
5
+ class ChartRuleError extends Error {
6
+ }
7
+ exports.ChartRuleError = ChartRuleError;
8
+ /**
9
+ * A node whose `kind` is not in the vocabulary. The caller catches this and
10
+ * shows the setting as "configured in code", read-only.
11
+ */
12
+ class UnknownNodeError extends ChartRuleError {
13
+ constructor(kind) {
14
+ super(`Unknown chart-rule node: ${kind ?? '(missing kind)'}`);
15
+ this.kind = kind;
16
+ this.name = 'UnknownNodeError';
17
+ }
18
+ }
19
+ exports.UnknownNodeError = UnknownNodeError;
20
+ /** A node evaluated to the wrong type of value (e.g. comparing non-numbers). */
21
+ class RuleTypeError extends ChartRuleError {
22
+ constructor(message) {
23
+ super(message);
24
+ this.name = 'RuleTypeError';
25
+ }
26
+ }
27
+ exports.RuleTypeError = RuleTypeError;
28
+ /**
29
+ * A structurally invalid node in a deserialized tree: not an object, no string
30
+ * `kind`, or a `literal` without a scalar `value`. Distinct from
31
+ * `UnknownNodeError` (a well-formed node whose `kind` is simply not in the
32
+ * vocabulary — the intentional escape hatch). Like the others it is a
33
+ * `ChartRuleError`, so a caller reading an untrusted rule catches it instead of
34
+ * a native `TypeError` (or, worse, an `undefined` slipping through silently).
35
+ */
36
+ class MalformedRuleError extends ChartRuleError {
37
+ constructor(message) {
38
+ super(message);
39
+ this.name = 'MalformedRuleError';
40
+ }
41
+ }
42
+ exports.MalformedRuleError = MalformedRuleError;
43
+ /**
44
+ * A rule nested deeper than the evaluator will walk. Guards against a
45
+ * stack-overflowing tree from untrusted, deserialized input; like the others it
46
+ * is a `ChartRuleError`, so the caller's escape hatch catches it.
47
+ */
48
+ class RuleDepthError extends ChartRuleError {
49
+ constructor(maxDepth) {
50
+ super(`chart rule nested deeper than ${maxDepth} levels`);
51
+ this.name = 'RuleDepthError';
52
+ }
53
+ }
54
+ exports.RuleDepthError = RuleDepthError;
55
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/charts/errors.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACrE,MAAa,cAAe,SAAQ,KAAK;CAAG;AAA5C,wCAA4C;AAE5C;;;GAGG;AACH,MAAa,gBAAiB,SAAQ,cAAc;IAClD,YAA4B,IAAa;QACvC,KAAK,CAAC,4BAA4B,IAAI,IAAI,gBAAgB,EAAE,CAAC,CAAC;QADpC,SAAI,GAAJ,IAAI,CAAS;QAEvC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AALD,4CAKC;AAED,gFAAgF;AAChF,MAAa,aAAc,SAAQ,cAAc;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC;AAED;;;;;;;GAOG;AACH,MAAa,kBAAmB,SAAQ,cAAc;IACpD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AALD,gDAKC;AAED;;;;GAIG;AACH,MAAa,cAAe,SAAQ,cAAc;IAChD,YAAY,QAAgB;QAC1B,KAAK,CAAC,iCAAiC,QAAQ,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC"}
@@ -0,0 +1,47 @@
1
+ /** Base class for every error the chart-rule evaluator can throw. */
2
+ export class ChartRuleError extends Error {
3
+ }
4
+ /**
5
+ * A node whose `kind` is not in the vocabulary. The caller catches this and
6
+ * shows the setting as "configured in code", read-only.
7
+ */
8
+ export class UnknownNodeError extends ChartRuleError {
9
+ constructor(kind) {
10
+ super(`Unknown chart-rule node: ${kind ?? '(missing kind)'}`);
11
+ this.kind = kind;
12
+ this.name = 'UnknownNodeError';
13
+ }
14
+ }
15
+ /** A node evaluated to the wrong type of value (e.g. comparing non-numbers). */
16
+ export class RuleTypeError extends ChartRuleError {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = 'RuleTypeError';
20
+ }
21
+ }
22
+ /**
23
+ * A structurally invalid node in a deserialized tree: not an object, no string
24
+ * `kind`, or a `literal` without a scalar `value`. Distinct from
25
+ * `UnknownNodeError` (a well-formed node whose `kind` is simply not in the
26
+ * vocabulary — the intentional escape hatch). Like the others it is a
27
+ * `ChartRuleError`, so a caller reading an untrusted rule catches it instead of
28
+ * a native `TypeError` (or, worse, an `undefined` slipping through silently).
29
+ */
30
+ export class MalformedRuleError extends ChartRuleError {
31
+ constructor(message) {
32
+ super(message);
33
+ this.name = 'MalformedRuleError';
34
+ }
35
+ }
36
+ /**
37
+ * A rule nested deeper than the evaluator will walk. Guards against a
38
+ * stack-overflowing tree from untrusted, deserialized input; like the others it
39
+ * is a `ChartRuleError`, so the caller's escape hatch catches it.
40
+ */
41
+ export class RuleDepthError extends ChartRuleError {
42
+ constructor(maxDepth) {
43
+ super(`chart rule nested deeper than ${maxDepth} levels`);
44
+ this.name = 'RuleDepthError';
45
+ }
46
+ }
47
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","sourceRoot":"","sources":["../../src/lib/charts/errors.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IAClD,YAA4B,IAAa;QACvC,KAAK,CAAC,4BAA4B,IAAI,IAAI,gBAAgB,EAAE,CAAC,CAAC;QADpC,SAAI,GAAJ,IAAI,CAAS;QAEvC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,OAAO,aAAc,SAAQ,cAAc;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,kBAAmB,SAAQ,cAAc;IACpD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,cAAe,SAAQ,cAAc;IAChD,YAAY,QAAgB;QAC1B,KAAK,CAAC,iCAAiC,QAAQ,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import { type Rule, type RuleContext, type RuleValue } from "./types.mjs";
2
+ /**
3
+ * Resolve a rule to a value against `ctx`. Accepts a `{$rule}` placeholder or a
4
+ * bare tree. A malformed or unknown node throws a `ChartRuleError` (never a
5
+ * native `TypeError`), so a caller reading an untrusted, deserialized rule can
6
+ * catch every failure with one type. When the rule is a colour placeholder, the
7
+ * result is checked to be a colour (`string | null`) — a rule that resolves to a
8
+ * number or boolean is a `RuleTypeError`, not something the renderer paints.
9
+ *
10
+ * Pure: the only inputs are the node and the context. No clock, no randomness,
11
+ * no I/O — which is what makes it safe to run on an untrusted, user-edited tree
12
+ * and identical across the renderer, the panel readout, and a test. A tree
13
+ * nested past `MAX_RULE_DEPTH` throws `RuleDepthError` rather than overflowing.
14
+ */
15
+ export declare function evaluate(rule: Rule, ctx: RuleContext): RuleValue;
16
+ //# sourceMappingURL=evaluate.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.d.mts","sourceRoot":"","sources":["../../src/lib/charts/evaluate.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,IAAI,EAET,KAAK,WAAW,EAEhB,KAAK,SAAS,EACf,oBAAgB;AAEjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,CAKhE"}
@@ -0,0 +1,16 @@
1
+ import { type Rule, type RuleContext, type RuleValue } from "./types.js";
2
+ /**
3
+ * Resolve a rule to a value against `ctx`. Accepts a `{$rule}` placeholder or a
4
+ * bare tree. A malformed or unknown node throws a `ChartRuleError` (never a
5
+ * native `TypeError`), so a caller reading an untrusted, deserialized rule can
6
+ * catch every failure with one type. When the rule is a colour placeholder, the
7
+ * result is checked to be a colour (`string | null`) — a rule that resolves to a
8
+ * number or boolean is a `RuleTypeError`, not something the renderer paints.
9
+ *
10
+ * Pure: the only inputs are the node and the context. No clock, no randomness,
11
+ * no I/O — which is what makes it safe to run on an untrusted, user-edited tree
12
+ * and identical across the renderer, the panel readout, and a test. A tree
13
+ * nested past `MAX_RULE_DEPTH` throws `RuleDepthError` rather than overflowing.
14
+ */
15
+ export declare function evaluate(rule: Rule, ctx: RuleContext): RuleValue;
16
+ //# sourceMappingURL=evaluate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/lib/charts/evaluate.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,IAAI,EAET,KAAK,WAAW,EAEhB,KAAK,SAAS,EACf,mBAAgB;AAEjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,CAKhE"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.evaluate = evaluate;
4
+ const builders_1 = require("./builders.js");
5
+ const errors_1 = require("./errors.js");
6
+ const guards_1 = require("./guards.js");
7
+ const types_1 = require("./types.js");
8
+ /**
9
+ * Resolve a rule to a value against `ctx`. Accepts a `{$rule}` placeholder or a
10
+ * bare tree. A malformed or unknown node throws a `ChartRuleError` (never a
11
+ * native `TypeError`), so a caller reading an untrusted, deserialized rule can
12
+ * catch every failure with one type. When the rule is a colour placeholder, the
13
+ * result is checked to be a colour (`string | null`) — a rule that resolves to a
14
+ * number or boolean is a `RuleTypeError`, not something the renderer paints.
15
+ *
16
+ * Pure: the only inputs are the node and the context. No clock, no randomness,
17
+ * no I/O — which is what makes it safe to run on an untrusted, user-edited tree
18
+ * and identical across the renderer, the panel readout, and a test. A tree
19
+ * nested past `MAX_RULE_DEPTH` throws `RuleDepthError` rather than overflowing.
20
+ */
21
+ function evaluate(rule, ctx) {
22
+ if ((0, builders_1.isRulePlaceholder)(rule)) {
23
+ return coerceForChannel(rule.channel, visit(rule.$rule, ctx, 0));
24
+ }
25
+ return visit(rule, ctx, 0);
26
+ }
27
+ function visit(node, ctx, depth) {
28
+ if (depth > types_1.MAX_RULE_DEPTH) {
29
+ throw new errors_1.RuleDepthError(types_1.MAX_RULE_DEPTH);
30
+ }
31
+ (0, guards_1.assertRuleNode)(node);
32
+ const next = depth + 1;
33
+ switch (node.kind) {
34
+ case 'value':
35
+ return ctx.value;
36
+ case 'literal':
37
+ return (0, guards_1.literalValue)(node);
38
+ case 'equals':
39
+ return visit(node.left, ctx, next) === visit(node.right, ctx, next);
40
+ case 'isNot':
41
+ return visit(node.left, ctx, next) !== visit(node.right, ctx, next);
42
+ case 'lessThan':
43
+ return num(visit(node.left, ctx, next)) < num(visit(node.right, ctx, next));
44
+ case 'greaterThan':
45
+ return num(visit(node.left, ctx, next)) > num(visit(node.right, ctx, next));
46
+ case 'lessOrEqual':
47
+ return num(visit(node.left, ctx, next)) <= num(visit(node.right, ctx, next));
48
+ case 'greaterOrEqual':
49
+ return num(visit(node.left, ctx, next)) >= num(visit(node.right, ctx, next));
50
+ case 'ifElse':
51
+ return bool(visit(node.cond, ctx, next)) ? visit(node.then, ctx, next) : visit(node.else, ctx, next);
52
+ default:
53
+ return unreachable(node);
54
+ }
55
+ }
56
+ /* -------------------------------------------------------------------------- */
57
+ /* Coercions — narrow a RuleValue, or throw a typed error. */
58
+ /* -------------------------------------------------------------------------- */
59
+ function num(value) {
60
+ if (typeof value === 'number') {
61
+ return value;
62
+ }
63
+ throw new errors_1.RuleTypeError(`expected a number, got ${typeName(value)}`);
64
+ }
65
+ function bool(value) {
66
+ if (typeof value === 'boolean') {
67
+ return value;
68
+ }
69
+ throw new errors_1.RuleTypeError(`expected a boolean, got ${typeName(value)}`);
70
+ }
71
+ /** A colour channel must resolve to a colour string, or null for "no override". */
72
+ function asColor(value) {
73
+ if (value === null || typeof value === 'string') {
74
+ return value;
75
+ }
76
+ throw new errors_1.RuleTypeError(`a colour rule must resolve to a colour string or null, got ${typeName(value)}`);
77
+ }
78
+ /**
79
+ * Coerce a resolved value to what its channel can use. A colour rule must
80
+ * resolve to a colour; a future channel would add its own case here. A
81
+ * placeholder whose `channel` is missing or unrecognised (only possible from
82
+ * untrusted, deserialized input — the type and schema both pin it to `'color'`)
83
+ * is malformed rather than silently unchecked.
84
+ */
85
+ function coerceForChannel(channel, value) {
86
+ switch (channel) {
87
+ case 'color':
88
+ return asColor(value);
89
+ default:
90
+ throw new errors_1.MalformedRuleError(`a rule placeholder has an unsupported channel: ${String(channel)}`);
91
+ }
92
+ }
93
+ function typeName(value) {
94
+ return value === null ? 'null' : typeof value;
95
+ }
96
+ function unreachable(node) {
97
+ throw new errors_1.UnknownNodeError(node.kind);
98
+ }
99
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/lib/charts/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { isRulePlaceholder } from "./builders.mjs";
2
+ import { MalformedRuleError, RuleDepthError, RuleTypeError, UnknownNodeError } from "./errors.mjs";
3
+ import { assertRuleNode, literalValue } from "./guards.mjs";
4
+ import { MAX_RULE_DEPTH, } from "./types.mjs";
5
+ /**
6
+ * Resolve a rule to a value against `ctx`. Accepts a `{$rule}` placeholder or a
7
+ * bare tree. A malformed or unknown node throws a `ChartRuleError` (never a
8
+ * native `TypeError`), so a caller reading an untrusted, deserialized rule can
9
+ * catch every failure with one type. When the rule is a colour placeholder, the
10
+ * result is checked to be a colour (`string | null`) — a rule that resolves to a
11
+ * number or boolean is a `RuleTypeError`, not something the renderer paints.
12
+ *
13
+ * Pure: the only inputs are the node and the context. No clock, no randomness,
14
+ * no I/O — which is what makes it safe to run on an untrusted, user-edited tree
15
+ * and identical across the renderer, the panel readout, and a test. A tree
16
+ * nested past `MAX_RULE_DEPTH` throws `RuleDepthError` rather than overflowing.
17
+ */
18
+ export function evaluate(rule, ctx) {
19
+ if (isRulePlaceholder(rule)) {
20
+ return coerceForChannel(rule.channel, visit(rule.$rule, ctx, 0));
21
+ }
22
+ return visit(rule, ctx, 0);
23
+ }
24
+ function visit(node, ctx, depth) {
25
+ if (depth > MAX_RULE_DEPTH) {
26
+ throw new RuleDepthError(MAX_RULE_DEPTH);
27
+ }
28
+ assertRuleNode(node);
29
+ const next = depth + 1;
30
+ switch (node.kind) {
31
+ case 'value':
32
+ return ctx.value;
33
+ case 'literal':
34
+ return literalValue(node);
35
+ case 'equals':
36
+ return visit(node.left, ctx, next) === visit(node.right, ctx, next);
37
+ case 'isNot':
38
+ return visit(node.left, ctx, next) !== visit(node.right, ctx, next);
39
+ case 'lessThan':
40
+ return num(visit(node.left, ctx, next)) < num(visit(node.right, ctx, next));
41
+ case 'greaterThan':
42
+ return num(visit(node.left, ctx, next)) > num(visit(node.right, ctx, next));
43
+ case 'lessOrEqual':
44
+ return num(visit(node.left, ctx, next)) <= num(visit(node.right, ctx, next));
45
+ case 'greaterOrEqual':
46
+ return num(visit(node.left, ctx, next)) >= num(visit(node.right, ctx, next));
47
+ case 'ifElse':
48
+ return bool(visit(node.cond, ctx, next)) ? visit(node.then, ctx, next) : visit(node.else, ctx, next);
49
+ default:
50
+ return unreachable(node);
51
+ }
52
+ }
53
+ /* -------------------------------------------------------------------------- */
54
+ /* Coercions — narrow a RuleValue, or throw a typed error. */
55
+ /* -------------------------------------------------------------------------- */
56
+ function num(value) {
57
+ if (typeof value === 'number') {
58
+ return value;
59
+ }
60
+ throw new RuleTypeError(`expected a number, got ${typeName(value)}`);
61
+ }
62
+ function bool(value) {
63
+ if (typeof value === 'boolean') {
64
+ return value;
65
+ }
66
+ throw new RuleTypeError(`expected a boolean, got ${typeName(value)}`);
67
+ }
68
+ /** A colour channel must resolve to a colour string, or null for "no override". */
69
+ function asColor(value) {
70
+ if (value === null || typeof value === 'string') {
71
+ return value;
72
+ }
73
+ throw new RuleTypeError(`a colour rule must resolve to a colour string or null, got ${typeName(value)}`);
74
+ }
75
+ /**
76
+ * Coerce a resolved value to what its channel can use. A colour rule must
77
+ * resolve to a colour; a future channel would add its own case here. A
78
+ * placeholder whose `channel` is missing or unrecognised (only possible from
79
+ * untrusted, deserialized input — the type and schema both pin it to `'color'`)
80
+ * is malformed rather than silently unchecked.
81
+ */
82
+ function coerceForChannel(channel, value) {
83
+ switch (channel) {
84
+ case 'color':
85
+ return asColor(value);
86
+ default:
87
+ throw new MalformedRuleError(`a rule placeholder has an unsupported channel: ${String(channel)}`);
88
+ }
89
+ }
90
+ function typeName(value) {
91
+ return value === null ? 'null' : typeof value;
92
+ }
93
+ function unreachable(node) {
94
+ throw new UnknownNodeError(node.kind);
95
+ }
96
+ //# sourceMappingURL=evaluate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.mjs","sourceRoot":"","sources":["../../src/lib/charts/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,uBAAmB;AAC/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAiB;AAC/F,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,qBAAiB;AACxD,OAAO,EACL,cAAc,GAMf,oBAAgB;AAEjB;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAU,EAAE,GAAgB;IACnD,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,KAAK,CAAC,IAAc,EAAE,GAAgB,EAAE,KAAa;IAC5D,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;QAC3B,MAAM,IAAI,cAAc,CAAC,cAAc,CAAC,CAAC;IAC3C,CAAC;IACD,cAAc,CAAC,IAAI,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;IACvB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,GAAG,CAAC,KAAK,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAE5B,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACtE,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACtE,KAAK,UAAU;YACb,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9E,KAAK,aAAa;YAChB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9E,KAAK,aAAa;YAChB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/E,KAAK,gBAAgB;YACnB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAE/E,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAEvG;YACE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,kFAAkF;AAClF,gFAAgF;AAEhF,SAAS,GAAG,CAAC,KAAgB;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,aAAa,CAAC,0BAA0B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,IAAI,CAAC,KAAgB;IAC5B,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,aAAa,CAAC,2BAA2B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,mFAAmF;AACnF,SAAS,OAAO,CAAC,KAAgB;IAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,aAAa,CAAC,8DAA8D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC3G,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,OAAoB,EAAE,KAAgB;IAC9D,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;QACxB;YACE,MAAM,IAAI,kBAAkB,CAAC,kDAAkD,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtG,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAgB;IAChC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC;AAChD,CAAC;AAED,SAAS,WAAW,CAAC,IAAW;IAC9B,MAAM,IAAI,gBAAgB,CAAE,IAA0B,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type RuleNode, type Scalar } from "./types.mjs";
2
+ /**
3
+ * Assert `node` is shaped like a rule node — an object carrying a string `kind`.
4
+ * An unrecognised `kind` is *not* rejected here; that is the caller's `switch`
5
+ * default (`UnknownNodeError`), the deliberate "configured in code" signal.
6
+ */
7
+ export declare function assertRuleNode(node: unknown): asserts node is RuleNode;
8
+ /**
9
+ * Read a `literal` node's `value`, rejecting a missing or non-scalar one. Without
10
+ * this, `{ kind: 'literal' }` resolves to `undefined` and slips past the caller.
11
+ */
12
+ export declare function literalValue(node: {
13
+ value?: unknown;
14
+ }): Scalar;
15
+ //# sourceMappingURL=guards.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.mts","sourceRoot":"","sources":["../../src/lib/charts/guards.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,oBAAgB;AAYrD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAStE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAQ9D"}
@@ -0,0 +1,15 @@
1
+ import { type RuleNode, type Scalar } from "./types.js";
2
+ /**
3
+ * Assert `node` is shaped like a rule node — an object carrying a string `kind`.
4
+ * An unrecognised `kind` is *not* rejected here; that is the caller's `switch`
5
+ * default (`UnknownNodeError`), the deliberate "configured in code" signal.
6
+ */
7
+ export declare function assertRuleNode(node: unknown): asserts node is RuleNode;
8
+ /**
9
+ * Read a `literal` node's `value`, rejecting a missing or non-scalar one. Without
10
+ * this, `{ kind: 'literal' }` resolves to `undefined` and slips past the caller.
11
+ */
12
+ export declare function literalValue(node: {
13
+ value?: unknown;
14
+ }): Scalar;
15
+ //# sourceMappingURL=guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/lib/charts/guards.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,mBAAgB;AAYrD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAStE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAQ9D"}