@rippling/rippling-sdk 0.2.0-alpha.104 → 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 (251) hide show
  1. package/client.d.mts +12 -0
  2. package/client.d.mts.map +1 -1
  3. package/client.d.ts +12 -0
  4. package/client.d.ts.map +1 -1
  5. package/client.js +12 -0
  6. package/client.js.map +1 -1
  7. package/client.mjs +12 -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/lib/manifest/_existing-component-fields.d.mts.map +1 -1
  74. package/lib/manifest/_existing-component-fields.d.ts.map +1 -1
  75. package/lib/manifest/_existing-component-fields.js +2 -0
  76. package/lib/manifest/_existing-component-fields.js.map +1 -1
  77. package/lib/manifest/_existing-component-fields.mjs +2 -0
  78. package/lib/manifest/_existing-component-fields.mjs.map +1 -1
  79. package/lib/manifest/existing-manifest-context.d.mts +3 -0
  80. package/lib/manifest/existing-manifest-context.d.mts.map +1 -1
  81. package/lib/manifest/existing-manifest-context.d.ts +3 -0
  82. package/lib/manifest/existing-manifest-context.d.ts.map +1 -1
  83. package/lib/manifest/existing-manifest-context.js +14 -0
  84. package/lib/manifest/existing-manifest-context.js.map +1 -1
  85. package/lib/manifest/existing-manifest-context.mjs +14 -0
  86. package/lib/manifest/existing-manifest-context.mjs.map +1 -1
  87. package/lib/manifest/workflow/index.d.mts +4 -0
  88. package/lib/manifest/workflow/index.d.mts.map +1 -1
  89. package/lib/manifest/workflow/index.d.ts +4 -0
  90. package/lib/manifest/workflow/index.d.ts.map +1 -1
  91. package/lib/manifest/workflow/index.js +49 -0
  92. package/lib/manifest/workflow/index.js.map +1 -1
  93. package/lib/manifest/workflow/index.mjs +49 -0
  94. package/lib/manifest/workflow/index.mjs.map +1 -1
  95. package/package.json +1 -1
  96. package/resources/activity-log.d.mts +517 -0
  97. package/resources/activity-log.d.mts.map +1 -0
  98. package/resources/activity-log.d.ts +517 -0
  99. package/resources/activity-log.d.ts.map +1 -0
  100. package/resources/activity-log.js +171 -0
  101. package/resources/activity-log.js.map +1 -0
  102. package/resources/activity-log.mjs +167 -0
  103. package/resources/activity-log.mjs.map +1 -0
  104. package/resources/compensations.d.mts +1 -1
  105. package/resources/compensations.d.ts +1 -1
  106. package/resources/compensations.js +1 -1
  107. package/resources/compensations.mjs +1 -1
  108. package/resources/developer-program-application.d.mts +1 -1
  109. package/resources/developer-program-application.d.ts +1 -1
  110. package/resources/developer-program-application.js +1 -1
  111. package/resources/developer-program-application.mjs +1 -1
  112. package/resources/developer-users.d.mts +2 -1
  113. package/resources/developer-users.d.mts.map +1 -1
  114. package/resources/developer-users.d.ts +2 -1
  115. package/resources/developer-users.d.ts.map +1 -1
  116. package/resources/developer-users.js +2 -1
  117. package/resources/developer-users.js.map +1 -1
  118. package/resources/developer-users.mjs +2 -1
  119. package/resources/developer-users.mjs.map +1 -1
  120. package/resources/hire-requirements.d.mts +8 -74
  121. package/resources/hire-requirements.d.mts.map +1 -1
  122. package/resources/hire-requirements.d.ts +8 -74
  123. package/resources/hire-requirements.d.ts.map +1 -1
  124. package/resources/hire-requirements.js +3 -19
  125. package/resources/hire-requirements.js.map +1 -1
  126. package/resources/hire-requirements.mjs +3 -19
  127. package/resources/hire-requirements.mjs.map +1 -1
  128. package/resources/hires.d.mts +677 -142
  129. package/resources/hires.d.mts.map +1 -1
  130. package/resources/hires.d.ts +677 -142
  131. package/resources/hires.d.ts.map +1 -1
  132. package/resources/hires.js +3 -4
  133. package/resources/hires.js.map +1 -1
  134. package/resources/hires.mjs +3 -4
  135. package/resources/hires.mjs.map +1 -1
  136. package/resources/index.d.mts +2 -0
  137. package/resources/index.d.mts.map +1 -1
  138. package/resources/index.d.ts +2 -0
  139. package/resources/index.d.ts.map +1 -1
  140. package/resources/index.js +7 -2
  141. package/resources/index.js.map +1 -1
  142. package/resources/index.mjs +2 -0
  143. package/resources/index.mjs.map +1 -1
  144. package/resources/listing-submissions.d.mts +1 -1
  145. package/resources/listing-submissions.d.ts +1 -1
  146. package/resources/listing-submissions.js +1 -1
  147. package/resources/listing-submissions.mjs +1 -1
  148. package/resources/listing-transitions.d.mts +1 -1
  149. package/resources/listing-transitions.d.ts +1 -1
  150. package/resources/listing-transitions.js +1 -1
  151. package/resources/listing-transitions.mjs +1 -1
  152. package/resources/listing.d.mts +1 -1
  153. package/resources/listing.d.ts +1 -1
  154. package/resources/listing.js +1 -1
  155. package/resources/listing.mjs +1 -1
  156. package/resources/payroll-payment-mode-changes.d.mts +102 -0
  157. package/resources/payroll-payment-mode-changes.d.mts.map +1 -0
  158. package/resources/payroll-payment-mode-changes.d.ts +102 -0
  159. package/resources/payroll-payment-mode-changes.d.ts.map +1 -0
  160. package/resources/payroll-payment-mode-changes.js +54 -0
  161. package/resources/payroll-payment-mode-changes.js.map +1 -0
  162. package/resources/payroll-payment-mode-changes.mjs +50 -0
  163. package/resources/payroll-payment-mode-changes.mjs.map +1 -0
  164. package/resources/payroll-runs/index.d.mts +1 -0
  165. package/resources/payroll-runs/index.d.mts.map +1 -1
  166. package/resources/payroll-runs/index.d.ts +1 -0
  167. package/resources/payroll-runs/index.d.ts.map +1 -1
  168. package/resources/payroll-runs/index.js +3 -1
  169. package/resources/payroll-runs/index.js.map +1 -1
  170. package/resources/payroll-runs/index.mjs +1 -0
  171. package/resources/payroll-runs/index.mjs.map +1 -1
  172. package/resources/payroll-runs/off-cycle.d.mts +322 -0
  173. package/resources/payroll-runs/off-cycle.d.mts.map +1 -0
  174. package/resources/payroll-runs/off-cycle.d.ts +322 -0
  175. package/resources/payroll-runs/off-cycle.d.ts.map +1 -0
  176. package/resources/payroll-runs/off-cycle.js +112 -0
  177. package/resources/payroll-runs/off-cycle.js.map +1 -0
  178. package/resources/payroll-runs/off-cycle.mjs +108 -0
  179. package/resources/payroll-runs/off-cycle.mjs.map +1 -0
  180. package/resources/payroll-runs/payroll-runs.d.mts +4 -0
  181. package/resources/payroll-runs/payroll-runs.d.mts.map +1 -1
  182. package/resources/payroll-runs/payroll-runs.d.ts +4 -0
  183. package/resources/payroll-runs/payroll-runs.d.ts.map +1 -1
  184. package/resources/payroll-runs/payroll-runs.js +4 -0
  185. package/resources/payroll-runs/payroll-runs.js.map +1 -1
  186. package/resources/payroll-runs/payroll-runs.mjs +4 -0
  187. package/resources/payroll-runs/payroll-runs.mjs.map +1 -1
  188. package/resources/sandboxes.d.mts +17 -11
  189. package/resources/sandboxes.d.mts.map +1 -1
  190. package/resources/sandboxes.d.ts +17 -11
  191. package/resources/sandboxes.d.ts.map +1 -1
  192. package/resources/sandboxes.js +1 -3
  193. package/resources/sandboxes.js.map +1 -1
  194. package/resources/sandboxes.mjs +1 -3
  195. package/resources/sandboxes.mjs.map +1 -1
  196. package/resources/variable-compensation-payout-labels.d.mts +3 -2
  197. package/resources/variable-compensation-payout-labels.d.mts.map +1 -1
  198. package/resources/variable-compensation-payout-labels.d.ts +3 -2
  199. package/resources/variable-compensation-payout-labels.d.ts.map +1 -1
  200. package/resources/variable-compensation-payout-labels.js +3 -2
  201. package/resources/variable-compensation-payout-labels.js.map +1 -1
  202. package/resources/variable-compensation-payout-labels.mjs +3 -2
  203. package/resources/variable-compensation-payout-labels.mjs.map +1 -1
  204. package/resources/variable-compensation-payout-types.d.mts +2 -2
  205. package/resources/variable-compensation-payout-types.d.ts +2 -2
  206. package/resources/variable-compensation-payout-types.js +2 -2
  207. package/resources/variable-compensation-payout-types.mjs +2 -2
  208. package/resources/variable-compensation-payouts.d.mts +5 -2
  209. package/resources/variable-compensation-payouts.d.mts.map +1 -1
  210. package/resources/variable-compensation-payouts.d.ts +5 -2
  211. package/resources/variable-compensation-payouts.d.ts.map +1 -1
  212. package/resources/variable-compensation-payouts.js +5 -2
  213. package/resources/variable-compensation-payouts.js.map +1 -1
  214. package/resources/variable-compensation-payouts.mjs +5 -2
  215. package/resources/variable-compensation-payouts.mjs.map +1 -1
  216. package/src/client.ts +38 -0
  217. package/src/lib/charts/README.md +114 -0
  218. package/src/lib/charts/builders.ts +90 -0
  219. package/src/lib/charts/describe.ts +67 -0
  220. package/src/lib/charts/errors.ts +48 -0
  221. package/src/lib/charts/evaluate.ts +114 -0
  222. package/src/lib/charts/guards.ts +42 -0
  223. package/src/lib/charts/schema.ts +72 -0
  224. package/src/lib/charts/types.ts +113 -0
  225. package/src/lib/charts.ts +43 -0
  226. package/src/lib/manifest/_existing-component-fields.ts +2 -0
  227. package/src/lib/manifest/existing-manifest-context.ts +22 -0
  228. package/src/lib/manifest/workflow/index.ts +64 -0
  229. package/src/resources/activity-log.ts +645 -0
  230. package/src/resources/compensations.ts +1 -1
  231. package/src/resources/developer-program-application.ts +1 -1
  232. package/src/resources/developer-users.ts +2 -1
  233. package/src/resources/hire-requirements.ts +8 -85
  234. package/src/resources/hires.ts +866 -213
  235. package/src/resources/index.ts +13 -0
  236. package/src/resources/listing-submissions.ts +1 -1
  237. package/src/resources/listing-transitions.ts +1 -1
  238. package/src/resources/listing.ts +1 -1
  239. package/src/resources/payroll-payment-mode-changes.ts +121 -0
  240. package/src/resources/payroll-runs/index.ts +1 -0
  241. package/src/resources/payroll-runs/off-cycle.ts +372 -0
  242. package/src/resources/payroll-runs/payroll-runs.ts +10 -0
  243. package/src/resources/sandboxes.ts +17 -11
  244. package/src/resources/variable-compensation-payout-labels.ts +3 -2
  245. package/src/resources/variable-compensation-payout-types.ts +2 -2
  246. package/src/resources/variable-compensation-payouts.ts +5 -2
  247. package/src/version.ts +1 -1
  248. package/version.d.mts +1 -1
  249. package/version.d.ts +1 -1
  250. package/version.js +1 -1
  251. package/version.mjs +1 -1
