@stripe/extensibility-sdk 0.24.0 → 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.
- package/README.md +355 -0
- package/dist/config-values/generate.d.ts +2 -0
- package/dist/config-values/generate.d.ts.map +1 -1
- package/dist/extensibility-sdk-alpha.d.ts +140 -38
- package/dist/extensibility-sdk-beta.d.ts +140 -38
- package/dist/extensibility-sdk-extensions-alpha.d.ts +155 -25
- package/dist/extensibility-sdk-extensions-beta.d.ts +155 -25
- package/dist/extensibility-sdk-extensions-internal.d.ts +159 -25
- package/dist/extensibility-sdk-extensions-public.d.ts +155 -25
- package/dist/extensibility-sdk-internal-alpha.d.ts +5 -0
- package/dist/extensibility-sdk-internal-beta.d.ts +5 -0
- package/dist/extensibility-sdk-internal-internal.d.ts +5 -0
- package/dist/extensibility-sdk-internal-public.d.ts +5 -0
- package/dist/extensibility-sdk-internal.d.ts +139 -40
- package/dist/extensibility-sdk-public.d.ts +140 -38
- package/dist/extensibility-sdk-stdlib-alpha.d.ts +145 -38
- package/dist/extensibility-sdk-stdlib-beta.d.ts +145 -38
- package/dist/extensibility-sdk-stdlib-internal.d.ts +144 -40
- package/dist/extensibility-sdk-stdlib-public.d.ts +145 -38
- package/dist/extensions/billing/bill/discount_calculation.d.ts +5 -3
- package/dist/extensions/billing/customer_balance_application.d.ts +3 -1
- package/dist/extensions/billing/invoice_collection_setting.d.ts +15 -11
- package/dist/extensions/billing/prorations.d.ts +30 -21
- package/dist/extensions/billing/recurring_billing_item_handling.d.ts +41 -23
- package/dist/extensions/billing/types.d.ts +4 -4
- package/dist/extensions/core/workflows/custom_action.d.ts +6 -2
- package/dist/extensions/extend/workflows/custom_action.d.ts +6 -2
- package/dist/index.cjs +385 -134
- package/dist/index.js +383 -133
- package/dist/internal.d.ts +4 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/stdlib/brand.d.ts +16 -10
- package/dist/stdlib/brand.d.ts.map +1 -1
- package/dist/stdlib/decimal.d.ts +49 -21
- package/dist/stdlib/decimal.d.ts.map +1 -1
- package/dist/stdlib/index.cjs +385 -134
- package/dist/stdlib/index.d.ts +10 -4
- package/dist/stdlib/index.d.ts.map +1 -1
- package/dist/stdlib/index.js +383 -133
- package/dist/stdlib/refs.d.ts +21 -7
- package/dist/stdlib/scalars.d.ts +61 -28
- package/dist/stdlib/scalars.d.ts.map +1 -1
- package/dist/stdlib/to-const.d.ts +35 -0
- package/dist/stdlib/to-const.d.ts.map +1 -0
- package/dist/stdlib/type-utils.d.ts +3 -1
- package/dist/stdlib/types.d.ts +6 -6
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/dist/api-surface.d.ts.map +0 -1
package/dist/stdlib/index.js
CHANGED
|
@@ -1,116 +1,5 @@
|
|
|
1
1
|
// src/stdlib/scalars.ts
|
|
2
2
|
import "@formspec/core";
|
|
3
|
-
function roundToInteger(value, direction) {
|
|
4
|
-
switch (direction) {
|
|
5
|
-
case "ceil":
|
|
6
|
-
return Math.ceil(value);
|
|
7
|
-
case "floor":
|
|
8
|
-
return Math.floor(value);
|
|
9
|
-
case "round-down":
|
|
10
|
-
return Math.trunc(value);
|
|
11
|
-
case "round-up":
|
|
12
|
-
return value >= 0 ? Math.ceil(value) : Math.floor(value);
|
|
13
|
-
case "half-up":
|
|
14
|
-
return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5);
|
|
15
|
-
default: {
|
|
16
|
-
const _exhaustive = direction;
|
|
17
|
-
throw new Error(`Unknown rounding direction: ${String(_exhaustive)}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
var Integer = {
|
|
22
|
-
/**
|
|
23
|
-
* Type guard that narrows a `number` to {@link (Integer:type)}.
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* const n: number = getCount();
|
|
28
|
-
* if (Integer.is(n)) {
|
|
29
|
-
* // n is Integer here
|
|
30
|
-
* config.retryCount = n;
|
|
31
|
-
* }
|
|
32
|
-
* ```
|
|
33
|
-
* @public
|
|
34
|
-
*/
|
|
35
|
-
is: (value) => Number.isInteger(value),
|
|
36
|
-
/**
|
|
37
|
-
* Coerces a number to an {@link (Integer:type)} by rounding.
|
|
38
|
-
* Throws if the value is not finite.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```ts
|
|
42
|
-
* const price = 9.99;
|
|
43
|
-
* const rounded = Integer.from(price, 'floor'); // 9
|
|
44
|
-
* const ceiled = Integer.from(price, 'ceil'); // 10
|
|
45
|
-
* ```
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
from: (value, rounding) => {
|
|
49
|
-
if (!Number.isFinite(value)) {
|
|
50
|
-
throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
|
|
51
|
-
}
|
|
52
|
-
return roundToInteger(value, rounding);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
var PositiveInteger = {
|
|
56
|
-
/**
|
|
57
|
-
* Type guard that narrows a `number` to {@link (PositiveInteger:type)}.
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```ts
|
|
61
|
-
* const n: number = getRetryCount();
|
|
62
|
-
* if (PositiveInteger.is(n)) {
|
|
63
|
-
* // n is PositiveInteger here
|
|
64
|
-
* config.maxRetries = n;
|
|
65
|
-
* }
|
|
66
|
-
* ```
|
|
67
|
-
* @public
|
|
68
|
-
*/
|
|
69
|
-
is: (value) => Number.isInteger(value) && value >= 0,
|
|
70
|
-
/**
|
|
71
|
-
* Coerces a number to a {@link (PositiveInteger:type)} by rounding.
|
|
72
|
-
* Throws if the value is not finite or the rounded result is negative.
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```ts
|
|
76
|
-
* const ratio = 2.7;
|
|
77
|
-
* const count = PositiveInteger.from(ratio, 'floor'); // 2
|
|
78
|
-
* ```
|
|
79
|
-
* @public
|
|
80
|
-
*/
|
|
81
|
-
from: (value, rounding) => {
|
|
82
|
-
if (!Number.isFinite(value)) {
|
|
83
|
-
throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
|
|
84
|
-
}
|
|
85
|
-
const rounded = roundToInteger(value, rounding) || 0;
|
|
86
|
-
if (rounded < 0) {
|
|
87
|
-
throw new Error(
|
|
88
|
-
`Value ${String(value)} rounds to ${String(rounded)}, which is negative`
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
return rounded;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
var StreetAddress = {
|
|
95
|
-
create: (address) => {
|
|
96
|
-
return address;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
var Timestamp = {
|
|
100
|
-
create: (value) => {
|
|
101
|
-
return value;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// src/stdlib/refs.ts
|
|
106
|
-
var Ref = {
|
|
107
|
-
create: (step) => {
|
|
108
|
-
return {
|
|
109
|
-
type: step.object,
|
|
110
|
-
id: step.id
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
3
|
|
|
115
4
|
// src/stdlib/decimal.ts
|
|
116
5
|
var PLAIN_NOTATION_DIGIT_LIMIT = 30;
|
|
@@ -127,6 +16,9 @@ var DecimalRoundingPresets = Object.freeze({
|
|
|
127
16
|
var DEFAULT_DIV_PRECISION = 34;
|
|
128
17
|
var IMPLICIT_DECIMAL_COERCION_ERROR = "Implicit Decimal coercion is not allowed; use .add(), .sub(), .mul(), .div(), .toString(), or .toNumber() explicitly.";
|
|
129
18
|
var MAX_EXPONENT = Number.MAX_SAFE_INTEGER;
|
|
19
|
+
function normalizeZero(value) {
|
|
20
|
+
return Object.is(value, -0) ? 0 : value;
|
|
21
|
+
}
|
|
130
22
|
var DECIMAL_BRAND = /* @__PURE__ */ Symbol.for(
|
|
131
23
|
"stripe.apps-extensibility-sdk.Decimal"
|
|
132
24
|
);
|
|
@@ -240,13 +132,13 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
240
132
|
/**
|
|
241
133
|
* Return the sum of this value and `other`.
|
|
242
134
|
*
|
|
243
|
-
* @param other - The addend.
|
|
135
|
+
* @param other - The addend. Accepts any {@link DecimalLike} value.
|
|
244
136
|
* @returns A new {@link Decimal} equal to `this + other`.
|
|
245
137
|
*
|
|
246
138
|
* @public
|
|
247
139
|
*/
|
|
248
140
|
add(other) {
|
|
249
|
-
const otherImpl =
|
|
141
|
+
const otherImpl = coerceToImpl(other);
|
|
250
142
|
if (this.#exponent === otherImpl.#exponent) {
|
|
251
143
|
return toDecimal(
|
|
252
144
|
new _DecimalImpl(this.#coefficient + otherImpl.#coefficient, this.#exponent)
|
|
@@ -273,13 +165,13 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
273
165
|
/**
|
|
274
166
|
* Return the difference of this value and `other`.
|
|
275
167
|
*
|
|
276
|
-
* @param other - The subtrahend.
|
|
168
|
+
* @param other - The subtrahend. Accepts any {@link DecimalLike} value.
|
|
277
169
|
* @returns A new {@link Decimal} equal to `this - other`.
|
|
278
170
|
*
|
|
279
171
|
* @public
|
|
280
172
|
*/
|
|
281
173
|
sub(other) {
|
|
282
|
-
const otherImpl =
|
|
174
|
+
const otherImpl = coerceToImpl(other);
|
|
283
175
|
if (this.#exponent === otherImpl.#exponent) {
|
|
284
176
|
return toDecimal(
|
|
285
177
|
new _DecimalImpl(this.#coefficient - otherImpl.#coefficient, this.#exponent)
|
|
@@ -306,13 +198,13 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
306
198
|
/**
|
|
307
199
|
* Return the product of this value and `other`.
|
|
308
200
|
*
|
|
309
|
-
* @param other - The multiplicand.
|
|
201
|
+
* @param other - The multiplicand. Accepts any {@link DecimalLike} value.
|
|
310
202
|
* @returns A new {@link Decimal} equal to `this × other`.
|
|
311
203
|
*
|
|
312
204
|
* @public
|
|
313
205
|
*/
|
|
314
206
|
mul(other) {
|
|
315
|
-
const otherImpl =
|
|
207
|
+
const otherImpl = coerceToImpl(other);
|
|
316
208
|
return toDecimal(
|
|
317
209
|
new _DecimalImpl(
|
|
318
210
|
this.#coefficient * otherImpl.#coefficient,
|
|
@@ -339,7 +231,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
339
231
|
* Decimal.from('5').div(Decimal.from('2'), 0, 'half-even'); // "2"
|
|
340
232
|
* ```
|
|
341
233
|
*
|
|
342
|
-
* @param other - The divisor. Must not be zero.
|
|
234
|
+
* @param other - The divisor. Must not be zero. Accepts any {@link DecimalLike} value.
|
|
343
235
|
* @param precision - Maximum number of decimal digits in the result.
|
|
344
236
|
* @param direction - How to round when the exact quotient cannot
|
|
345
237
|
* be represented at the requested precision.
|
|
@@ -354,7 +246,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
354
246
|
if (precision < 0 || !Number.isInteger(precision)) {
|
|
355
247
|
throw new Error("precision must be a non-negative integer");
|
|
356
248
|
}
|
|
357
|
-
const otherImpl =
|
|
249
|
+
const otherImpl = coerceToImpl(other);
|
|
358
250
|
if (otherImpl.#coefficient === 0n) {
|
|
359
251
|
throw new Error("Division by zero");
|
|
360
252
|
}
|
|
@@ -396,13 +288,13 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
396
288
|
* a.cmp(a); // 0
|
|
397
289
|
* ```
|
|
398
290
|
*
|
|
399
|
-
* @param other - The value to compare against.
|
|
291
|
+
* @param other - The value to compare against. Accepts any {@link DecimalLike} value.
|
|
400
292
|
* @returns `-1` if `this < other`, `0` if equal, `1` if `this > other`.
|
|
401
293
|
*
|
|
402
294
|
* @public
|
|
403
295
|
*/
|
|
404
296
|
cmp(other) {
|
|
405
|
-
const otherImpl =
|
|
297
|
+
const otherImpl = coerceToImpl(other);
|
|
406
298
|
if (this.#exponent === otherImpl.#exponent) {
|
|
407
299
|
if (this.#coefficient < otherImpl.#coefficient) return -1;
|
|
408
300
|
if (this.#coefficient > otherImpl.#coefficient) return 1;
|
|
@@ -425,7 +317,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
425
317
|
/**
|
|
426
318
|
* Return `true` if this value is numerically equal to `other`.
|
|
427
319
|
*
|
|
428
|
-
* @param other - The value to compare against.
|
|
320
|
+
* @param other - The value to compare against. Accepts any {@link DecimalLike} value.
|
|
429
321
|
* @returns `true` if `this === other` in value, `false` otherwise.
|
|
430
322
|
*
|
|
431
323
|
* @public
|
|
@@ -436,7 +328,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
436
328
|
/**
|
|
437
329
|
* Return `true` if this value is strictly less than `other`.
|
|
438
330
|
*
|
|
439
|
-
* @param other - The value to compare against.
|
|
331
|
+
* @param other - The value to compare against. Accepts any {@link DecimalLike} value.
|
|
440
332
|
* @returns `true` if `this < other`, `false` otherwise.
|
|
441
333
|
*
|
|
442
334
|
* @public
|
|
@@ -447,7 +339,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
447
339
|
/**
|
|
448
340
|
* Return `true` if this value is less than or equal to `other`.
|
|
449
341
|
*
|
|
450
|
-
* @param other - The value to compare against.
|
|
342
|
+
* @param other - The value to compare against. Accepts any {@link DecimalLike} value.
|
|
451
343
|
* @returns `true` if `this ≤ other`, `false` otherwise.
|
|
452
344
|
*
|
|
453
345
|
* @public
|
|
@@ -458,7 +350,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
458
350
|
/**
|
|
459
351
|
* Return `true` if this value is strictly greater than `other`.
|
|
460
352
|
*
|
|
461
|
-
* @param other - The value to compare against.
|
|
353
|
+
* @param other - The value to compare against. Accepts any {@link DecimalLike} value.
|
|
462
354
|
* @returns `true` if `this > other`, `false` otherwise.
|
|
463
355
|
*
|
|
464
356
|
* @public
|
|
@@ -469,7 +361,7 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
469
361
|
/**
|
|
470
362
|
* Return `true` if this value is greater than or equal to `other`.
|
|
471
363
|
*
|
|
472
|
-
* @param other - The value to compare against.
|
|
364
|
+
* @param other - The value to compare against. Accepts any {@link DecimalLike} value.
|
|
473
365
|
* @returns `true` if `this ≥ other`, `false` otherwise.
|
|
474
366
|
*
|
|
475
367
|
* @public
|
|
@@ -768,6 +660,38 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
768
660
|
return formatFixed(scaled);
|
|
769
661
|
}
|
|
770
662
|
}
|
|
663
|
+
/**
|
|
664
|
+
* Convert this value to an {@link (Integer:type)} by rounding.
|
|
665
|
+
*
|
|
666
|
+
* @remarks
|
|
667
|
+
* The rounding direction is always required — no invisible defaults
|
|
668
|
+
* in financial code.
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```ts
|
|
672
|
+
* Decimal.from('2.7').toInteger('floor'); // 2
|
|
673
|
+
* Decimal.from('2.5').toInteger('half-up'); // 3
|
|
674
|
+
* Decimal.from('2.5').toInteger('half-even'); // 2
|
|
675
|
+
* ```
|
|
676
|
+
*
|
|
677
|
+
* @param direction - How to round when the value is not a whole number.
|
|
678
|
+
* @returns A branded {@link (Integer:type)} value.
|
|
679
|
+
* @throws Error if the rounded value is too large to represent as
|
|
680
|
+
* a JavaScript `number`.
|
|
681
|
+
*
|
|
682
|
+
* @public
|
|
683
|
+
*/
|
|
684
|
+
toInteger(direction) {
|
|
685
|
+
const fixed = this.toFixed(0, direction);
|
|
686
|
+
const num = Number(fixed);
|
|
687
|
+
if (!Number.isFinite(num) || !Number.isSafeInteger(num)) {
|
|
688
|
+
throw new Error(
|
|
689
|
+
`Decimal value ${fixed} cannot be exactly represented as a JavaScript integer`
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
const normalized = normalizeZero(num);
|
|
693
|
+
return normalized;
|
|
694
|
+
}
|
|
771
695
|
/**
|
|
772
696
|
* Reject implicit arithmetic-style coercion while preserving explicit
|
|
773
697
|
* stringification.
|
|
@@ -808,23 +732,59 @@ var DecimalImpl = class _DecimalImpl {
|
|
|
808
732
|
function toImpl(d) {
|
|
809
733
|
return d;
|
|
810
734
|
}
|
|
735
|
+
function coerceToImpl(value) {
|
|
736
|
+
if (isDecimal(value)) {
|
|
737
|
+
return toImpl(value);
|
|
738
|
+
}
|
|
739
|
+
return toImpl(Decimal.from(value));
|
|
740
|
+
}
|
|
811
741
|
function toDecimal(impl) {
|
|
812
742
|
return impl;
|
|
813
743
|
}
|
|
814
744
|
function isDecimal(value) {
|
|
815
|
-
return typeof value === "object" && value !== null && DECIMAL_BRAND in value
|
|
745
|
+
return typeof value === "object" && value !== null && DECIMAL_BRAND in value && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- symbol key access requires cast
|
|
746
|
+
value[DECIMAL_BRAND] === true;
|
|
747
|
+
}
|
|
748
|
+
function assertIsDecimal(value) {
|
|
749
|
+
if (!isDecimal(value)) {
|
|
750
|
+
throw new Error(`Expected a Decimal, got ${typeof value}`);
|
|
751
|
+
}
|
|
816
752
|
}
|
|
817
753
|
var Decimal = {
|
|
818
754
|
/**
|
|
819
|
-
*
|
|
755
|
+
* Type guard that narrows an unknown value to {@link (Decimal:type)}.
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```ts
|
|
759
|
+
* if (Decimal.is(value)) {
|
|
760
|
+
* value.add(1); // value is Decimal
|
|
761
|
+
* }
|
|
762
|
+
* ```
|
|
763
|
+
* @public
|
|
764
|
+
*/
|
|
765
|
+
is: isDecimal,
|
|
766
|
+
/**
|
|
767
|
+
* Assertion guard that throws if the value is not a {@link (Decimal:type)}.
|
|
768
|
+
*
|
|
769
|
+
* @example
|
|
770
|
+
* ```ts
|
|
771
|
+
* Decimal.assert(value);
|
|
772
|
+
* value.add(1); // value is Decimal
|
|
773
|
+
* ```
|
|
774
|
+
* @public
|
|
775
|
+
*/
|
|
776
|
+
assert: assertIsDecimal,
|
|
777
|
+
/**
|
|
778
|
+
* Create a `Decimal` from a string, number, bigint, Integer, or Decimal.
|
|
820
779
|
*
|
|
821
780
|
* @remarks
|
|
781
|
+
* - **Decimal**: returned as-is (immutable passthrough).
|
|
822
782
|
* - **string**: Parsed as a decimal literal. Accepts an optional sign,
|
|
823
783
|
* integer digits, an optional fractional part, and an optional `e`/`E`
|
|
824
784
|
* exponent. Leading/trailing whitespace is trimmed.
|
|
825
|
-
* - **number
|
|
826
|
-
* then parsed, so `Decimal.from(0.1)`
|
|
827
|
-
* 53-bit binary approximation).
|
|
785
|
+
* - **number** (including Integer): Must be finite. Converted via
|
|
786
|
+
* `Number.prototype.toString()` then parsed, so `Decimal.from(0.1)`
|
|
787
|
+
* produces `"0.1"` (not the 53-bit binary approximation).
|
|
828
788
|
* - **bigint**: Treated as an integer with exponent 0.
|
|
829
789
|
*
|
|
830
790
|
* @example
|
|
@@ -833,16 +793,21 @@ var Decimal = {
|
|
|
833
793
|
* Decimal.from(42); // number
|
|
834
794
|
* Decimal.from(100n); // bigint
|
|
835
795
|
* Decimal.from('1.5e3'); // scientific notation → 1500
|
|
796
|
+
* Decimal.from(d); // Decimal passthrough
|
|
836
797
|
* ```
|
|
837
798
|
*
|
|
838
799
|
* @param value - The value to convert.
|
|
839
|
-
* @returns A new frozen `Decimal` instance
|
|
800
|
+
* @returns A new frozen `Decimal` instance (or the same instance if
|
|
801
|
+
* already a Decimal).
|
|
840
802
|
* @throws Error if `value` is a non-finite number, an empty
|
|
841
803
|
* string, or a string that does not match the decimal literal grammar.
|
|
842
804
|
*
|
|
843
805
|
* @public
|
|
844
806
|
*/
|
|
845
807
|
from(value) {
|
|
808
|
+
if (isDecimal(value)) {
|
|
809
|
+
return value;
|
|
810
|
+
}
|
|
846
811
|
if (typeof value === "bigint") {
|
|
847
812
|
return toDecimal(new DecimalImpl(value, 0));
|
|
848
813
|
}
|
|
@@ -891,6 +856,273 @@ var Decimal = {
|
|
|
891
856
|
zero: toDecimal(new DecimalImpl(0n, 0))
|
|
892
857
|
};
|
|
893
858
|
|
|
859
|
+
// src/stdlib/scalars.ts
|
|
860
|
+
function roundToInteger(value, direction) {
|
|
861
|
+
switch (direction) {
|
|
862
|
+
case "ceil":
|
|
863
|
+
return Math.ceil(value);
|
|
864
|
+
case "floor":
|
|
865
|
+
return Math.floor(value);
|
|
866
|
+
case "round-down":
|
|
867
|
+
return Math.trunc(value);
|
|
868
|
+
case "round-up":
|
|
869
|
+
return value >= 0 ? Math.ceil(value) : Math.floor(value);
|
|
870
|
+
case "half-up":
|
|
871
|
+
return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5);
|
|
872
|
+
default: {
|
|
873
|
+
const _exhaustive = direction;
|
|
874
|
+
throw new Error(`Unknown rounding direction: ${String(_exhaustive)}`);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
function normalizeZero2(value) {
|
|
879
|
+
return Object.is(value, -0) ? 0 : value;
|
|
880
|
+
}
|
|
881
|
+
function assertIsInteger(value) {
|
|
882
|
+
if (!(typeof value === "number" && Number.isInteger(value))) {
|
|
883
|
+
throw new Error(
|
|
884
|
+
`Expected an integer, got ${typeof value === "number" ? String(value) : typeof value}`
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
function assertIsPositiveInteger(value) {
|
|
889
|
+
if (!(typeof value === "number" && Number.isInteger(value) && value >= 0)) {
|
|
890
|
+
throw new Error(
|
|
891
|
+
`Expected a non-negative integer, got ${typeof value === "number" ? String(value) : typeof value}`
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
function assertIntegerIsPositive(value) {
|
|
896
|
+
if (value < 0) {
|
|
897
|
+
throw new Error(`Expected a non-negative integer, got ${String(value)}`);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
var Integer = {
|
|
901
|
+
/**
|
|
902
|
+
* The `Integer` value representing zero.
|
|
903
|
+
*
|
|
904
|
+
* @remarks
|
|
905
|
+
* Pre-allocated singleton — prefer `Integer.zero` over
|
|
906
|
+
* `Integer.from(0, 'floor')` to avoid an unnecessary call.
|
|
907
|
+
*
|
|
908
|
+
* @public
|
|
909
|
+
*/
|
|
910
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-type-assertion -- branded type construction: 0 is trivially an integer
|
|
911
|
+
zero: 0,
|
|
912
|
+
/**
|
|
913
|
+
* Type guard that narrows an unknown value to {@link (Integer:type)}.
|
|
914
|
+
*
|
|
915
|
+
* @example
|
|
916
|
+
* ```ts
|
|
917
|
+
* const n: unknown = getCount();
|
|
918
|
+
* if (Integer.is(n)) {
|
|
919
|
+
* // n is Integer here
|
|
920
|
+
* config.retryCount = n;
|
|
921
|
+
* }
|
|
922
|
+
* ```
|
|
923
|
+
* @public
|
|
924
|
+
*/
|
|
925
|
+
is: (value) => typeof value === "number" && Number.isInteger(value),
|
|
926
|
+
/**
|
|
927
|
+
* Assertion guard that throws if the value is not an {@link (Integer:type)}.
|
|
928
|
+
*
|
|
929
|
+
* @example
|
|
930
|
+
* ```ts
|
|
931
|
+
* const n: unknown = getCount();
|
|
932
|
+
* Integer.assert(n);
|
|
933
|
+
* // n is Integer here
|
|
934
|
+
* ```
|
|
935
|
+
* @public
|
|
936
|
+
*/
|
|
937
|
+
assert: assertIsInteger,
|
|
938
|
+
/**
|
|
939
|
+
* Coerces a value to an {@link (Integer:type)} by rounding.
|
|
940
|
+
*
|
|
941
|
+
* @remarks
|
|
942
|
+
* Accepts `number`, `string`, `Decimal`, or `Integer`. The rounding
|
|
943
|
+
* direction is always required — no invisible defaults.
|
|
944
|
+
*
|
|
945
|
+
* - **number** (including Integer): must be finite and round to a
|
|
946
|
+
* safe integer (`Number.isSafeInteger`). IEEE 754 negative zero is
|
|
947
|
+
* normalized to positive zero.
|
|
948
|
+
* - **string**: must be a valid numeric literal (not empty/whitespace).
|
|
949
|
+
* Parsed via `Number()`, then rounded. The result must be a safe integer.
|
|
950
|
+
* - **Decimal**: delegated to {@link Decimal.toInteger | Decimal.toInteger()}.
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* ```ts
|
|
954
|
+
* Integer.from(9.99, 'floor'); // 9
|
|
955
|
+
* Integer.from('1.5', 'ceil'); // 2
|
|
956
|
+
* Integer.from(Decimal.from('2.7'), 'half-up'); // 3
|
|
957
|
+
* ```
|
|
958
|
+
*
|
|
959
|
+
* @throws Error if the value is non-finite, an empty string, an
|
|
960
|
+
* unparseable string, or rounds to a value outside the safe integer range.
|
|
961
|
+
*
|
|
962
|
+
* @public
|
|
963
|
+
*/
|
|
964
|
+
from(value, rounding) {
|
|
965
|
+
if (typeof value === "number") {
|
|
966
|
+
if (!Number.isFinite(value)) {
|
|
967
|
+
throw new Error(`Cannot round non-finite value ${String(value)} to an integer`);
|
|
968
|
+
}
|
|
969
|
+
const rounded = normalizeZero2(roundToInteger(value, rounding));
|
|
970
|
+
if (!Number.isSafeInteger(rounded)) {
|
|
971
|
+
throw new Error(
|
|
972
|
+
`Value ${String(value)} rounds to ${String(rounded)}, which is outside the safe integer range`
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
return rounded;
|
|
976
|
+
}
|
|
977
|
+
if (typeof value === "string") {
|
|
978
|
+
if (value.trim() === "") {
|
|
979
|
+
throw new Error("Cannot parse empty string as an integer");
|
|
980
|
+
}
|
|
981
|
+
const num = Number(value);
|
|
982
|
+
if (!Number.isFinite(num)) {
|
|
983
|
+
throw new Error(
|
|
984
|
+
`Cannot parse "${value}" as a finite number for integer conversion`
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
const rounded = normalizeZero2(roundToInteger(num, rounding));
|
|
988
|
+
if (!Number.isSafeInteger(rounded)) {
|
|
989
|
+
throw new Error(
|
|
990
|
+
`Value "${value}" rounds to ${String(rounded)}, which is outside the safe integer range`
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
return rounded;
|
|
994
|
+
}
|
|
995
|
+
if (isDecimal(value)) {
|
|
996
|
+
return value.toInteger(rounding);
|
|
997
|
+
}
|
|
998
|
+
throw new Error(
|
|
999
|
+
`Cannot convert ${typeof value} to Integer; expected string, number, or Decimal`
|
|
1000
|
+
);
|
|
1001
|
+
},
|
|
1002
|
+
/**
|
|
1003
|
+
* Convert an {@link (Integer:type)} to a {@link (Decimal:type)}.
|
|
1004
|
+
*
|
|
1005
|
+
* @remarks
|
|
1006
|
+
* This conversion is lossless — every JavaScript integer is exactly
|
|
1007
|
+
* representable as a Decimal.
|
|
1008
|
+
*
|
|
1009
|
+
* @example
|
|
1010
|
+
* ```ts
|
|
1011
|
+
* const dec = Integer.toDecimal(Integer.from(42, 'floor'));
|
|
1012
|
+
* dec.add(Decimal.from('0.5')); // 42.5
|
|
1013
|
+
* ```
|
|
1014
|
+
* @public
|
|
1015
|
+
*/
|
|
1016
|
+
toDecimal(value) {
|
|
1017
|
+
return Decimal.from(value);
|
|
1018
|
+
},
|
|
1019
|
+
/**
|
|
1020
|
+
* Type guard that narrows an {@link (Integer:type)} to {@link (PositiveInteger:type)}.
|
|
1021
|
+
*
|
|
1022
|
+
* @example
|
|
1023
|
+
* ```ts
|
|
1024
|
+
* const n = Integer.from(count, 'floor');
|
|
1025
|
+
* if (Integer.isPositive(n)) {
|
|
1026
|
+
* // n is PositiveInteger here
|
|
1027
|
+
* }
|
|
1028
|
+
* ```
|
|
1029
|
+
* @public
|
|
1030
|
+
*/
|
|
1031
|
+
isPositive: (value) => value >= 0,
|
|
1032
|
+
/**
|
|
1033
|
+
* Assertion guard that throws if an {@link (Integer:type)} is not a {@link (PositiveInteger:type)}.
|
|
1034
|
+
*
|
|
1035
|
+
* @example
|
|
1036
|
+
* ```ts
|
|
1037
|
+
* const n = Integer.from(count, 'floor');
|
|
1038
|
+
* Integer.assertIsPositive(n);
|
|
1039
|
+
* // n is PositiveInteger here
|
|
1040
|
+
* ```
|
|
1041
|
+
* @public
|
|
1042
|
+
*/
|
|
1043
|
+
assertIsPositive: assertIntegerIsPositive
|
|
1044
|
+
};
|
|
1045
|
+
var PositiveInteger = {
|
|
1046
|
+
/**
|
|
1047
|
+
* Type guard that narrows an unknown value to {@link (PositiveInteger:type)}.
|
|
1048
|
+
*
|
|
1049
|
+
* @example
|
|
1050
|
+
* ```ts
|
|
1051
|
+
* const n: unknown = getRetryCount();
|
|
1052
|
+
* if (PositiveInteger.is(n)) {
|
|
1053
|
+
* // n is PositiveInteger here
|
|
1054
|
+
* config.maxRetries = n;
|
|
1055
|
+
* }
|
|
1056
|
+
* ```
|
|
1057
|
+
* @public
|
|
1058
|
+
*/
|
|
1059
|
+
is: (value) => typeof value === "number" && Number.isInteger(value) && value >= 0,
|
|
1060
|
+
/**
|
|
1061
|
+
* Assertion guard that throws if the value is not a {@link (PositiveInteger:type)}.
|
|
1062
|
+
*
|
|
1063
|
+
* @example
|
|
1064
|
+
* ```ts
|
|
1065
|
+
* const n: unknown = getRetryCount();
|
|
1066
|
+
* PositiveInteger.assert(n);
|
|
1067
|
+
* // n is PositiveInteger here
|
|
1068
|
+
* ```
|
|
1069
|
+
* @public
|
|
1070
|
+
*/
|
|
1071
|
+
assert: assertIsPositiveInteger,
|
|
1072
|
+
/**
|
|
1073
|
+
* Coerces a value to a {@link (PositiveInteger:type)} by rounding.
|
|
1074
|
+
*
|
|
1075
|
+
* @remarks
|
|
1076
|
+
* Delegates to {@link (Integer:variable).from | Integer.from()} for
|
|
1077
|
+
* rounding, then checks the result is non-negative. All error
|
|
1078
|
+
* conditions from `Integer.from()` apply (non-finite, empty string,
|
|
1079
|
+
* unsafe integer range), plus an additional check that the rounded
|
|
1080
|
+
* result is ≥ 0. IEEE 754 negative zero is normalized to positive zero.
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
* ```ts
|
|
1084
|
+
* PositiveInteger.from(2.7, 'floor'); // 2
|
|
1085
|
+
* PositiveInteger.from('1.5', 'ceil'); // 2
|
|
1086
|
+
* PositiveInteger.from(Decimal.from('3.2'), 'half-up'); // 3
|
|
1087
|
+
* ```
|
|
1088
|
+
*
|
|
1089
|
+
* @throws Error if the value is non-finite, unparseable, outside the
|
|
1090
|
+
* safe integer range, or rounds to a negative number.
|
|
1091
|
+
*
|
|
1092
|
+
* @public
|
|
1093
|
+
*/
|
|
1094
|
+
from(value, rounding) {
|
|
1095
|
+
const rounded = Integer.from(value, rounding);
|
|
1096
|
+
const normalized = normalizeZero2(rounded);
|
|
1097
|
+
if (normalized < 0) {
|
|
1098
|
+
throw new Error(
|
|
1099
|
+
`Value ${String(value)} rounds to ${String(normalized)}, which is negative`
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
return normalized;
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
var StreetAddress = {
|
|
1106
|
+
create: (address) => {
|
|
1107
|
+
return address;
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
var Timestamp = {
|
|
1111
|
+
create: (value) => {
|
|
1112
|
+
return value;
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
// src/stdlib/refs.ts
|
|
1117
|
+
var Ref = {
|
|
1118
|
+
create: (step) => {
|
|
1119
|
+
return {
|
|
1120
|
+
type: step.object,
|
|
1121
|
+
id: step.id
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1125
|
+
|
|
894
1126
|
// src/stdlib/types.ts
|
|
895
1127
|
var WireReadError = class extends Error {
|
|
896
1128
|
/**
|
|
@@ -1423,6 +1655,23 @@ function _applyConfig(descriptor, inputObject, appCtx) {
|
|
|
1423
1655
|
const strategy = appCtx?.clockTime !== void 0 ? createJsonWireToType(appCtx) : _JsonWireToType;
|
|
1424
1656
|
return _apply(descriptor, strategy, inputObject);
|
|
1425
1657
|
}
|
|
1658
|
+
|
|
1659
|
+
// src/stdlib/to-const.ts
|
|
1660
|
+
function toConst(value) {
|
|
1661
|
+
if (value === null || typeof value !== "object") {
|
|
1662
|
+
return value;
|
|
1663
|
+
}
|
|
1664
|
+
if (Array.isArray(value)) {
|
|
1665
|
+
for (const item of value) {
|
|
1666
|
+
toConst(item);
|
|
1667
|
+
}
|
|
1668
|
+
return Object.freeze(value);
|
|
1669
|
+
}
|
|
1670
|
+
for (const key of Object.keys(value)) {
|
|
1671
|
+
toConst(value[key]);
|
|
1672
|
+
}
|
|
1673
|
+
return Object.freeze(value);
|
|
1674
|
+
}
|
|
1426
1675
|
export {
|
|
1427
1676
|
DEFAULT_DIV_PRECISION,
|
|
1428
1677
|
Decimal,
|
|
@@ -1456,5 +1705,6 @@ export {
|
|
|
1456
1705
|
_translateMap,
|
|
1457
1706
|
_translateShape,
|
|
1458
1707
|
_translateUnion,
|
|
1459
|
-
isDecimal
|
|
1708
|
+
isDecimal,
|
|
1709
|
+
toConst
|
|
1460
1710
|
};
|