@stripe/extensibility-sdk 0.24.1 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +328 -0
  2. package/dist/config-values/generate.cjs +1 -1
  3. package/dist/config-values/generate.d.ts +2 -0
  4. package/dist/config-values/generate.d.ts.map +1 -1
  5. package/dist/config-values/generate.js +1 -1
  6. package/dist/extensibility-sdk-alpha.d.ts +141 -98
  7. package/dist/extensibility-sdk-beta.d.ts +141 -98
  8. package/dist/extensibility-sdk-extensions-alpha.d.ts +155 -25
  9. package/dist/extensibility-sdk-extensions-beta.d.ts +155 -25
  10. package/dist/extensibility-sdk-extensions-internal.d.ts +160 -26
  11. package/dist/extensibility-sdk-extensions-public.d.ts +155 -25
  12. package/dist/extensibility-sdk-internal-alpha.d.ts +5 -0
  13. package/dist/extensibility-sdk-internal-beta.d.ts +5 -0
  14. package/dist/extensibility-sdk-internal-internal.d.ts +5 -0
  15. package/dist/extensibility-sdk-internal-public.d.ts +5 -0
  16. package/dist/extensibility-sdk-internal.d.ts +144 -82
  17. package/dist/extensibility-sdk-public.d.ts +141 -98
  18. package/dist/extensibility-sdk-stdlib-alpha.d.ts +146 -98
  19. package/dist/extensibility-sdk-stdlib-beta.d.ts +146 -98
  20. package/dist/extensibility-sdk-stdlib-internal.d.ts +149 -82
  21. package/dist/extensibility-sdk-stdlib-public.d.ts +146 -98
  22. package/dist/extensions/billing/bill/discount_calculation.d.ts +5 -3
  23. package/dist/extensions/billing/customer_balance_application.d.ts +3 -1
  24. package/dist/extensions/billing/invoice_collection_setting.d.ts +15 -11
  25. package/dist/extensions/billing/prorations.d.ts +30 -21
  26. package/dist/extensions/billing/recurring_billing_item_handling.d.ts +41 -23
  27. package/dist/extensions/billing/types.d.ts +4 -4
  28. package/dist/extensions/core/workflows/custom_action.d.ts +6 -2
  29. package/dist/extensions/extend/workflows/custom_action.d.ts +6 -2
  30. package/dist/index.cjs +398 -163
  31. package/dist/index.js +395 -158
  32. package/dist/internal.d.ts +4 -0
  33. package/dist/internal.d.ts.map +1 -1
  34. package/dist/stdlib/brand.d.ts +16 -10
  35. package/dist/stdlib/brand.d.ts.map +1 -1
  36. package/dist/stdlib/decimal.d.ts +50 -22
  37. package/dist/stdlib/decimal.d.ts.map +1 -1
  38. package/dist/stdlib/index.cjs +398 -163
  39. package/dist/stdlib/index.d.ts +11 -5
  40. package/dist/stdlib/index.d.ts.map +1 -1
  41. package/dist/stdlib/index.js +395 -158
  42. package/dist/stdlib/refs.d.ts +12 -20
  43. package/dist/stdlib/refs.d.ts.map +1 -1
  44. package/dist/stdlib/scalars.d.ts +51 -36
  45. package/dist/stdlib/scalars.d.ts.map +1 -1
  46. package/dist/stdlib/to-const.d.ts +35 -0
  47. package/dist/stdlib/to-const.d.ts.map +1 -0
  48. package/dist/stdlib/transforms.d.ts +1 -1
  49. package/dist/stdlib/type-utils.d.ts +3 -1
  50. package/dist/stdlib/types.d.ts +11 -11
  51. package/dist/stdlib/types.d.ts.map +1 -1
  52. package/dist/tsconfig.build.tsbuildinfo +1 -1
  53. package/package.json +11 -11
  54. package/dist/api-surface.d.ts.map +0 -1
