@stripe/extensibility-sdk 0.24.1 → 0.25.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 (49) hide show
  1. package/README.md +355 -0
  2. package/dist/config-values/generate.d.ts +2 -0
  3. package/dist/config-values/generate.d.ts.map +1 -1
  4. package/dist/extensibility-sdk-alpha.d.ts +140 -38
  5. package/dist/extensibility-sdk-beta.d.ts +140 -38
  6. package/dist/extensibility-sdk-extensions-alpha.d.ts +155 -25
  7. package/dist/extensibility-sdk-extensions-beta.d.ts +155 -25
  8. package/dist/extensibility-sdk-extensions-internal.d.ts +159 -25
  9. package/dist/extensibility-sdk-extensions-public.d.ts +155 -25
  10. package/dist/extensibility-sdk-internal-alpha.d.ts +5 -0
  11. package/dist/extensibility-sdk-internal-beta.d.ts +5 -0
  12. package/dist/extensibility-sdk-internal-internal.d.ts +5 -0
  13. package/dist/extensibility-sdk-internal-public.d.ts +5 -0
  14. package/dist/extensibility-sdk-internal.d.ts +139 -40
  15. package/dist/extensibility-sdk-public.d.ts +140 -38
  16. package/dist/extensibility-sdk-stdlib-alpha.d.ts +145 -38
  17. package/dist/extensibility-sdk-stdlib-beta.d.ts +145 -38
  18. package/dist/extensibility-sdk-stdlib-internal.d.ts +144 -40
  19. package/dist/extensibility-sdk-stdlib-public.d.ts +145 -38
  20. package/dist/extensions/billing/bill/discount_calculation.d.ts +5 -3
  21. package/dist/extensions/billing/customer_balance_application.d.ts +3 -1
  22. package/dist/extensions/billing/invoice_collection_setting.d.ts +15 -11
  23. package/dist/extensions/billing/prorations.d.ts +30 -21
  24. package/dist/extensions/billing/recurring_billing_item_handling.d.ts +41 -23
  25. package/dist/extensions/billing/types.d.ts +4 -4
  26. package/dist/extensions/core/workflows/custom_action.d.ts +6 -2
  27. package/dist/extensions/extend/workflows/custom_action.d.ts +6 -2
  28. package/dist/index.cjs +385 -134
  29. package/dist/index.js +383 -133
  30. package/dist/internal.d.ts +4 -0
  31. package/dist/internal.d.ts.map +1 -1
  32. package/dist/stdlib/brand.d.ts +16 -10
  33. package/dist/stdlib/brand.d.ts.map +1 -1
  34. package/dist/stdlib/decimal.d.ts +49 -21
  35. package/dist/stdlib/decimal.d.ts.map +1 -1
  36. package/dist/stdlib/index.cjs +385 -134
  37. package/dist/stdlib/index.d.ts +10 -4
  38. package/dist/stdlib/index.d.ts.map +1 -1
  39. package/dist/stdlib/index.js +383 -133
  40. package/dist/stdlib/refs.d.ts +21 -7
  41. package/dist/stdlib/scalars.d.ts +61 -28
  42. package/dist/stdlib/scalars.d.ts.map +1 -1
  43. package/dist/stdlib/to-const.d.ts +35 -0
  44. package/dist/stdlib/to-const.d.ts.map +1 -0
  45. package/dist/stdlib/type-utils.d.ts +3 -1
  46. package/dist/stdlib/types.d.ts +6 -6
  47. package/dist/tsconfig.build.tsbuildinfo +1 -1
  48. package/package.json +11 -11
  49. package/dist/api-surface.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -55,123 +55,13 @@ __export(src_exports, {
55
55
  _translateMap: () => _translateMap,
56
56
  _translateShape: () => _translateShape,
57
57
  _translateUnion: () => _translateUnion,
58
- isDecimal: () => isDecimal
58
+ isDecimal: () => isDecimal,
59
+ toConst: () => toConst
59
60
  });