@@ -7,9 +7,12 @@ import { path } from "../internal/utils/path.mjs";
7
7
  */
8
8
  export class VariableCompensationPayouts extends APIResource {
9
9
  /**
10
- * A list of variable compensation payouts.
10
+ * List variable compensation payouts. Paginated with limit and cursor. Filters use
11
+ * the documented query parameters only (not OData filter). Always uses the company
12
+ * admin payout rowset; callers without admin payout visibility receive an empty
13
+ * list. Retrieve returns NotFound for the same rows.
11
14
  *
12
- * - Requires: `API Tier 1`
15
+ * - Requires: `Variable Compensation Scheduled Payouts API`
13
16
  *
14
17
  * @example HTTP
15
18
  * Representative request and response shapes.
@@ -1 +1 @@
1
- {"version":3,"file":"variable-compensation-payouts.mjs","sourceRoot":"","sources":["../src/resources/variable-compensation-payouts.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAE,WAAW,EAAE,6BAAyB;AAG/C,OAAO,EAAE,aAAa,EAAe,+BAA2B;AAEhE,OAAO,EAAE,IAAI,EAAE,mCAA+B;AAE9C;;GAEG;AACH,MAAM,OAAO,2BAA4B,SAAQ,WAAW;IAC1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0DG;IACH,IAAI,CACF,QAAiE,EAAE,EACnE,OAAwB;QAKxB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAC5B,iCAAiC,EACjC,CAAA,aAAqD,CAAA,EACrD,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CACtB,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEG;IACH,MAAM,CACJ,IAA4C,EAC5C,OAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACpF,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,EAAU,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAA,kCAAkC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;CACF"}
1
+ {"version":3,"file":"variable-compensation-payouts.mjs","sourceRoot":"","sources":["../src/resources/variable-compensation-payouts.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAE,WAAW,EAAE,6BAAyB;AAG/C,OAAO,EAAE,aAAa,EAAe,+BAA2B;AAEhE,OAAO,EAAE,IAAI,EAAE,mCAA+B;AAE9C;;GAEG;AACH,MAAM,OAAO,2BAA4B,SAAQ,WAAW;IAC1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6DG;IACH,IAAI,CACF,QAAiE,EAAE,EACnE,OAAwB;QAKxB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAC5B,iCAAiC,EACjC,CAAA,aAAqD,CAAA,EACrD,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CACtB,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEG;IACH,MAAM,CACJ,IAA4C,EAC5C,OAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACpF,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,EAAU,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAA,kCAAkC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;CACF"}
package/src/client.ts CHANGED
@@ -19,6 +19,14 @@ import { AbstractPage, PageCursorURLResponse } from './core/pagination';
19
19
  import * as Uploads from './core/uploads';
20
20
  import * as API from './resources/index';
21
21
  import { APIPromise } from './core/api-promise';
22
+ import {
23
+ ActivityLog,
24
+ ActivityLogListParams,
25
+ ActivityLogListResponse,
26
+ ActivityLogListResponsesPageCursorURL,
27
+ ActivityLogRetrieveParams,
28
+ ActivityLogRetrieveResponse,
29
+ } from './resources/activity-log';
22
30
  import {
23
31
  AppUserListParams,
24
32
  AppUserListResponse,
@@ -483,6 +491,11 @@ import {
483
491
  PackageVersionComponentUpdateRetrieveResponse,
484
492
  PackageVersionComponentUpdates,
485
493
  } from './resources/package-version-component-updates';
494
+ import {
495
+ PayrollPaymentModeChangeCreateParams,
496
+ PayrollPaymentModeChangeCreateResponse,
497
+ PayrollPaymentModeChanges,
498
+ } from './resources/payroll-payment-mode-changes';
486
499
  import {
487
500
  PlatformCapabilities,
488
501
  PlatformCapabilityListResponse,
@@ -1682,6 +1695,10 @@ export class RipplingSDK {
1682
1695
  * Job related information for the company
1683
1696
  */
1684
1697
  jobPayRateExceptions: API.JobPayRateExceptions = new API.JobPayRateExceptions(this);
1698
+ /**
1699
+ * Visible Activity Log events recorded for the company
1700
+ */
1701
+ activityLog: API.ActivityLog = new API.ActivityLog(this);
1685
1702
  /**
1686
1703
  * Agents defined by the company
1687
1704
  */
@@ -1859,6 +1876,10 @@ export class RipplingSDK {
1859
1876
  packageVersionComponentUpdates: API.PackageVersionComponentUpdates = new API.PackageVersionComponentUpdates(
1860
1877
  this,
1861
1878
  );
1879
+ /**
1880
+ * Payroll runs for the company
1881
+ */
1882
+ payrollPaymentModeChanges: API.PayrollPaymentModeChanges = new API.PayrollPaymentModeChanges(this);
1862
1883
  /**
1863
1884
  * Payroll runs for the company
1864
1885
  */
@@ -1990,6 +2011,7 @@ RipplingSDK.BusinessPartnerGroups = BusinessPartnerGroups;
1990
2011
  RipplingSDK.Functions = Functions;
1991
2012
  RipplingSDK.JobAssignments = JobAssignments;
1992
2013
  RipplingSDK.JobPayRateExceptions = JobPayRateExceptions;
2014
+ RipplingSDK.ActivityLog = ActivityLog;
1993
2015
  RipplingSDK.Agents = Agents;
1994
2016
  RipplingSDK.AppUsers = AppUsers;
1995
2017
  RipplingSDK.BackgroundCheckCandidates = BackgroundCheckCandidates;
@@ -2036,6 +2058,7 @@ RipplingSDK.PackageUninstalls = PackageUninstalls;
2036
2058
  RipplingSDK.PackageUpgrades = PackageUpgrades;
2037
2059
  RipplingSDK.PackageVersions = PackageVersions;
2038
2060
  RipplingSDK.PackageVersionComponentUpdates = PackageVersionComponentUpdates;
2061
+ RipplingSDK.PayrollPaymentModeChanges = PayrollPaymentModeChanges;
2039
2062
  RipplingSDK.PayrollRuns = PayrollRuns;
2040
2063
  RipplingSDK.PlatformCapabilities = PlatformCapabilities;
2041
2064
  RipplingSDK.Reports = Reports;
@@ -2369,6 +2392,15 @@ export declare namespace RipplingSDK {
2369
2392
  type JobPayRateExceptionListChangeLogParams as JobPayRateExceptionListChangeLogParams,
2370
2393
  };
2371
2394
 
2395
+ export {
2396
+ ActivityLog as ActivityLog,
2397
+ type ActivityLogListResponse as ActivityLogListResponse,
2398
+ type ActivityLogRetrieveResponse as ActivityLogRetrieveResponse,
2399
+ type ActivityLogListResponsesPageCursorURL as ActivityLogListResponsesPageCursorURL,
2400
+ type ActivityLogListParams as ActivityLogListParams,
2401
+ type ActivityLogRetrieveParams as ActivityLogRetrieveParams,
2402
+ };
2403
+
2372
2404
  export {
2373
2405
  Agents as Agents,
2374
2406
  type AgentListResponse as AgentListResponse,
@@ -2757,6 +2789,12 @@ export declare namespace RipplingSDK {
2757
2789
  type PackageVersionComponentUpdateCreateParams as PackageVersionComponentUpdateCreateParams,
2758
2790
  };
2759
2791
 
2792
+ export {
2793
+ PayrollPaymentModeChanges as PayrollPaymentModeChanges,
2794
+ type PayrollPaymentModeChangeCreateResponse as PayrollPaymentModeChangeCreateResponse,
2795
+ type PayrollPaymentModeChangeCreateParams as PayrollPaymentModeChangeCreateParams,
2796
+ };
2797
+
2760
2798
  export {
2761
2799
  PayrollRuns as PayrollRuns,
2762
2800
  type PayrollRunListResponse as PayrollRunListResponse,
@@ -0,0 +1,114 @@
1
+ # Chart Rules
2
+
3
+ Handwritten helpers for authoring the _behaviour_ of an AI-generated dashboard
4
+ chart in a form that can be read back and edited.
5
+
6
+ A dashboard chart is drawn by a visualization function the agent writes. Some of
7
+ what that function decides — which colour a bar takes — is worked out fresh each
8
+ render from the data. Written as ordinary code, that decision vanishes into the
9
+ output: the chart shows _what_ colour it drew, never _why_. This library lets the
10
+ agent state the decision as a small rule instead, so the settings panel can show
11
+ it, explain it, and let a user change it.
12
+
13
+ This is not a charting library. It does not render, own an ECharts option, fetch
14
+ data, or touch the DOM. It produces and interprets plain data.
15
+
16
+ ## Scope (v1: conditional colour)
17
+
18
+ v1 is deliberately narrow — the **colour channel only**: colour a series or datum
19
+ by comparing its value against a constant.
20
+
21
+ - **`value`** — this data point's plotted numeric value (a bar's height, a
22
+ point's y, a slice's amount). It is what the rule compares.
23
+ - **Comparisons** — `equals`, `isNot`, `lessThan`, `greaterThan`, `lessOrEqual`, `greaterOrEqual`.
24
+ - **`when(condition, ifTrue, ifFalse?)`** — a conditional value (channel-agnostic).
25
+ `ifFalse` is optional and defaults to `null` — for a colour, no override (default kept).
26
+ - **`color(rule)`** — target the colour channel. Wrapping `when(...)` in `color(...)`
27
+ is what says "this rule sets the colour"; the channel is separate from the condition,
28
+ so more channels (opacity, label visibility) are just more wrappers later.
29
+ - **`literal`** — bare constants (`100`, `'#E24B4A'`) are wrapped automatically.
30
+
31
+ ```ts
32
+ import { color, when, lessThan, greaterThan, value } from '@rippling/rippling-sdk/lib/charts';
33
+
34
+ // red when this point's value is below 100, blue otherwise
35
+ const barColour = color(when(lessThan(value, 100), '#E24B4A', '#378ADD'));
36
+
37
+ // highlight only the points over target; leave the rest their default colour
38
+ const highlight = color(when(greaterThan(value, 1000), '#E24B4A'));
39
+ ```
40
+
41
+ ## Intended flow
42
+
43
+ ```text
44
+ Agent writes a rule with these builders (the only consumer that imports the SDK)
45
+ -> color(when(lessThan(value, 100), '#E24B4A', '#378ADD')) returns a {$rule} placeholder
46
+ -> the placeholder is emitted into the chart option, like the {$fn} placeholders
47
+ a chart already emits, and crosses to the app as plain JSON
48
+ -> renderer resolves {$rule} against the point's value -> a colour, drawn
49
+ -> settings panel reads the same {$rule} tree -> controls the user can edit
50
+ ```
51
+
52
+ ```json
53
+ {
54
+ "channel": "color",
55
+ "$rule": {
56
+ "kind": "ifElse",
57
+ "cond": { "kind": "lessThan", "left": { "kind": "value" }, "right": { "kind": "literal", "value": 100 } },
58
+ "then": { "kind": "literal", "value": "#E24B4A" },
59
+ "else": { "kind": "literal", "value": "#378ADD" }
60
+ }
61
+ }
62
+ ```
63
+
64
+ `channel: 'color'` says what the rule targets, so a reader sees it without
65
+ inferring from where it sits. `evaluate(rule, { value })` resolves it to a colour
66
+ for the renderer; `describe(rule)` turns it into the controls the settings panel
67
+ shows. Both accept the placeholder or the bare tree. A node can only ever be one
68
+ of a fixed set of kinds, so the three faces never drift — the `chartRuleSchema`
69
+ export describes that closed set.
70
+
71
+ ## How it is consumed
72
+
73
+ The app never has to import this package. The rule crosses as data — a `{$rule}`
74
+ placeholder alongside the `{$fn}` ones — and the app's own rehydrator resolves it
75
+ at render time. Two ways, and only the first is needed:
76
+
77
+ 1. **Contract-only** — the app keeps its own small evaluator and validates it
78
+ against `chartRuleSchema` (published here) with a contract test, so the two
79
+ can't drift without CI noticing. No dependency on this package.
80
+ 2. **Shared** — the app imports `evaluate`/`describe` from here, so the closed
81
+ set is defined exactly once. A no-drift choice, not a requirement.
82
+
83
+ ## Where it is going
84
+
85
+ The vocabulary starts small on purpose and is built to grow. Each addition is a
86
+ new kind (or channel) — one builder, one `evaluate` case, one `describe` case,
87
+ one `schema` entry — and it becomes editable in the panel the moment it lands,
88
+ with no change to charts already using it. Planned next, roughly in order:
89
+
90
+ - **More channels** — opacity, label visibility (`show`), and the like, added
91
+ alongside `channel: 'color'`.
92
+ - **Collection refs + aggregates** — `rows`, `series`, and `count`/`sum`/`avg`/`min`/`max`,
93
+ so a rule can compare a point against the series (e.g. the max bar, or below average).
94
+ - **Logic** — `and`, `or`, `not` to compose several conditions.
95
+ - **More refs** — `index`, `name`, `field('column')`.
96
+ - **`percentile`, arithmetic** (`plus`, `minus`, `mod`), **`between`, `isIn`**.
97
+ - **Shaping** — `filter`, `sortBy`, `limit`, `groupSmallest` (change the data before it is drawn).
98
+
99
+ ## What this library does not do
100
+
101
+ - It does not render or hold an ECharts option — it returns values and controls.
102
+ - It has no I/O. A rule cannot reach the network, the DOM, or the clock, because
103
+ there is no node for it. Evaluating a rule reads only the context it is given.
104
+
105
+ ## Safety
106
+
107
+ A rule is data, not code, so evaluating one is not running code. The vocabulary
108
+ has no primitive with a side effect, so an untrusted, user-edited tree is safe
109
+ to evaluate: the worst a malformed tree can do is throw a `ChartRuleError`, which
110
+ the caller catches and turns into the read-only "configured in code" state. There
111
+ are no loops or recursion, and a tree nested past `MAX_RULE_DEPTH` throws
112
+ `RuleDepthError` (also a `ChartRuleError`) rather than overflowing the stack.
113
+ Catch `ChartRuleError` — every failure mode is a subclass of it (`UnknownNodeError`,
114
+ `RuleTypeError`, `RuleDepthError`).
@@ -0,0 +1,90 @@
1
+ import { ChartRuleError } from './errors';
2
+ import {
3
+ type ComparisonKind,
4
+ type ComparisonNode,
5
+ type IfElseNode,
6
+ type LiteralNode,
7
+ type RefNode,
8
+ type RuleNode,
9
+ type RulePlaceholder,
10
+ type Scalar,
11
+ } from './types';
12
+
13
+ /** A rule node, a nested rule (`{$rule}` placeholder), or a bare scalar. */
14
+ export type Operand = RuleNode | RulePlaceholder | Scalar;
15
+
16
+ function isRuleNode(operand: Operand): operand is RuleNode {
17
+ return typeof operand === 'object' && operand !== null && 'kind' in operand;
18
+ }
19
+
20
+ /** True when a value is a `{$rule}` placeholder — the marker the builders emit. */
21
+ export function isRulePlaceholder(value: unknown): value is RulePlaceholder {
22
+ return typeof value === 'object' && value !== null && '$rule' in value;
23
+ }
24
+
25
+ /** Wrap a bare scalar as a literal node. */
26
+ export function literal(value: Scalar): LiteralNode {
27
+ return { kind: 'literal', value };
28
+ }
29
+
30
+ function toNode(operand: Operand): RuleNode {
31
+ if (isRulePlaceholder(operand)) {
32
+ return operand.$rule; // a nested rule — unwrap it, never wrap it as a literal
33
+ }
34
+ return isRuleNode(operand) ? operand : literal(operand);
35
+ }
36
+
37
+ /**
38
+ * `value` — this data point's plotted numeric value: a bar's height, a point's
39
+ * y, a slice's amount. It is what a colour rule compares against a constant.
40
+ */
41
+ export const value: RefNode = Object.freeze({ kind: 'value' });
42
+
43
+ /* Comparisons — return a condition. */
44
+ function comparison(kind: ComparisonKind): (left: Operand, right: Operand) => ComparisonNode {
45
+ return (left, right) => ({ kind, left: toNode(left), right: toNode(right) });
46
+ }
47
+ export const equals = comparison('equals');
48
+ export const isNot = comparison('isNot');
49
+ export const lessThan = comparison('lessThan');
50
+ export const greaterThan = comparison('greaterThan');
51
+ export const lessOrEqual = comparison('lessOrEqual');
52
+ export const greaterOrEqual = comparison('greaterOrEqual');
53
+
54
+ /**
55
+ * A conditional value: pick `ifTrue` when the condition holds, else `ifFalse`.
56
+ * Channel-agnostic — wrap it in a channel builder (`color`) to target something.
57
+ *
58
+ * when(lessThan(value, 100), '#E24B4A', '#378ADD')
59
+ * // → '#E24B4A' when this point's value is under 100, '#378ADD' otherwise
60
+ *
61
+ * `ifFalse` is optional and defaults to `null` — for a colour, that means no
62
+ * override (the chart's default is kept). Returns a plain node, not a placeholder.
63
+ */
64
+ export function when(condition: RuleNode, ifTrue: Operand, ifFalse?: Operand): IfElseNode {
65
+ if (ifTrue === undefined) {
66
+ throw new ChartRuleError('when(condition, ifTrue, ifFalse?) needs a value for the true case');
67
+ }
68
+ return {
69
+ kind: 'ifElse',
70
+ cond: condition,
71
+ then: toNode(ifTrue),
72
+ else: toNode(ifFalse ?? null),
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Target the colour channel — the v1 channel. Wrap a conditional value so the
78
+ * renderer knows it resolves to a colour, and the panel knows what it edits.
79
+ *
80
+ * color(when(lessThan(value, 100), '#E24B4A', '#378ADD'))
81
+ * // → red when this point's value is under 100, blue otherwise
82
+ *
83
+ * Takes a conditional value — a `when(...)` (`IfElseNode`) or an already-wrapped
84
+ * rule — not a bare `value` or comparison: those resolve to a number or a
85
+ * boolean, which is not a colour. `evaluate` enforces the same at runtime for a
86
+ * deserialized rule. Returns a `{$rule}` placeholder tagged `channel: 'color'`.
87
+ */
88
+ export function color(rule: IfElseNode | RulePlaceholder): RulePlaceholder {
89
+ return { $rule: isRulePlaceholder(rule) ? rule.$rule : rule, channel: 'color' };
90
+ }
@@ -0,0 +1,67 @@
1
+ import { isRulePlaceholder } from './builders';
2
+ import { RuleDepthError, UnknownNodeError } from './errors';
3
+ import { assertRuleNode, literalValue } from './guards';
4
+ import { MAX_RULE_DEPTH, type Control, type Rule, type RuleNode } from './types';
5
+
6
+ /**
7
+ * Turn a rule into the shape the settings panel renders: a label plus its
8
+ * editable parts. Accepts a `{$rule}` placeholder or a bare tree. Walks the same
9
+ * tree `evaluate` runs — and validates each node the same way — so a malformed or
10
+ * unknown node throws a `ChartRuleError` here too, never a native `TypeError`.
11
+ * The unwrap is gated on `isRulePlaceholder` (not a raw `'$rule' in rule`) so a
12
+ * `null`/primitive rule reaches `assertRuleNode` instead of throwing on `in`.
13
+ * A tree nested past `MAX_RULE_DEPTH` throws `RuleDepthError`.
14
+ */
15
+ export function describe(rule: Rule): Control {
16
+ if (isRulePlaceholder(rule)) {
17
+ return visit(rule.$rule, 0);
18
+ }
19
+ return visit(rule, 0);
20
+ }
21
+
22
+ function visit(node: RuleNode, depth: number): Control {
23
+ if (depth > MAX_RULE_DEPTH) {
24
+ throw new RuleDepthError(MAX_RULE_DEPTH);
25
+ }
26
+ assertRuleNode(node);
27
+ const next = depth + 1;
28
+ switch (node.kind) {
29
+ case 'value':
30
+ return { role: 'ref', label: "this row's value" };
31
+ case 'literal': {
32
+ const scalar = literalValue(node);
33
+ return { role: 'literal', label: String(scalar), value: scalar };
34
+ }
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
+
49
+ case 'ifElse':
50
+ return {
51
+ role: 'rule',
52
+ label: 'when',
53
+ parts: [visit(node.cond, next), visit(node.then, next), visit(node.else, next)],
54
+ };
55
+
56
+ default:
57
+ return unreachable(node);
58
+ }
59
+ }
60
+
61
+ function comparison(label: string, left: RuleNode, right: RuleNode, depth: number): Control {
62
+ return { role: 'comparison', label, parts: [visit(left, depth), visit(right, depth)] };
63
+ }
64
+
65
+ function unreachable(node: never): never {
66
+ throw new UnknownNodeError((node as { kind?: string }).kind);
67
+ }
@@ -0,0 +1,48 @@
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(public readonly kind?: string) {
10
+ super(`Unknown chart-rule node: ${kind ?? '(missing kind)'}`);
11
+ this.name = 'UnknownNodeError';
12
+ }
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: string) {
18
+ super(message);
19
+ this.name = 'RuleTypeError';
20
+ }
21
+ }
22
+
23
+ /**
24
+ * A structurally invalid node in a deserialized tree: not an object, no string
25
+ * `kind`, or a `literal` without a scalar `value`. Distinct from
26
+ * `UnknownNodeError` (a well-formed node whose `kind` is simply not in the
27
+ * vocabulary — the intentional escape hatch). Like the others it is a
28
+ * `ChartRuleError`, so a caller reading an untrusted rule catches it instead of
29
+ * a native `TypeError` (or, worse, an `undefined` slipping through silently).
30
+ */
31
+ export class MalformedRuleError extends ChartRuleError {
32
+ constructor(message: string) {
33
+ super(message);
34
+ this.name = 'MalformedRuleError';
35
+ }
36
+ }
37
+
38
+ /**
39
+ * A rule nested deeper than the evaluator will walk. Guards against a
40
+ * stack-overflowing tree from untrusted, deserialized input; like the others it
41
+ * is a `ChartRuleError`, so the caller's escape hatch catches it.
42
+ */
43
+ export class RuleDepthError extends ChartRuleError {
44
+ constructor(maxDepth: number) {
45
+ super(`chart rule nested deeper than ${maxDepth} levels`);
46
+ this.name = 'RuleDepthError';
47
+ }
48
+ }
@@ -0,0 +1,114 @@
1
+ import { isRulePlaceholder } from './builders';
2
+ import { MalformedRuleError, RuleDepthError, RuleTypeError, UnknownNodeError } from './errors';
3
+ import { assertRuleNode, literalValue } from './guards';
4
+ import {
5
+ MAX_RULE_DEPTH,
6
+ type Rule,
7
+ type RuleChannel,
8
+ type RuleContext,
9
+ type RuleNode,
10
+ type RuleValue,
11
+ } from './types';
12
+
13
+ /**
14
+ * Resolve a rule to a value against `ctx`. Accepts a `{$rule}` placeholder or a
15
+ * bare tree. A malformed or unknown node throws a `ChartRuleError` (never a
16
+ * native `TypeError`), so a caller reading an untrusted, deserialized rule can
17
+ * catch every failure with one type. When the rule is a colour placeholder, the
18
+ * result is checked to be a colour (`string | null`) — a rule that resolves to a
19
+ * number or boolean is a `RuleTypeError`, not something the renderer paints.
20
+ *
21
+ * Pure: the only inputs are the node and the context. No clock, no randomness,
22
+ * no I/O — which is what makes it safe to run on an untrusted, user-edited tree
23
+ * and identical across the renderer, the panel readout, and a test. A tree
24
+ * nested past `MAX_RULE_DEPTH` throws `RuleDepthError` rather than overflowing.
25
+ */
26
+ export function evaluate(rule: Rule, ctx: RuleContext): RuleValue {
27
+ if (isRulePlaceholder(rule)) {
28
+ return coerceForChannel(rule.channel, visit(rule.$rule, ctx, 0));
29
+ }
30
+ return visit(rule, ctx, 0);
31
+ }
32
+
33
+ function visit(node: RuleNode, ctx: RuleContext, depth: number): RuleValue {
34
+ if (depth > MAX_RULE_DEPTH) {
35
+ throw new RuleDepthError(MAX_RULE_DEPTH);
36
+ }
37
+ assertRuleNode(node);
38
+ const next = depth + 1;
39
+ switch (node.kind) {
40
+ case 'value':
41
+ return ctx.value;
42
+ case 'literal':
43
+ return literalValue(node);
44
+
45
+ case 'equals':
46
+ return visit(node.left, ctx, next) === visit(node.right, ctx, next);
47
+ case 'isNot':
48
+ return visit(node.left, ctx, next) !== visit(node.right, ctx, next);
49
+ case 'lessThan':
50
+ return num(visit(node.left, ctx, next)) < num(visit(node.right, ctx, next));
51
+ case 'greaterThan':
52
+ return num(visit(node.left, ctx, next)) > num(visit(node.right, ctx, next));
53
+ case 'lessOrEqual':
54
+ return num(visit(node.left, ctx, next)) <= num(visit(node.right, ctx, next));
55
+ case 'greaterOrEqual':
56
+ return num(visit(node.left, ctx, next)) >= num(visit(node.right, ctx, next));
57
+
58
+ case 'ifElse':
59
+ return bool(visit(node.cond, ctx, next)) ? visit(node.then, ctx, next) : visit(node.else, ctx, next);
60
+
61
+ default:
62
+ return unreachable(node);
63
+ }
64
+ }
65
+
66
+ /* -------------------------------------------------------------------------- */
67
+ /* Coercions — narrow a RuleValue, or throw a typed error. */
68
+ /* -------------------------------------------------------------------------- */
69
+
70
+ function num(value: RuleValue): number {
71
+ if (typeof value === 'number') {
72
+ return value;
73
+ }
74
+ throw new RuleTypeError(`expected a number, got ${typeName(value)}`);
75
+ }
76
+
77
+ function bool(value: RuleValue): boolean {
78
+ if (typeof value === 'boolean') {
79
+ return value;
80
+ }
81
+ throw new RuleTypeError(`expected a boolean, got ${typeName(value)}`);
82
+ }
83
+
84
+ /** A colour channel must resolve to a colour string, or null for "no override". */
85
+ function asColor(value: RuleValue): RuleValue {
86
+ if (value === null || typeof value === 'string') {
87
+ return value;
88
+ }
89
+ throw new RuleTypeError(`a colour rule must resolve to a colour string or null, got ${typeName(value)}`);
90
+ }
91
+
92
+ /**
93
+ * Coerce a resolved value to what its channel can use. A colour rule must
94
+ * resolve to a colour; a future channel would add its own case here. A
95
+ * placeholder whose `channel` is missing or unrecognised (only possible from
96
+ * untrusted, deserialized input — the type and schema both pin it to `'color'`)
97
+ * is malformed rather than silently unchecked.
98
+ */
99
+ function coerceForChannel(channel: RuleChannel, value: RuleValue): RuleValue {
100
+ switch (channel) {
101
+ case 'color':
102
+ return asColor(value);
103
+ default:
104
+ throw new MalformedRuleError(`a rule placeholder has an unsupported channel: ${String(channel)}`);
105
+ }
106
+ }
107
+
108
+ function typeName(value: RuleValue): string {
109
+ return value === null ? 'null' : typeof value;
110
+ }
111
+
112
+ function unreachable(node: never): never {
113
+ throw new UnknownNodeError((node as { kind?: string }).kind);
114
+ }
@@ -0,0 +1,42 @@
1
+ import { MalformedRuleError } from './errors';
2
+ import { type RuleNode, type Scalar } from './types';
3
+
4
+ /**
5
+ * Runtime validation for one node of a deserialized, untrusted rule tree, shared
6
+ * by `evaluate` and `describe`. A rule can arrive from JSON that TypeScript never
7
+ * checked, so `null`, a non-object, or a node without a string `kind` would throw
8
+ * a native `TypeError` on the first field read — skipping the `ChartRuleError`
9
+ * escape hatch a caller relies on. Validate before reading fields.
10
+ */
11
+
12
+ const SCALAR_TYPES: ReadonlySet<string> = new Set(['number', 'string', 'boolean']);
13
+
14
+ /**
15
+ * Assert `node` is shaped like a rule node — an object carrying a string `kind`.
16
+ * An unrecognised `kind` is *not* rejected here; that is the caller's `switch`
17
+ * default (`UnknownNodeError`), the deliberate "configured in code" signal.
18
+ */
19
+ export function assertRuleNode(node: unknown): asserts node is RuleNode {
20
+ if (
21
+ node === null ||
22
+ typeof node !== 'object' ||
23
+ Array.isArray(node) ||
24
+ typeof (node as { kind?: unknown }).kind !== 'string'
25
+ ) {
26
+ throw new MalformedRuleError('a rule node must be an object with a string "kind"');
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Read a `literal` node's `value`, rejecting a missing or non-scalar one. Without
32
+ * this, `{ kind: 'literal' }` resolves to `undefined` and slips past the caller.
33
+ */
34
+ export function literalValue(node: { value?: unknown }): Scalar {
35
+ const { value } = node;
36
+ if (value === null || SCALAR_TYPES.has(typeof value)) {
37
+ return value as Scalar;
38
+ }
39
+ throw new MalformedRuleError(
40
+ `a literal must carry a scalar value, got ${value === undefined ? 'undefined' : typeof value}`,
41
+ );
42
+ }
@@ -0,0 +1,72 @@
1
+ import { CHART_RULE_CONTRACT_VERSION } from './types';
2
+
3
+ /** Stable identifier for the published contract, versioned by the tag. */
4
+ export const CHART_RULE_SCHEMA_ID = `https://rippling.com/schemas/${CHART_RULE_CONTRACT_VERSION}.json`;
5
+
6
+ /**
7
+ * JSON Schema (2020-12) for the `{$rule}` placeholder and its closed node set.
8
+ *
9
+ * This is the contract. A consumer that keeps its own rule evaluator (rather
10
+ * than importing `evaluate`) can validate against this so the two never drift —
11
+ * every kind and operand shape the builders can emit is described here.
12
+ */
13
+ export const chartRuleSchema = {
14
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
15
+ $id: CHART_RULE_SCHEMA_ID,
16
+ title: 'Chart rule placeholder',
17
+ description: 'A rule tree the chart agent emits into a chart option, marked with $rule.',
18
+ type: 'object',
19
+ required: ['$rule', 'channel'],
20
+ additionalProperties: false,
21
+ properties: {
22
+ // A colour rule's top-level tree is the conditional-value form (`when(...)`),
23
+ // matching what `color()` builds and accepts. A bare ref/comparison/literal
24
+ // resolves to a number/boolean/constant, not a colour decision.
25
+ $rule: { $ref: '#/$defs/ifElse' },
26
+ channel: { const: 'color' },
27
+ },
28
+ $defs: {
29
+ scalar: { type: ['number', 'string', 'boolean', 'null'] },
30
+ node: {
31
+ oneOf: [
32
+ { $ref: '#/$defs/ref' },
33
+ { $ref: '#/$defs/literal' },
34
+ { $ref: '#/$defs/comparison' },
35
+ { $ref: '#/$defs/ifElse' },
36
+ ],
37
+ },
38
+ ref: {
39
+ type: 'object',
40
+ required: ['kind'],
41
+ additionalProperties: false,
42
+ properties: { kind: { const: 'value' } },
43
+ },
44
+ literal: {
45
+ type: 'object',
46
+ required: ['kind', 'value'],
47
+ additionalProperties: false,
48
+ properties: { kind: { const: 'literal' }, value: { $ref: '#/$defs/scalar' } },
49
+ },
50
+ comparison: {
51
+ type: 'object',
52
+ required: ['kind', 'left', 'right'],
53
+ additionalProperties: false,
54
+ properties: {
55
+ kind: { enum: ['equals', 'isNot', 'lessThan', 'greaterThan', 'lessOrEqual', 'greaterOrEqual'] },
56
+ left: { $ref: '#/$defs/node' },
57
+ right: { $ref: '#/$defs/node' },
58
+ },
59
+ },
60
+ ifElse: {
61
+ type: 'object',
62
+ required: ['kind', 'cond', 'then', 'else'],
63
+ additionalProperties: false,
64
+ properties: {
65
+ kind: { const: 'ifElse' },
66
+ cond: { $ref: '#/$defs/node' },
67
+ then: { $ref: '#/$defs/node' },
68
+ else: { $ref: '#/$defs/node' },
69
+ },
70
+ },
71
+ },
72
+ } as const;