@@ -26,10 +26,6 @@ __export(stdlib_exports, {
26
26
  Integer: () => Integer,
27
27
  PositiveInteger: () => PositiveInteger,
28
28
  Ref: () => Ref,
29
- StreetAddress: () => StreetAddress,
30
- Timestamp: () => Timestamp,
31
- WireReadError: () => WireReadError,
32
- WireWriteError: () => WireWriteError,
33
29
  _ConfigEnum: () => _ConfigEnum,
34
30
  _JsonWireToType: () => _JsonWireToType,
35
31
  _ProtoEnum: () => _ProtoEnum,
@@ -37,6 +33,8 @@ __export(stdlib_exports, {
37
33
  _ShapeDescriptor: () => _ShapeDescriptor,
38
34
  _TypeToProtoWire: () => _TypeToProtoWire,
39
35
  _UnionDescriptor: () => _UnionDescriptor,
36
+ _WireReadError: () => _WireReadError,
37
+ _WireWriteError: () => _WireWriteError,
40
38
  _apply: () => _apply,
41
39
  _applyConfig: () => _applyConfig,
42
40
  _applyIncoming: () => _applyIncoming,
@@ -52,123 +50,12 @@ __export(stdlib_exports, {
52
50
  _translateMap: () => _translateMap,
53
51
  _translateShape: () => _translateShape,
54
52
  _translateUnion: () => _translateUnion,
55
- isDecimal: () => isDecimal
53
+ toConst: () => toConst
56
54
  });
57
55
  module.exports = __toCommonJS(stdlib_exports);
58
56
 
59
57
  // src/stdlib/scalars.ts
60
58
  var import_core = require("@formspec/core");
61
- function roundToInteger(value, direction) {
62
- switch (direction) {
63
- case "ceil":
64
- return Math.ceil(value);
65
- case "floor":
66
- return Math.floor(value);
67
- case "round-down":
68
- return Math.trunc(value);
69
- case "round-up":
70
- return value >= 0 ? Math.ceil(value) : Math.floor(value);
71
- case "half-up":
72
- return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5);
73
- default: {
74
- const _exhaustive = direction;
75
- throw new Error(`Unknown rounding direction: ${String(_exhaustive)}`);
76
- }
77
- }
78
- }
79
- var Integer = {
80
- /**
81
- * Type guard that narrows a `number` to {@link (Integer:type)}.
82
- *
83
- * @example
84
- * ```ts
85
- * const n: number = getCount();
86
- * if (Integer.is(n)) {
87
- * // n is Integer here
88
- * config.retryCount = n;
89
- * }
90
- * ```
91
- * @public
92
- */
93
- is: (value) => Number.isInteger(value),
94
- /**
95
- * Coerces a number to an {@link (Integer:type)} by rounding.
96
- * Throws if the value is not finite.
97
- *
98
- * @example
99
- * ```ts
100
- * const price = 9.99;
101
- * const rounded = Integer.from(price, 'floor'); // 9
102
- * const ceiled = Integer.from(price, 'ceil'); // 10
103
- * ```
104
- * @public
105
- */
106
- from: (value, rounding) => {
107
- if (!Number.isFinite(value)) {
108
- throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
109
- }
110
- return roundToInteger(value, rounding);
111
- }
112
- };
113
- var PositiveInteger = {
114
- /**
115
- * Type guard that narrows a `number` to {@link (PositiveInteger:type)}.
116
- *
117
- * @example
118
- * ```ts
119
- * const n: number = getRetryCount();
120
- * if (PositiveInteger.is(n)) {
121
- * // n is PositiveInteger here
122
- * config.maxRetries = n;
123
- * }
124
- * ```
125
- * @public
126
- */
127
- is: (value) => Number.isInteger(value) && value >= 0,
128
- /**
129
- * Coerces a number to a {@link (PositiveInteger:type)} by rounding.
130
- * Throws if the value is not finite or the rounded result is negative.
131
- *
132
- * @example
133
- * ```ts
134
- * const ratio = 2.7;
135
- * const count = PositiveInteger.from(ratio, 'floor'); // 2
136
- * ```
137
- * @public
138
- */
139
- from: (value, rounding) => {
140
- if (!Number.isFinite(value)) {
141
- throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
142
- }
143
- const rounded = roundToInteger(value, rounding) || 0;
144
- if (rounded < 0) {
145
- throw new Error(
146
- `Value ${String(value)} rounds to ${String(rounded)}, which is negative`
147
- );
148
- }
149
- return rounded;
150
- }
151
- };
152
- var StreetAddress = {
153
- create: (address) => {
154
- return address;
155
- }
156
- };
157
- var Timestamp = {
158
- create: (value) => {
159
- return value;
160
- }
161
- };
162
-
163
- // src/stdlib/refs.ts
164
- var Ref = {
165
- create: (step) => {
166
- return {
167
- type: step.object,
168
- id: step.id
169
- };
170
- }
171
- };
172
59
 
173
60
  // src/stdlib/decimal.ts
174
61
  var PLAIN_NOTATION_DIGIT_LIMIT = 30;
@@ -185,6 +72,9 @@ var DecimalRoundingPresets = Object.freeze({
185
72
  var DEFAULT_DIV_PRECISION = 34;
186
73
  var IMPLICIT_DECIMAL_COERCION_ERROR = "Implicit Decimal coercion is not allowed; use .add(), .sub(), .mul(), .div(), .toString(), or .toNumber() explicitly.";
187
74
  var MAX_EXPONENT = Number.MAX_SAFE_INTEGER;
75
+ function normalizeZero(value) {
76
+ return Object.is(value, -0) ? 0 : value;
77
+ }
188
78
  var DECIMAL_BRAND = /* @__PURE__ */ Symbol.for(
189
79
  "stripe.apps-extensibility-sdk.Decimal"
190
80
  );
@@ -298,13 +188,13 @@ var DecimalImpl = class _DecimalImpl {
298
188
  /**
299
189
  * Return the sum of this value and `other`.
300
190
  *
301
- * @param other - The addend.
191
+ * @param other - The addend. Accepts any {@link DecimalLike} value.
302
192
  * @returns A new {@link Decimal} equal to `this + other`.
303
193
  *
304
194
  * @public
305
195
  */
306
196
  add(other) {
307
- const otherImpl = toImpl(other);
197
+ const otherImpl = coerceToImpl(other);
308
198
  if (this.#exponent === otherImpl.#exponent) {
309
199
  return toDecimal(
310
200
  new _DecimalImpl(this.#coefficient + otherImpl.#coefficient, this.#exponent)
@@ -331,13 +221,13 @@ var DecimalImpl = class _DecimalImpl {
331
221
  /**
332
222
  * Return the difference of this value and `other`.
333
223
  *
334
- * @param other - The subtrahend.
224
+ * @param other - The subtrahend. Accepts any {@link DecimalLike} value.
335
225
  * @returns A new {@link Decimal} equal to `this - other`.
336
226
  *
337
227
  * @public
338
228
  */
339
229
  sub(other) {
340
- const otherImpl = toImpl(other);
230
+ const otherImpl = coerceToImpl(other);
341
231
  if (this.#exponent === otherImpl.#exponent) {
342
232
  return toDecimal(
343
233
  new _DecimalImpl(this.#coefficient - otherImpl.#coefficient, this.#exponent)
@@ -364,13 +254,13 @@ var DecimalImpl = class _DecimalImpl {
364
254
  /**
365
255
  * Return the product of this value and `other`.
366
256
  *
367
- * @param other - The multiplicand.
257
+ * @param other - The multiplicand. Accepts any {@link DecimalLike} value.
368
258
  * @returns A new {@link Decimal} equal to `this × other`.
369
259
  *
370
260
  * @public
371
261
  */
372
262
  mul(other) {
373
- const otherImpl = toImpl(other);
263
+ const otherImpl = coerceToImpl(other);
374
264
  return toDecimal(
375
265
  new _DecimalImpl(
376
266
  this.#coefficient * otherImpl.#coefficient,
@@ -397,7 +287,7 @@ var DecimalImpl = class _DecimalImpl {
397
287
  * Decimal.from('5').div(Decimal.from('2'), 0, 'half-even'); // "2"
398
288
  * ```
399
289
  *
400
- * @param other - The divisor. Must not be zero.
290
+ * @param other - The divisor. Must not be zero. Accepts any {@link DecimalLike} value.
401
291
  * @param precision - Maximum number of decimal digits in the result.
402
292
  * @param direction - How to round when the exact quotient cannot
403
293
  * be represented at the requested precision.
@@ -412,7 +302,7 @@ var DecimalImpl = class _DecimalImpl {
412
302
  if (precision < 0 || !Number.isInteger(precision)) {
413
303
  throw new Error("precision must be a non-negative integer");
414
304
  }
415
- const otherImpl = toImpl(other);
305
+ const otherImpl = coerceToImpl(other);
416
306
  if (otherImpl.#coefficient === 0n) {
417
307
  throw new Error("Division by zero");
418
308
  }
@@ -454,13 +344,13 @@ var DecimalImpl = class _DecimalImpl {
454
344
  * a.cmp(a); // 0
455
345
  * ```
456
346
  *
457
- * @param other - The value to compare against.
347
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
458
348
  * @returns `-1` if `this < other`, `0` if equal, `1` if `this > other`.
459
349
  *
460
350
  * @public
461
351
  */
462
352
  cmp(other) {
463
- const otherImpl = toImpl(other);
353
+ const otherImpl = coerceToImpl(other);
464
354
  if (this.#exponent === otherImpl.#exponent) {
465
355
  if (this.#coefficient < otherImpl.#coefficient) return -1;
466
356
  if (this.#coefficient > otherImpl.#coefficient) return 1;
@@ -483,7 +373,7 @@ var DecimalImpl = class _DecimalImpl {
483
373
  /**
484
374
  * Return `true` if this value is numerically equal to `other`.
485
375
  *
486
- * @param other - The value to compare against.
376
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
487
377
  * @returns `true` if `this === other` in value, `false` otherwise.
488
378
  *
489
379
  * @public
@@ -494,7 +384,7 @@ var DecimalImpl = class _DecimalImpl {
494
384
  /**
495
385
  * Return `true` if this value is strictly less than `other`.
496
386
  *
497
- * @param other - The value to compare against.
387
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
498
388
  * @returns `true` if `this < other`, `false` otherwise.
499
389
  *
500
390
  * @public
@@ -505,7 +395,7 @@ var DecimalImpl = class _DecimalImpl {
505
395
  /**
506
396
  * Return `true` if this value is less than or equal to `other`.
507
397
  *
508
- * @param other - The value to compare against.
398
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
509
399
  * @returns `true` if `this ≤ other`, `false` otherwise.
510
400
  *
511
401
  * @public
@@ -516,7 +406,7 @@ var DecimalImpl = class _DecimalImpl {
516
406
  /**
517
407
  * Return `true` if this value is strictly greater than `other`.
518
408
  *
519
- * @param other - The value to compare against.
409
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
520
410
  * @returns `true` if `this > other`, `false` otherwise.
521
411
  *
522
412
  * @public
@@ -527,7 +417,7 @@ var DecimalImpl = class _DecimalImpl {
527
417
  /**
528
418
  * Return `true` if this value is greater than or equal to `other`.
529
419
  *
530
- * @param other - The value to compare against.
420
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
531
421
  * @returns `true` if `this ≥ other`, `false` otherwise.
532
422
  *
533
423
  * @public
@@ -826,6 +716,38 @@ var DecimalImpl = class _DecimalImpl {
826
716
  return formatFixed(scaled);
827
717
  }
828
718
  }
719
+ /**
720
+ * Convert this value to an {@link (Integer:type)} by rounding.
721
+ *
722
+ * @remarks
723
+ * The rounding direction is always required — no invisible defaults
724
+ * in financial code.
725
+ *
726
+ * @example
727
+ * ```ts
728
+ * Decimal.from('2.7').toInteger('floor'); // 2
729
+ * Decimal.from('2.5').toInteger('half-up'); // 3
730
+ * Decimal.from('2.5').toInteger('half-even'); // 2
731
+ * ```
732
+ *
733
+ * @param direction - How to round when the value is not a whole number.
734
+ * @returns A branded {@link (Integer:type)} value.
735
+ * @throws Error if the rounded value is too large to represent as
736
+ * a JavaScript `number`.
737
+ *
738
+ * @public
739
+ */
740
+ toInteger(direction) {
741
+ const fixed = this.toFixed(0, direction);
742
+ const num = Number(fixed);
743
+ if (!Number.isFinite(num) || !Number.isSafeInteger(num)) {
744
+ throw new Error(
745
+ `Decimal value ${fixed} cannot be exactly represented as a JavaScript integer`
746
+ );
747
+ }
748
+ const normalized = normalizeZero(num);
749
+ return normalized;
750
+ }
829
751
  /**
830
752
  * Reject implicit arithmetic-style coercion while preserving explicit
831
753
  * stringification.
@@ -866,23 +788,59 @@ var DecimalImpl = class _DecimalImpl {
866
788
  function toImpl(d) {
867
789
  return d;
868
790
  }
791
+ function coerceToImpl(value) {
792
+ if (isDecimal(value)) {
793
+ return toImpl(value);
794
+ }
795
+ return toImpl(Decimal.from(value));
796
+ }
869
797
  function toDecimal(impl) {
870
798
  return impl;
871
799
  }
872
800
  function isDecimal(value) {
873
- return typeof value === "object" && value !== null && DECIMAL_BRAND in value;
801
+ return typeof value === "object" && value !== null && DECIMAL_BRAND in value && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- symbol key access requires cast
802
+ value[DECIMAL_BRAND] === true;
803
+ }
804
+ function assertIsDecimal(value) {
805
+ if (!isDecimal(value)) {
806
+ throw new Error(`Expected a Decimal, got ${typeof value}`);
807
+ }
874
808
  }
875
809
  var Decimal = {
876
810
  /**
877
- * Create a `Decimal` from a string, number, or bigint.
811
+ * Type guard that narrows an unknown value to {@link (Decimal:type)}.
812
+ *
813
+ * @example
814
+ * ```ts
815
+ * if (Decimal.is(value)) {
816
+ * value.add(1); // value is Decimal
817
+ * }
818
+ * ```
819
+ * @public
820
+ */
821
+ is: isDecimal,
822
+ /**
823
+ * Assertion guard that throws if the value is not a {@link (Decimal:type)}.
824
+ *
825
+ * @example
826
+ * ```ts
827
+ * Decimal.assert(value);
828
+ * value.add(1); // value is Decimal
829
+ * ```
830
+ * @public
831
+ */
832
+ assert: assertIsDecimal,
833
+ /**
834
+ * Create a `Decimal` from a string, number, bigint, Integer, or Decimal.
878
835
  *
879
836
  * @remarks
837
+ * - **Decimal**: returned as-is (immutable passthrough).
880
838
  * - **string**: Parsed as a decimal literal. Accepts an optional sign,
881
839
  * integer digits, an optional fractional part, and an optional `e`/`E`
882
840
  * exponent. Leading/trailing whitespace is trimmed.
883
- * - **number**: Must be finite. Converted via `Number.prototype.toString()`
884
- * then parsed, so `Decimal.from(0.1)` produces `"0.1"` (not the
885
- * 53-bit binary approximation).
841
+ * - **number** (including Integer): Must be finite. Converted via
842
+ * `Number.prototype.toString()` then parsed, so `Decimal.from(0.1)`
843
+ * produces `"0.1"` (not the 53-bit binary approximation).
886
844
  * - **bigint**: Treated as an integer with exponent 0.
887
845
  *
888
846
  * @example
@@ -891,16 +849,21 @@ var Decimal = {
891
849
  * Decimal.from(42); // number
892
850
  * Decimal.from(100n); // bigint
893
851
  * Decimal.from('1.5e3'); // scientific notation → 1500
852
+ * Decimal.from(d); // Decimal passthrough
894
853
  * ```
895
854
  *
896
855
  * @param value - The value to convert.
897
- * @returns A new frozen `Decimal` instance.
856
+ * @returns A new frozen `Decimal` instance (or the same instance if
857
+ * already a Decimal).
898
858
  * @throws Error if `value` is a non-finite number, an empty
899
859
  * string, or a string that does not match the decimal literal grammar.
900
860
  *
901
861
  * @public
902
862
  */
903
863
  from(value) {
864
+ if (isDecimal(value)) {
865
+ return value;
866
+ }
904
867
  if (typeof value === "bigint") {
905
868
  return toDecimal(new DecimalImpl(value, 0));
906
869
  }
@@ -949,20 +912,277 @@ var Decimal = {
949
912
  zero: toDecimal(new DecimalImpl(0n, 0))
950
913
  };
951
914
 
915
+ // src/stdlib/scalars.ts
916
+ function roundToInteger(value, direction) {
917
+ switch (direction) {
918
+ case "ceil":
919
+ return Math.ceil(value);
920
+ case "floor":
921
+ return Math.floor(value);
922
+ case "round-down":
923
+ return Math.trunc(value);
924
+ case "round-up":
925
+ return value >= 0 ? Math.ceil(value) : Math.floor(value);
926
+ case "half-up":
927
+ return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5);
928
+ default: {
929
+ const _exhaustive = direction;
930
+ throw new Error(`Unknown rounding direction: ${String(_exhaustive)}`);
931
+ }
932
+ }
933
+ }
934
+ function normalizeZero2(value) {
935
+ return Object.is(value, -0) ? 0 : value;
936
+ }
937
+ function assertIsInteger(value) {
938
+ if (!(typeof value === "number" && Number.isInteger(value))) {
939
+ throw new Error(
940
+ `Expected an integer, got ${typeof value === "number" ? String(value) : typeof value}`
941
+ );
942
+ }
943
+ }
944
+ function assertIsPositiveInteger(value) {
945
+ if (!(typeof value === "number" && Number.isInteger(value) && value >= 0)) {
946
+ throw new Error(
947
+ `Expected a non-negative integer, got ${typeof value === "number" ? String(value) : typeof value}`
948
+ );
949
+ }
950
+ }
951
+ function assertIntegerIsPositive(value) {
952
+ if (value < 0) {
953
+ throw new Error(`Expected a non-negative integer, got ${String(value)}`);
954
+ }
955
+ }
956
+ var Integer = {
957
+ /**
958
+ * The `Integer` value representing zero.
959
+ *
960
+ * @remarks
961
+ * Pre-allocated singleton — prefer `Integer.zero` over
962
+ * `Integer.from(0, 'floor')` to avoid an unnecessary call.
963
+ *
964
+ * @public
965
+ */
966
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-type-assertion -- branded type construction: 0 is trivially an integer
967
+ zero: 0,
968
+ /**
969
+ * Type guard that narrows an unknown value to {@link (Integer:type)}.
970
+ *
971
+ * @example
972
+ * ```ts
973
+ * const n: unknown = getCount();
974
+ * if (Integer.is(n)) {
975
+ * // n is Integer here
976
+ * config.retryCount = n;
977
+ * }
978
+ * ```
979
+ * @public
980
+ */
981
+ is: (value) => typeof value === "number" && Number.isInteger(value),
982
+ /**
983
+ * Assertion guard that throws if the value is not an {@link (Integer:type)}.
984
+ *
985
+ * @example
986
+ * ```ts
987
+ * const n: unknown = getCount();
988
+ * Integer.assert(n);
989
+ * // n is Integer here
990
+ * ```
991
+ * @public
992
+ */
993
+ assert: assertIsInteger,
994
+ /**
995
+ * Coerces a value to an {@link (Integer:type)} by rounding.
996
+ *
997
+ * @remarks
998
+ * Accepts `number`, `string`, `Decimal`, or `Integer`. The rounding
999
+ * direction is always required — no invisible defaults.
1000
+ *
1001
+ * - **number** (including Integer): must be finite and round to a
1002
+ * safe integer (`Number.isSafeInteger`). IEEE 754 negative zero is
1003
+ * normalized to positive zero.
1004
+ * - **string**: must be a valid numeric literal (not empty/whitespace).
1005
+ * Parsed via `Number()`, then rounded. The result must be a safe integer.
1006
+ * - **Decimal**: delegated to {@link Decimal.toInteger | Decimal.toInteger()}.
1007
+ *
1008
+ * @example
1009
+ * ```ts
1010
+ * Integer.from(9.99, 'floor'); // 9
1011
+ * Integer.from('1.5', 'ceil'); // 2
1012
+ * Integer.from(Decimal.from('2.7'), 'half-up'); // 3
1013
+ * ```
1014
+ *
1015
+ * @throws Error if the value is non-finite, an empty string, an
1016
+ * unparseable string, or rounds to a value outside the safe integer range.
1017
+ *
1018
+ * @public
1019
+ */
1020
+ from(value, rounding) {
1021
+ if (typeof value === "number") {
1022
+ if (!Number.isFinite(value)) {
1023
+ throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
1024
+ }
1025
+ const rounded = normalizeZero2(roundToInteger(value, rounding));
1026
+ if (!Number.isSafeInteger(rounded)) {
1027
+ throw new Error(
1028
+ `Value ${String(value)} rounds to ${String(rounded)}, which is outside the safe integer range`
1029
+ );
1030
+ }
1031
+ return rounded;
1032
+ }
1033
+ if (typeof value === "string") {
1034
+ if (value.trim() === "") {
1035
+ throw new Error("Cannot parse empty string as an integer");
1036
+ }
1037
+ const num = Number(value);
1038
+ if (!Number.isFinite(num)) {
1039
+ throw new Error(
1040
+ `Cannot parse "${value}" as a finite number for integer conversion`
1041
+ );
1042
+ }
1043
+ const rounded = normalizeZero2(roundToInteger(num, rounding));
1044
+ if (!Number.isSafeInteger(rounded)) {
1045
+ throw new Error(
1046
+ `Value "${value}" rounds to ${String(rounded)}, which is outside the safe integer range`
1047
+ );
1048
+ }
1049
+ return rounded;
1050
+ }
1051
+ if (isDecimal(value)) {
1052
+ return value.toInteger(rounding);
1053
+ }
1054
+ throw new Error(
1055
+ `Cannot convert ${typeof value} to Integer; expected string, number, or Decimal`
1056
+ );
1057
+ },
1058
+ /**
1059
+ * Convert an {@link (Integer:type)} to a {@link (Decimal:type)}.
1060
+ *
1061
+ * @remarks
1062
+ * This conversion is lossless — every JavaScript integer is exactly
1063
+ * representable as a Decimal.
1064
+ *
1065
+ * @example
1066
+ * ```ts
1067
+ * const dec = Integer.toDecimal(Integer.from(42, 'floor'));
1068
+ * dec.add(Decimal.from('0.5')); // 42.5
1069
+ * ```
1070
+ * @public
1071
+ */
1072
+ toDecimal(value) {
1073
+ return Decimal.from(value);
1074
+ },
1075
+ /**
1076
+ * Type guard that narrows an {@link (Integer:type)} to {@link (PositiveInteger:type)}.
1077
+ *
1078
+ * @example
1079
+ * ```ts
1080
+ * const n = Integer.from(count, 'floor');
1081
+ * if (Integer.isPositive(n)) {
1082
+ * // n is PositiveInteger here
1083
+ * }
1084
+ * ```
1085
+ * @public
1086
+ */
1087
+ isPositive: (value) => value >= 0,
1088
+ /**
1089
+ * Assertion guard that throws if an {@link (Integer:type)} is not a {@link (PositiveInteger:type)}.
1090
+ *
1091
+ * @example
1092
+ * ```ts
1093
+ * const n = Integer.from(count, 'floor');
1094
+ * Integer.assertIsPositive(n);
1095
+ * // n is PositiveInteger here
1096
+ * ```
1097
+ * @public
1098
+ */
1099
+ assertIsPositive: assertIntegerIsPositive
1100
+ };
1101
+ var PositiveInteger = {
1102
+ /**
1103
+ * Type guard that narrows an unknown value to {@link (PositiveInteger:type)}.
1104
+ *
1105
+ * @example
1106
+ * ```ts
1107
+ * const n: unknown = getRetryCount();
1108
+ * if (PositiveInteger.is(n)) {
1109
+ * // n is PositiveInteger here
1110
+ * config.maxRetries = n;
1111
+ * }
1112
+ * ```
1113
+ * @public
1114
+ */
1115
+ is: (value) => typeof value === "number" && Number.isInteger(value) && value >= 0,
1116
+ /**
1117
+ * Assertion guard that throws if the value is not a {@link (PositiveInteger:type)}.
1118
+ *
1119
+ * @example
1120
+ * ```ts
1121
+ * const n: unknown = getRetryCount();
1122
+ * PositiveInteger.assert(n);
1123
+ * // n is PositiveInteger here
1124
+ * ```
1125
+ * @public
1126
+ */
1127
+ assert: assertIsPositiveInteger,
1128
+ /**
1129
+ * Coerces a value to a {@link (PositiveInteger:type)} by rounding.
1130
+ *
1131
+ * @remarks
1132
+ * Delegates to {@link (Integer:variable).from | Integer.from()} for
1133
+ * rounding, then checks the result is non-negative. All error
1134
+ * conditions from `Integer.from()` apply (non-finite, empty string,
1135
+ * unsafe integer range), plus an additional check that the rounded
1136
+ * result is ≥ 0. IEEE 754 negative zero is normalized to positive zero.
1137
+ *
1138
+ * @example
1139
+ * ```ts
1140
+ * PositiveInteger.from(2.7, 'floor'); // 2
1141
+ * PositiveInteger.from('1.5', 'ceil'); // 2
1142
+ * PositiveInteger.from(Decimal.from('3.2'), 'half-up'); // 3
1143
+ * ```
1144
+ *
1145
+ * @throws Error if the value is non-finite, unparseable, outside the
1146
+ * safe integer range, or rounds to a negative number.
1147
+ *
1148
+ * @public
1149
+ */
1150
+ from(value, rounding) {
1151
+ const rounded = Integer.from(value, rounding);
1152
+ const normalized = normalizeZero2(rounded);
1153
+ if (normalized < 0) {
1154
+ throw new Error(
1155
+ `Value ${String(value)} rounds to ${String(normalized)}, which is negative`
1156
+ );
1157
+ }
1158
+ return normalized;
1159
+ }
1160
+ };
1161
+
1162
+ // src/stdlib/refs.ts
1163
+ var Ref = {
1164
+ create: (step) => {
1165
+ return {
1166
+ type: step.object,
1167
+ id: step.id
1168
+ };
1169
+ }
1170
+ };
1171
+
952
1172
  // src/stdlib/types.ts
953
- var WireReadError = class extends Error {
1173
+ var _WireReadError = class extends Error {
954
1174
  /**
955
1175
  * Error class name for `instanceof`-free identification.
956
1176
  * @internal
957
1177
  */
958
- name = "WireReadError";
1178
+ name = "_WireReadError";
959
1179
  };
960
- var WireWriteError = class extends Error {
1180
+ var _WireWriteError = class extends Error {
961
1181
  /**
962
1182
  * Error class name for `instanceof`-free identification.
963
1183
  * @internal
964
1184
  */
965
- name = "WireWriteError";
1185
+ name = "_WireWriteError";
966
1186
  };
967
1187
  var WireParseError = class extends Error {
968
1188
  name = "WireParseError";
@@ -1169,7 +1389,7 @@ function enumLookup(spec, value, direction) {
1169
1389
  var _ProtoWireToType = {
1170
1390
  _brand: "ProtoWireToType",
1171
1391
  createNotObjectError(loc, received) {
1172
- return new WireReadError(`${loc}: Expected an object but received ${received}`);
1392
+ return new _WireReadError(`${loc}: Expected an object but received ${received}`);
1173
1393
  },
1174
1394
  applyField(typeName, desc, input, strategy) {
1175
1395
  const from = desc.wire ?? desc.type;
@@ -1179,7 +1399,7 @@ var _ProtoWireToType = {
1179
1399
  return [to, (desc.transform ?? _identity)(strategy, raw)];
1180
1400
  } catch (e) {
1181
1401
  if (e instanceof WireParseError)
1182
- throw new WireReadError(`${typeName}.${desc.type}: ${e.message}`);
1402
+ throw new _WireReadError(`${typeName}.${desc.type}: ${e.message}`);
1183
1403
  throw e;
1184
1404
  }
1185
1405
  },
@@ -1234,7 +1454,7 @@ var _ProtoWireToType = {
1234
1454
  }
1235
1455
  }
1236
1456
  const loc = descriptor.typeName || "union";
1237
- throw new WireReadError(`${loc}: No variant set`);
1457
+ throw new _WireReadError(`${loc}: No variant set`);
1238
1458
  },
1239
1459
  applyOneofField(typeName, oneof, input, strategy, result, excludeWireKeys) {
1240
1460
  applyOneofFieldIncoming(typeName, oneof, input, strategy, result, excludeWireKeys);
@@ -1243,7 +1463,7 @@ var _ProtoWireToType = {
1243
1463
  var _TypeToProtoWire = {
1244
1464
  _brand: "TypeToProtoWire",
1245
1465
  createNotObjectError(loc, received) {
1246
- return new WireWriteError(`${loc}: Expected an object but received ${received}`);
1466
+ return new _WireWriteError(`${loc}: Expected an object but received ${received}`);
1247
1467
  },
1248
1468
  applyField(typeName, desc, input, strategy) {
1249
1469
  const from = desc.type;
@@ -1253,7 +1473,7 @@ var _TypeToProtoWire = {
1253
1473
  return [to, (desc.transform ?? _identity)(strategy, raw)];
1254
1474
  } catch (e) {
1255
1475
  if (e instanceof WireParseError)
1256
- throw new WireWriteError(`${typeName}.${desc.type}: ${e.message}`);
1476
+ throw new _WireWriteError(`${typeName}.${desc.type}: ${e.message}`);
1257
1477
  throw e;
1258
1478
  }
1259
1479
  },
@@ -1293,20 +1513,20 @@ var _TypeToProtoWire = {
1293
1513
  const discriminant = sdk[descriptor.discriminantFieldName];
1294
1514
  if (typeof discriminant !== "string") {
1295
1515
  const loc = descriptor.typeName || "union";
1296
- throw new WireWriteError(
1516
+ throw new _WireWriteError(
1297
1517
  `${loc}: Expected a string '${descriptor.discriminantFieldName}' discriminant but received ${discriminant === void 0 ? "undefined" : typeof discriminant}`
1298
1518
  );
1299
1519
  }
1300
1520
  if (discriminant === "other") {
1301
1521
  const loc = descriptor.typeName || "union";
1302
- throw new WireWriteError(
1522
+ throw new _WireWriteError(
1303
1523
  `${loc}: Cannot serialize 'other' variant back to wire format`
1304
1524
  );
1305
1525
  }
1306
1526
  const branch = descriptor.branches.find((b) => b.typeKey === discriminant);
1307
1527
  if (!branch) {
1308
1528
  const loc = descriptor.typeName || "union";
1309
- throw new WireWriteError(`${loc}: Unknown variant '${discriminant}'`);
1529
+ throw new _WireWriteError(`${loc}: Unknown variant '${discriminant}'`);
1310
1530
  }
1311
1531
  const branchData = _apply(
1312
1532
  new _ShapeDescriptor(descriptor.typeName, branch.shape),
@@ -1335,7 +1555,7 @@ function _configAppContextFromContext(ctx) {
1335
1555
  var _JsonWireToType = {
1336
1556
  _brand: "JsonWireToType",
1337
1557
  createNotObjectError(loc, received) {
1338
- return new WireReadError(`${loc}: Expected an object but received ${received}`);
1558
+ return new _WireReadError(`${loc}: Expected an object but received ${received}`);
1339
1559
  },
1340
1560
  applyField(typeName, desc, input, strategy) {
1341
1561
  const key = desc.type;
@@ -1344,7 +1564,7 @@ var _JsonWireToType = {
1344
1564
  return [key, (desc.transform ?? _identity)(strategy, raw)];
1345
1565
  } catch (e) {
1346
1566
  if (e instanceof WireParseError)
1347
- throw new WireReadError(`${typeName}.${desc.type}: ${e.message}`);
1567
+ throw new _WireReadError(`${typeName}.${desc.type}: ${e.message}`);
1348
1568
  throw e;
1349
1569
  }
1350
1570
  },
@@ -1399,7 +1619,7 @@ function applyOneofFieldIncoming(typeName, oneof, input, strategy, result, exclu
1399
1619
  }
1400
1620
  } catch (e) {
1401
1621
  if (e instanceof WireParseError) {
1402
- throw new WireReadError(
1622
+ throw new _WireReadError(
1403
1623
  `${typeName}.${oneof.discriminant}(${branch.typeKey}): ${e.message}`
1404
1624
  );
1405
1625
  }
@@ -1417,30 +1637,30 @@ function applyOneofFieldIncoming(typeName, oneof, input, strategy, result, exclu
1417
1637
  }
1418
1638
  }
1419
1639
  if (!oneof.optional) {
1420
- throw new WireReadError(`${typeName}.${oneof.discriminant}: no variant set`);
1640
+ throw new _WireReadError(`${typeName}.${oneof.discriminant}: no variant set`);
1421
1641
  }
1422
1642
  }
1423
1643
  function applyOneofFieldOutgoing(typeName, oneof, input, strategy, result) {
1424
1644
  const discriminant = Object.hasOwn(input, oneof.discriminant) ? input[oneof.discriminant] : void 0;
1425
1645
  if (discriminant === void 0 || discriminant === null) {
1426
1646
  if (!oneof.optional) {
1427
- throw new WireWriteError(`${typeName}.${oneof.discriminant}: no variant set`);
1647
+ throw new _WireWriteError(`${typeName}.${oneof.discriminant}: no variant set`);
1428
1648
  }
1429
1649
  return;
1430
1650
  }
1431
1651
  if (typeof discriminant !== "string") {
1432
- throw new WireWriteError(
1652
+ throw new _WireWriteError(
1433
1653
  `${typeName}.${oneof.discriminant}: expected string discriminant but received ${typeof discriminant}`
1434
1654
  );
1435
1655
  }
1436
1656
  if (discriminant === "other") {
1437
- throw new WireWriteError(
1657
+ throw new _WireWriteError(
1438
1658
  `${typeName}.${oneof.discriminant}: cannot serialize 'other' variant back to wire format`
1439
1659
  );
1440
1660
  }
1441
1661
  const branch = oneof.branches.find((b) => b.typeKey === discriminant);
1442
1662
  if (!branch) {
1443
- throw new WireWriteError(
1663
+ throw new _WireWriteError(
1444
1664
  `${typeName}.${oneof.discriminant}: unknown variant '${discriminant}'`
1445
1665
  );
1446
1666
  }
@@ -1450,7 +1670,7 @@ function applyOneofFieldOutgoing(typeName, oneof, input, strategy, result) {
1450
1670
  result[branch.wireKey] = transformed ?? {};
1451
1671
  } catch (e) {
1452
1672
  if (e instanceof WireParseError) {
1453
- throw new WireWriteError(
1673
+ throw new _WireWriteError(
1454
1674
  `${typeName}.${oneof.discriminant}(${branch.typeKey}): ${e.message}`
1455
1675
  );
1456
1676
  }
@@ -1481,6 +1701,23 @@ function _applyConfig(descriptor, inputObject, appCtx) {
1481
1701
  const strategy = appCtx?.clockTime !== void 0 ? createJsonWireToType(appCtx) : _JsonWireToType;
1482
1702
  return _apply(descriptor, strategy, inputObject);
1483
1703
  }
1704
+
1705
+ // src/stdlib/to-const.ts
1706
+ function toConst(value) {
1707
+ if (value === null || typeof value !== "object") {
1708
+ return value;
1709
+ }
1710
+ if (Array.isArray(value)) {
1711
+ for (const item of value) {
1712
+ toConst(item);
1713
+ }
1714
+ return Object.freeze(value);
1715
+ }
1716
+ for (const key of Object.keys(value)) {
1717
+ toConst(value[key]);
1718
+ }
1719
+ return Object.freeze(value);
1720
+ }
1484
1721
  // Annotate the CommonJS export names for ESM import in node:
1485
1722
  0 && (module.exports = {
1486
1723
  DEFAULT_DIV_PRECISION,
@@ -1489,10 +1726,6 @@ function _applyConfig(descriptor, inputObject, appCtx) {
1489
1726
  Integer,
1490
1727
  PositiveInteger,
1491
1728
  Ref,
1492
- StreetAddress,
1493
- Timestamp,
1494
- WireReadError,
1495
- WireWriteError,
1496
1729
  _ConfigEnum,
1497
1730
  _JsonWireToType,
1498
1731
  _ProtoEnum,
@@ -1500,6 +1733,8 @@ function _applyConfig(descriptor, inputObject, appCtx) {
1500
1733
  _ShapeDescriptor,
1501
1734
  _TypeToProtoWire,
1502
1735
  _UnionDescriptor,
1736
+ _WireReadError,
1737
+ _WireWriteError,
1503
1738
  _apply,
1504
1739
  _applyConfig,
1505
1740
  _applyIncoming,
@@ -1515,5 +1750,5 @@ function _applyConfig(descriptor, inputObject, appCtx) {
1515
1750
  _translateMap,
1516
1751
  _translateShape,
1517
1752
  _translateUnion,
1518
- isDecimal
1753
+ toConst
1519
1754
  });