60
61
  module.exports = __toCommonJS(src_exports);
61
62
 
62
63
  // src/stdlib/scalars.ts
63
64
  var import_core = require("@formspec/core");
64
- function roundToInteger(value, direction) {
65
- switch (direction) {
66
- case "ceil":
67
- return Math.ceil(value);
68
- case "floor":
69
- return Math.floor(value);
70
- case "round-down":
71
- return Math.trunc(value);
72
- case "round-up":
73
- return value >= 0 ? Math.ceil(value) : Math.floor(value);
74
- case "half-up":
75
- return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5);
76
- default: {
77
- const _exhaustive = direction;
78
- throw new Error(`Unknown rounding direction: ${String(_exhaustive)}`);
79
- }
80
- }
81
- }
82
- var Integer = {
83
- /**
84
- * Type guard that narrows a `number` to {@link (Integer:type)}.
85
- *
86
- * @example
87
- * ```ts
88
- * const n: number = getCount();
89
- * if (Integer.is(n)) {
90
- * // n is Integer here
91
- * config.retryCount = n;
92
- * }
93
- * ```
94
- * @public
95
- */
96
- is: (value) => Number.isInteger(value),
97
- /**
98
- * Coerces a number to an {@link (Integer:type)} by rounding.
99
- * Throws if the value is not finite.
100
- *
101
- * @example
102
- * ```ts
103
- * const price = 9.99;
104
- * const rounded = Integer.from(price, 'floor'); // 9
105
- * const ceiled = Integer.from(price, 'ceil'); // 10
106
- * ```
107
- * @public
108
- */
109
- from: (value, rounding) => {
110
- if (!Number.isFinite(value)) {
111
- throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
112
- }
113
- return roundToInteger(value, rounding);
114
- }
115
- };
116
- var PositiveInteger = {
117
- /**
118
- * Type guard that narrows a `number` to {@link (PositiveInteger:type)}.
119
- *
120
- * @example
121
- * ```ts
122
- * const n: number = getRetryCount();
123
- * if (PositiveInteger.is(n)) {
124
- * // n is PositiveInteger here
125
- * config.maxRetries = n;
126
- * }
127
- * ```
128
- * @public
129
- */
130
- is: (value) => Number.isInteger(value) && value >= 0,
131
- /**
132
- * Coerces a number to a {@link (PositiveInteger:type)} by rounding.
133
- * Throws if the value is not finite or the rounded result is negative.
134
- *
135
- * @example
136
- * ```ts
137
- * const ratio = 2.7;
138
- * const count = PositiveInteger.from(ratio, 'floor'); // 2
139
- * ```
140
- * @public
141
- */
142
- from: (value, rounding) => {
143
- if (!Number.isFinite(value)) {
144
- throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
145
- }
146
- const rounded = roundToInteger(value, rounding) || 0;
147
- if (rounded < 0) {
148
- throw new Error(
149
- `Value ${String(value)} rounds to ${String(rounded)}, which is negative`
150
- );
151
- }
152
- return rounded;
153
- }
154
- };
155
- var StreetAddress = {
156
- create: (address) => {
157
- return address;
158
- }
159
- };
160
- var Timestamp = {
161
- create: (value) => {
162
- return value;
163
- }
164
- };
165
-
166
- // src/stdlib/refs.ts
167
- var Ref = {
168
- create: (step) => {
169
- return {
170
- type: step.object,
171
- id: step.id
172
- };
173
- }
174
- };
175
65
 
176
66
  // src/stdlib/decimal.ts
177
67
  var PLAIN_NOTATION_DIGIT_LIMIT = 30;
@@ -188,6 +78,9 @@ var DecimalRoundingPresets = Object.freeze({
188
78
  var DEFAULT_DIV_PRECISION = 34;
189
79
  var IMPLICIT_DECIMAL_COERCION_ERROR = "Implicit Decimal coercion is not allowed; use .add(), .sub(), .mul(), .div(), .toString(), or .toNumber() explicitly.";
190
80
  var MAX_EXPONENT = Number.MAX_SAFE_INTEGER;
81
+ function normalizeZero(value) {
82
+ return Object.is(value, -0) ? 0 : value;
83
+ }
191
84
  var DECIMAL_BRAND = /* @__PURE__ */ Symbol.for(
192
85
  "stripe.apps-extensibility-sdk.Decimal"
193
86
  );
@@ -301,13 +194,13 @@ var DecimalImpl = class _DecimalImpl {
301
194
  /**
302
195
  * Return the sum of this value and `other`.
303
196
  *
304
- * @param other - The addend.
197
+ * @param other - The addend. Accepts any {@link DecimalLike} value.
305
198
  * @returns A new {@link Decimal} equal to `this + other`.
306
199
  *
307
200
  * @public
308
201
  */
309
202
  add(other) {
310
- const otherImpl = toImpl(other);
203
+ const otherImpl = coerceToImpl(other);
311
204
  if (this.#exponent === otherImpl.#exponent) {
312
205
  return toDecimal(
313
206
  new _DecimalImpl(this.#coefficient + otherImpl.#coefficient, this.#exponent)
@@ -334,13 +227,13 @@ var DecimalImpl = class _DecimalImpl {
334
227
  /**
335
228
  * Return the difference of this value and `other`.
336
229
  *
337
- * @param other - The subtrahend.
230
+ * @param other - The subtrahend. Accepts any {@link DecimalLike} value.
338
231
  * @returns A new {@link Decimal} equal to `this - other`.
339
232
  *
340
233
  * @public
341
234
  */
342
235
  sub(other) {
343
- const otherImpl = toImpl(other);
236
+ const otherImpl = coerceToImpl(other);
344
237
  if (this.#exponent === otherImpl.#exponent) {
345
238
  return toDecimal(
346
239
  new _DecimalImpl(this.#coefficient - otherImpl.#coefficient, this.#exponent)
@@ -367,13 +260,13 @@ var DecimalImpl = class _DecimalImpl {
367
260
  /**
368
261
  * Return the product of this value and `other`.
369
262
  *
370
- * @param other - The multiplicand.
263
+ * @param other - The multiplicand. Accepts any {@link DecimalLike} value.
371
264
  * @returns A new {@link Decimal} equal to `this × other`.
372
265
  *
373
266
  * @public
374
267
  */
375
268
  mul(other) {
376
- const otherImpl = toImpl(other);
269
+ const otherImpl = coerceToImpl(other);
377
270
  return toDecimal(
378
271
  new _DecimalImpl(
379
272
  this.#coefficient * otherImpl.#coefficient,
@@ -400,7 +293,7 @@ var DecimalImpl = class _DecimalImpl {
400
293
  * Decimal.from('5').div(Decimal.from('2'), 0, 'half-even'); // "2"
401
294
  * ```
402
295
  *
403
- * @param other - The divisor. Must not be zero.
296
+ * @param other - The divisor. Must not be zero. Accepts any {@link DecimalLike} value.
404
297
  * @param precision - Maximum number of decimal digits in the result.
405
298
  * @param direction - How to round when the exact quotient cannot
406
299
  * be represented at the requested precision.
@@ -415,7 +308,7 @@ var DecimalImpl = class _DecimalImpl {
415
308
  if (precision < 0 || !Number.isInteger(precision)) {
416
309
  throw new Error("precision must be a non-negative integer");
417
310
  }
418
- const otherImpl = toImpl(other);
311
+ const otherImpl = coerceToImpl(other);
419
312
  if (otherImpl.#coefficient === 0n) {
420
313
  throw new Error("Division by zero");
421
314
  }
@@ -457,13 +350,13 @@ var DecimalImpl = class _DecimalImpl {
457
350
  * a.cmp(a); // 0
458
351
  * ```
459
352
  *
460
- * @param other - The value to compare against.
353
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
461
354
  * @returns `-1` if `this < other`, `0` if equal, `1` if `this > other`.
462
355
  *
463
356
  * @public
464
357
  */
465
358
  cmp(other) {
466
- const otherImpl = toImpl(other);
359
+ const otherImpl = coerceToImpl(other);
467
360
  if (this.#exponent === otherImpl.#exponent) {
468
361
  if (this.#coefficient < otherImpl.#coefficient) return -1;
469
362
  if (this.#coefficient > otherImpl.#coefficient) return 1;
@@ -486,7 +379,7 @@ var DecimalImpl = class _DecimalImpl {
486
379
  /**
487
380
  * Return `true` if this value is numerically equal to `other`.
488
381
  *
489
- * @param other - The value to compare against.
382
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
490
383
  * @returns `true` if `this === other` in value, `false` otherwise.
491
384
  *
492
385
  * @public
@@ -497,7 +390,7 @@ var DecimalImpl = class _DecimalImpl {
497
390
  /**
498
391
  * Return `true` if this value is strictly less than `other`.
499
392
  *
500
- * @param other - The value to compare against.
393
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
501
394
  * @returns `true` if `this < other`, `false` otherwise.
502
395
  *
503
396
  * @public
@@ -508,7 +401,7 @@ var DecimalImpl = class _DecimalImpl {
508
401
  /**
509
402
  * Return `true` if this value is less than or equal to `other`.
510
403
  *
511
- * @param other - The value to compare against.
404
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
512
405
  * @returns `true` if `this ≤ other`, `false` otherwise.
513
406
  *
514
407
  * @public
@@ -519,7 +412,7 @@ var DecimalImpl = class _DecimalImpl {
519
412
  /**
520
413
  * Return `true` if this value is strictly greater than `other`.
521
414
  *
522
- * @param other - The value to compare against.
415
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
523
416
  * @returns `true` if `this > other`, `false` otherwise.
524
417
  *
525
418
  * @public
@@ -530,7 +423,7 @@ var DecimalImpl = class _DecimalImpl {
530
423
  /**
531
424
  * Return `true` if this value is greater than or equal to `other`.
532
425
  *
533
- * @param other - The value to compare against.
426
+ * @param other - The value to compare against. Accepts any {@link DecimalLike} value.
534
427
  * @returns `true` if `this ≥ other`, `false` otherwise.
535
428
  *
536
429
  * @public
@@ -829,6 +722,38 @@ var DecimalImpl = class _DecimalImpl {
829
722
  return formatFixed(scaled);
830
723
  }
831
724
  }
725
+ /**
726
+ * Convert this value to an {@link (Integer:type)} by rounding.
727
+ *
728
+ * @remarks
729
+ * The rounding direction is always required — no invisible defaults
730
+ * in financial code.
731
+ *
732
+ * @example
733
+ * ```ts
734
+ * Decimal.from('2.7').toInteger('floor'); // 2
735
+ * Decimal.from('2.5').toInteger('half-up'); // 3
736
+ * Decimal.from('2.5').toInteger('half-even'); // 2
737
+ * ```
738
+ *
739
+ * @param direction - How to round when the value is not a whole number.
740
+ * @returns A branded {@link (Integer:type)} value.
741
+ * @throws Error if the rounded value is too large to represent as
742
+ * a JavaScript `number`.
743
+ *
744
+ * @public
745
+ */
746
+ toInteger(direction) {
747
+ const fixed = this.toFixed(0, direction);
748
+ const num = Number(fixed);
749
+ if (!Number.isFinite(num) || !Number.isSafeInteger(num)) {
750
+ throw new Error(
751
+ `Decimal value ${fixed} cannot be exactly represented as a JavaScript integer`
752
+ );
753
+ }
754
+ const normalized = normalizeZero(num);
755
+ return normalized;
756
+ }
832
757
  /**
833
758
  * Reject implicit arithmetic-style coercion while preserving explicit
834
759
  * stringification.
@@ -869,23 +794,59 @@ var DecimalImpl = class _DecimalImpl {
869
794
  function toImpl(d) {
870
795
  return d;
871
796
  }
797
+ function coerceToImpl(value) {
798
+ if (isDecimal(value)) {
799
+ return toImpl(value);
800
+ }
801
+ return toImpl(Decimal.from(value));
802
+ }
872
803
  function toDecimal(impl) {
873
804
  return impl;
874
805
  }
875
806
  function isDecimal(value) {
876
- return typeof value === "object" && value !== null && DECIMAL_BRAND in value;
807
+ return typeof value === "object" && value !== null && DECIMAL_BRAND in value && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- symbol key access requires cast
808
+ value[DECIMAL_BRAND] === true;
809
+ }
810
+ function assertIsDecimal(value) {
811
+ if (!isDecimal(value)) {
812
+ throw new Error(`Expected a Decimal, got ${typeof value}`);
813
+ }
877
814
  }
878
815
  var Decimal = {
879
816
  /**
880
- * Create a `Decimal` from a string, number, or bigint.
817
+ * Type guard that narrows an unknown value to {@link (Decimal:type)}.
818
+ *
819
+ * @example
820
+ * ```ts
821
+ * if (Decimal.is(value)) {
822
+ * value.add(1); // value is Decimal
823
+ * }
824
+ * ```
825
+ * @public
826
+ */
827
+ is: isDecimal,
828
+ /**
829
+ * Assertion guard that throws if the value is not a {@link (Decimal:type)}.
830
+ *
831
+ * @example
832
+ * ```ts
833
+ * Decimal.assert(value);
834
+ * value.add(1); // value is Decimal
835
+ * ```
836
+ * @public
837
+ */
838
+ assert: assertIsDecimal,
839
+ /**
840
+ * Create a `Decimal` from a string, number, bigint, Integer, or Decimal.
881
841
  *
882
842
  * @remarks
843
+ * - **Decimal**: returned as-is (immutable passthrough).
883
844
  * - **string**: Parsed as a decimal literal. Accepts an optional sign,
884
845
  * integer digits, an optional fractional part, and an optional `e`/`E`
885
846
  * exponent. Leading/trailing whitespace is trimmed.
886
- * - **number**: Must be finite. Converted via `Number.prototype.toString()`
887
- * then parsed, so `Decimal.from(0.1)` produces `"0.1"` (not the
888
- * 53-bit binary approximation).
847
+ * - **number** (including Integer): Must be finite. Converted via
848
+ * `Number.prototype.toString()` then parsed, so `Decimal.from(0.1)`
849
+ * produces `"0.1"` (not the 53-bit binary approximation).
889
850
  * - **bigint**: Treated as an integer with exponent 0.
890
851
  *
891
852
  * @example
@@ -894,16 +855,21 @@ var Decimal = {
894
855
  * Decimal.from(42); // number
895
856
  * Decimal.from(100n); // bigint
896
857
  * Decimal.from('1.5e3'); // scientific notation → 1500
858
+ * Decimal.from(d); // Decimal passthrough
897
859
  * ```
898
860
  *
899
861
  * @param value - The value to convert.
900
- * @returns A new frozen `Decimal` instance.
862
+ * @returns A new frozen `Decimal` instance (or the same instance if
863
+ * already a Decimal).
901
864
  * @throws Error if `value` is a non-finite number, an empty
902
865
  * string, or a string that does not match the decimal literal grammar.
903
866
  *
904
867
  * @public
905
868
  */
906
869
  from(value) {
870
+ if (isDecimal(value)) {
871
+ return value;
872
+ }
907
873
  if (typeof value === "bigint") {
908
874
  return toDecimal(new DecimalImpl(value, 0));
909
875
  }
@@ -952,6 +918,273 @@ var Decimal = {
952
918
  zero: toDecimal(new DecimalImpl(0n, 0))
953
919
  };
954
920
 
921
+ // src/stdlib/scalars.ts
922
+ function roundToInteger(value, direction) {
923
+ switch (direction) {
924
+ case "ceil":
925
+ return Math.ceil(value);
926
+ case "floor":
927
+ return Math.floor(value);
928
+ case "round-down":
929
+ return Math.trunc(value);
930
+ case "round-up":
931
+ return value >= 0 ? Math.ceil(value) : Math.floor(value);
932
+ case "half-up":
933
+ return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5);
934
+ default: {
935
+ const _exhaustive = direction;
936
+ throw new Error(`Unknown rounding direction: ${String(_exhaustive)}`);
937
+ }
938
+ }
939
+ }
940
+ function normalizeZero2(value) {
941
+ return Object.is(value, -0) ? 0 : value;
942
+ }
943
+ function assertIsInteger(value) {
944
+ if (!(typeof value === "number" && Number.isInteger(value))) {
945
+ throw new Error(
946
+ `Expected an integer, got ${typeof value === "number" ? String(value) : typeof value}`
947
+ );
948
+ }
949
+ }
950
+ function assertIsPositiveInteger(value) {
951
+ if (!(typeof value === "number" && Number.isInteger(value) && value >= 0)) {
952
+ throw new Error(
953
+ `Expected a non-negative integer, got ${typeof value === "number" ? String(value) : typeof value}`
954
+ );
955
+ }
956
+ }
957
+ function assertIntegerIsPositive(value) {
958
+ if (value < 0) {
959
+ throw new Error(`Expected a non-negative integer, got ${String(value)}`);
960
+ }
961
+ }
962
+ var Integer = {
963
+ /**
964
+ * The `Integer` value representing zero.
965
+ *
966
+ * @remarks
967
+ * Pre-allocated singleton — prefer `Integer.zero` over
968
+ * `Integer.from(0, 'floor')` to avoid an unnecessary call.
969
+ *
970
+ * @public
971
+ */
972
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-type-assertion -- branded type construction: 0 is trivially an integer
973
+ zero: 0,
974
+ /**
975
+ * Type guard that narrows an unknown value to {@link (Integer:type)}.
976
+ *
977
+ * @example
978
+ * ```ts
979
+ * const n: unknown = getCount();
980
+ * if (Integer.is(n)) {
981
+ * // n is Integer here
982
+ * config.retryCount = n;
983
+ * }
984
+ * ```
985
+ * @public
986
+ */
987
+ is: (value) => typeof value === "number" && Number.isInteger(value),
988
+ /**
989
+ * Assertion guard that throws if the value is not an {@link (Integer:type)}.
990
+ *
991
+ * @example
992
+ * ```ts
993
+ * const n: unknown = getCount();
994
+ * Integer.assert(n);
995
+ * // n is Integer here
996
+ * ```
997
+ * @public
998
+ */
999
+ assert: assertIsInteger,
1000
+ /**
1001
+ * Coerces a value to an {@link (Integer:type)} by rounding.
1002
+ *
1003
+ * @remarks
1004
+ * Accepts `number`, `string`, `Decimal`, or `Integer`. The rounding
1005
+ * direction is always required — no invisible defaults.
1006
+ *
1007
+ * - **number** (including Integer): must be finite and round to a
1008
+ * safe integer (`Number.isSafeInteger`). IEEE 754 negative zero is
1009
+ * normalized to positive zero.
1010
+ * - **string**: must be a valid numeric literal (not empty/whitespace).
1011
+ * Parsed via `Number()`, then rounded. The result must be a safe integer.
1012
+ * - **Decimal**: delegated to {@link Decimal.toInteger | Decimal.toInteger()}.
1013
+ *
1014
+ * @example
1015
+ * ```ts
1016
+ * Integer.from(9.99, 'floor'); // 9
1017
+ * Integer.from('1.5', 'ceil'); // 2
1018
+ * Integer.from(Decimal.from('2.7'), 'half-up'); // 3
1019
+ * ```
1020
+ *
1021
+ * @throws Error if the value is non-finite, an empty string, an
1022
+ * unparseable string, or rounds to a value outside the safe integer range.
1023
+ *
1024
+ * @public
1025
+ */
1026
+ from(value, rounding) {
1027
+ if (typeof value === "number") {
1028
+ if (!Number.isFinite(value)) {
1029
+ throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
1030
+ }
1031
+ const rounded = normalizeZero2(roundToInteger(value, rounding));
1032
+ if (!Number.isSafeInteger(rounded)) {
1033
+ throw new Error(
1034
+ `Value ${String(value)} rounds to ${String(rounded)}, which is outside the safe integer range`
1035
+ );
1036
+ }
1037
+ return rounded;
1038
+ }
1039
+ if (typeof value === "string") {
1040
+ if (value.trim() === "") {
1041
+ throw new Error("Cannot parse empty string as an integer");
1042
+ }
1043
+ const num = Number(value);
1044
+ if (!Number.isFinite(num)) {
1045
+ throw new Error(
1046
+ `Cannot parse "${value}" as a finite number for integer conversion`
1047
+ );
1048
+ }
1049
+ const rounded = normalizeZero2(roundToInteger(num, rounding));
1050
+ if (!Number.isSafeInteger(rounded)) {
1051
+ throw new Error(
1052
+ `Value "${value}" rounds to ${String(rounded)}, which is outside the safe integer range`
1053
+ );
1054
+ }
1055
+ return rounded;
1056
+ }
1057
+ if (isDecimal(value)) {
1058
+ return value.toInteger(rounding);
1059
+ }
1060
+ throw new Error(
1061
+ `Cannot convert ${typeof value} to Integer; expected string, number, or Decimal`
1062
+ );
1063
+ },
1064
+ /**
1065
+ * Convert an {@link (Integer:type)} to a {@link (Decimal:type)}.
1066
+ *
1067
+ * @remarks
1068
+ * This conversion is lossless — every JavaScript integer is exactly
1069
+ * representable as a Decimal.
1070
+ *
1071
+ * @example
1072
+ * ```ts
1073
+ * const dec = Integer.toDecimal(Integer.from(42, 'floor'));
1074
+ * dec.add(Decimal.from('0.5')); // 42.5
1075
+ * ```
1076
+ * @public
1077
+ */
1078
+ toDecimal(value) {
1079
+ return Decimal.from(value);
1080
+ },
1081
+ /**
1082
+ * Type guard that narrows an {@link (Integer:type)} to {@link (PositiveInteger:type)}.
1083
+ *
1084
+ * @example
1085
+ * ```ts
1086
+ * const n = Integer.from(count, 'floor');
1087
+ * if (Integer.isPositive(n)) {
1088
+ * // n is PositiveInteger here
1089
+ * }
1090
+ * ```
1091
+ * @public
1092
+ */
1093
+ isPositive: (value) => value >= 0,
1094
+ /**
1095
+ * Assertion guard that throws if an {@link (Integer:type)} is not a {@link (PositiveInteger:type)}.
1096
+ *
1097
+ * @example
1098
+ * ```ts
1099
+ * const n = Integer.from(count, 'floor');
1100
+ * Integer.assertIsPositive(n);
1101
+ * // n is PositiveInteger here
1102
+ * ```
1103
+ * @public
1104
+ */
1105
+ assertIsPositive: assertIntegerIsPositive
1106
+ };
1107
+ var PositiveInteger = {
1108
+ /**
1109
+ * Type guard that narrows an unknown value to {@link (PositiveInteger:type)}.
1110
+ *
1111
+ * @example
1112
+ * ```ts
1113
+ * const n: unknown = getRetryCount();
1114
+ * if (PositiveInteger.is(n)) {
1115
+ * // n is PositiveInteger here
1116
+ * config.maxRetries = n;
1117
+ * }
1118
+ * ```
1119
+ * @public
1120
+ */
1121
+ is: (value) => typeof value === "number" && Number.isInteger(value) && value >= 0,
1122
+ /**
1123
+ * Assertion guard that throws if the value is not a {@link (PositiveInteger:type)}.
1124
+ *
1125
+ * @example
1126
+ * ```ts
1127
+ * const n: unknown = getRetryCount();
1128
+ * PositiveInteger.assert(n);
1129
+ * // n is PositiveInteger here
1130
+ * ```
1131
+ * @public
1132
+ */
1133
+ assert: assertIsPositiveInteger,
1134
+ /**
1135
+ * Coerces a value to a {@link (PositiveInteger:type)} by rounding.
1136
+ *
1137
+ * @remarks
1138
+ * Delegates to {@link (Integer:variable).from | Integer.from()} for
1139
+ * rounding, then checks the result is non-negative. All error
1140
+ * conditions from `Integer.from()` apply (non-finite, empty string,
1141
+ * unsafe integer range), plus an additional check that the rounded
1142
+ * result is ≥ 0. IEEE 754 negative zero is normalized to positive zero.
1143
+ *
1144
+ * @example
1145
+ * ```ts
1146
+ * PositiveInteger.from(2.7, 'floor'); // 2
1147
+ * PositiveInteger.from('1.5', 'ceil'); // 2
1148
+ * PositiveInteger.from(Decimal.from('3.2'), 'half-up'); // 3
1149
+ * ```
1150
+ *
1151
+ * @throws Error if the value is non-finite, unparseable, outside the
1152
+ * safe integer range, or rounds to a negative number.
1153
+ *
1154
+ * @public
1155
+ */
1156
+ from(value, rounding) {
1157
+ const rounded = Integer.from(value, rounding);
1158
+ const normalized = normalizeZero2(rounded);
1159
+ if (normalized < 0) {
1160
+ throw new Error(
1161
+ `Value ${String(value)} rounds to ${String(normalized)}, which is negative`
1162
+ );
1163
+ }
1164
+ return normalized;
1165
+ }
1166
+ };
1167
+ var StreetAddress = {
1168
+ create: (address) => {
1169
+ return address;
1170
+ }
1171
+ };
1172
+ var Timestamp = {
1173
+ create: (value) => {
1174
+ return value;
1175
+ }
1176
+ };
1177
+
1178
+ // src/stdlib/refs.ts
1179
+ var Ref = {
1180
+ create: (step) => {
1181
+ return {
1182
+ type: step.object,
1183
+ id: step.id
1184
+ };
1185
+ }
1186
+ };
1187
+
955
1188
  // src/stdlib/types.ts
956
1189
  var WireReadError = class extends Error {
957
1190
  /**
@@ -1485,6 +1718,23 @@ function _applyConfig(descriptor, inputObject, appCtx) {
1485
1718
  return _apply(descriptor, strategy, inputObject);
1486
1719
  }
1487
1720
 
1721
+ // src/stdlib/to-const.ts
1722
+ function toConst(value) {
1723
+ if (value === null || typeof value !== "object") {
1724
+ return value;
1725
+ }
1726
+ if (Array.isArray(value)) {
1727
+ for (const item of value) {
1728
+ toConst(item);
1729
+ }
1730
+ return Object.freeze(value);
1731
+ }
1732
+ for (const key of Object.keys(value)) {
1733
+ toConst(value[key]);
1734
+ }
1735
+ return Object.freeze(value);
1736
+ }
1737
+
1488
1738
  // src/extensions/billing/index.ts
1489
1739
  var billing_exports = {};
1490
1740
  __export(billing_exports, {
@@ -3832,5 +4082,6 @@ var CustomAction2;
3832
4082
  _translateMap,
3833
4083
  _translateShape,
3834
4084
  _translateUnion,
3835
- isDecimal
4085
+ isDecimal,
4086
+ toConst
3836
4087
  });