mixradix 0.1.0 → 0.2.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/dist/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type BaseLike } from "./core.js";
1
+ import { type BaseLike } from "./core/index.js";
2
2
  /** A number for the convenience functions: text in `base`, or an integer. */
3
3
  export type NumberInput = string | number | bigint;
4
4
  export interface CalculateOptions {
package/dist/api.js CHANGED
@@ -1,4 +1,4 @@
1
- import { MixedRadix } from "./core.js";
1
+ import { MixedRadix } from "./core/index.js";
2
2
  /**
3
3
  * Adds numbers written in `base` and returns the sum as text in `to`.
4
4
  *
package/dist/cli.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { parseArgs } from "node:util";
3
- import { MixedRadix } from "./core.js";
4
- import { MixedRadixError } from "./errors.js";
3
+ import { MixedRadix } from "./core/index.js";
4
+ import { MixedRadixError } from "./errors/index.js";
5
+ import { UsageError } from "./usage-error.js";
5
6
  const processIo = {
6
7
  stdout: (text) => process.stdout.write(text),
7
8
  stderr: (text) => process.stderr.write(text),
@@ -120,15 +121,6 @@ function protectNegativeNumbers(argv) {
120
121
  }
121
122
  return result;
122
123
  }
123
- class UsageError extends Error {
124
- usage;
125
- prog;
126
- constructor(usage, prog, message) {
127
- super(message);
128
- this.usage = usage;
129
- this.prog = prog;
130
- }
131
- }
132
124
  /** Runs the CLI with `argv` (without the node and script paths) and returns the exit code. */
133
125
  export function main(argv = process.argv.slice(2), io = processIo) {
134
126
  try {
@@ -0,0 +1,18 @@
1
+ /** What is left of the leftmost radix: see the README. */
2
+ export type Overflow = "extend" | "wrap" | "repeat";
3
+ export declare const SEPARATOR = ":";
4
+ export declare const OVERFLOW_SEPARATOR = "/";
5
+ export declare const DIGIT_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz";
6
+ export declare const MAX_COMPACT_RADIX: bigint;
7
+ export declare const BASE_SYNTAX = "expected radices of 2 or more separated by ':', like 16 or 24:60:60";
8
+ export declare const DIGIT_SYNTAX = "expected decimal digits separated by ':'";
9
+ export declare const isDecimal: (text: string) => boolean;
10
+ export declare const defaultOverflow: (radixCount: number) => Overflow;
11
+ export declare const listLabel: (values: readonly unknown[]) => string;
12
+ export declare function checkOverflow(base: string, overflow: string): Overflow;
13
+ /** A safe integer or bigint as a bigint, or undefined for anything else. */
14
+ export declare function asInteger(value: unknown): bigint | undefined;
15
+ export declare function toInteger(value: number | bigint): bigint;
16
+ export declare const abs: (value: bigint) => bigint;
17
+ /** Remainder that is never negative, for wrapping values into [0, modulus). */
18
+ export declare const mod: (value: bigint, modulus: bigint) => bigint;
@@ -0,0 +1,37 @@
1
+ /** Notation and integer helpers shared by MixedRadix and MixedRadixNumber. */
2
+ import { InvalidBaseError } from "../errors/index.js";
3
+ const OVERFLOWS = ["extend", "wrap", "repeat"];
4
+ export const SEPARATOR = ":";
5
+ export const OVERFLOW_SEPARATOR = "/";
6
+ export const DIGIT_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz";
7
+ export const MAX_COMPACT_RADIX = BigInt(DIGIT_CHARS.length);
8
+ export const BASE_SYNTAX = "expected radices of 2 or more separated by ':', like 16 or 24:60:60";
9
+ export const DIGIT_SYNTAX = "expected decimal digits separated by ':'";
10
+ export const isDecimal = (text) => /^[0-9]+$/.test(text);
11
+ export const defaultOverflow = (radixCount) => radixCount === 1 ? "repeat" : "extend";
12
+ export const listLabel = (values) => `[${values.map(String).join(", ")}]`;
13
+ export function checkOverflow(base, overflow) {
14
+ const known = OVERFLOWS.find((o) => o === overflow);
15
+ if (known === undefined) {
16
+ throw new InvalidBaseError(base, `unknown overflow '${overflow}' (expected extend, wrap or repeat)`);
17
+ }
18
+ return known;
19
+ }
20
+ /** A safe integer or bigint as a bigint, or undefined for anything else. */
21
+ export function asInteger(value) {
22
+ if (typeof value === "bigint")
23
+ return value;
24
+ if (typeof value === "number" && Number.isSafeInteger(value))
25
+ return BigInt(value);
26
+ return undefined;
27
+ }
28
+ export function toInteger(value) {
29
+ const integer = asInteger(value);
30
+ if (integer === undefined) {
31
+ throw new TypeError(`expected a safe integer or a bigint, got ${String(value)}`);
32
+ }
33
+ return integer;
34
+ }
35
+ export const abs = (value) => (value < 0n ? -value : value);
36
+ /** Remainder that is never negative, for wrapping values into [0, modulus). */
37
+ export const mod = (value, modulus) => ((value % modulus) + modulus) % modulus;
@@ -0,0 +1,3 @@
1
+ export type { Overflow } from "./common.js";
2
+ export { type BaseLike, type BaseOptions, MixedRadix } from "./mixed-radix.js";
3
+ export { MixedRadixNumber, type NumberLike } from "./mixed-radix-number.js";
@@ -0,0 +1,2 @@
1
+ export { MixedRadix } from "./mixed-radix.js";
2
+ export { MixedRadixNumber } from "./mixed-radix-number.js";
@@ -0,0 +1,34 @@
1
+ import { type BaseLike, MixedRadix } from "./mixed-radix.js";
2
+ /** An operand for arithmetic: a number, an integer, or text in the left operand's base. */
3
+ export type NumberLike = MixedRadixNumber | string | number | bigint;
4
+ /**
5
+ * A signed integer of any size, written in a MixedRadix.
6
+ *
7
+ * Arithmetic is on values, so operands may be in different bases, integers,
8
+ * or text in this number's base. Results use the left operand's base.
9
+ *
10
+ * ```ts
11
+ * new MixedRadixNumber("23:59:59", "24:60:60").add(1).toString(); // "1:0:0:0"
12
+ * ```
13
+ */
14
+ export declare class MixedRadixNumber {
15
+ readonly value: bigint;
16
+ readonly base: MixedRadix;
17
+ constructor(number: string | number | bigint, base?: BaseLike);
18
+ get isNegative(): boolean;
19
+ /** Digit values of the absolute value, most significant first. */
20
+ get digits(): readonly bigint[];
21
+ /** The same value written in another base. */
22
+ to(base: BaseLike): MixedRadixNumber;
23
+ add(other: NumberLike): MixedRadixNumber;
24
+ sub(other: NumberLike): MixedRadixNumber;
25
+ neg(): MixedRadixNumber;
26
+ abs(): MixedRadixNumber;
27
+ /** -1, 0 or 1 as this value is below, equal to or above `other`'s. */
28
+ compare(other: MixedRadixNumber | number | bigint): -1 | 0 | 1;
29
+ /** True when the values are equal, whatever the bases. */
30
+ equals(other: MixedRadixNumber | number | bigint): boolean;
31
+ toBigInt(): bigint;
32
+ toString(): string;
33
+ toJSON(): string;
34
+ }
@@ -0,0 +1,111 @@
1
+ import { abs, DIGIT_CHARS, mod, SEPARATOR, toInteger } from "./common.js";
2
+ import { MixedRadix } from "./mixed-radix.js";
3
+ /**
4
+ * A signed integer of any size, written in a MixedRadix.
5
+ *
6
+ * Arithmetic is on values, so operands may be in different bases, integers,
7
+ * or text in this number's base. Results use the left operand's base.
8
+ *
9
+ * ```ts
10
+ * new MixedRadixNumber("23:59:59", "24:60:60").add(1).toString(); // "1:0:0:0"
11
+ * ```
12
+ */
13
+ export class MixedRadixNumber {
14
+ value;
15
+ base;
16
+ constructor(number, base = 10) {
17
+ const mixedRadix = MixedRadix.of(base);
18
+ const built = typeof number === "string" ? mixedRadix.parse(number) : mixedRadix.fromInt(number);
19
+ this.value = built.value;
20
+ this.base = mixedRadix;
21
+ Object.freeze(this);
22
+ }
23
+ /** @internal Makes a number from a value, wrapping it for `wrap` bases. */
24
+ static create(value, base) {
25
+ const modulus = base.modulus;
26
+ const number = Object.create(MixedRadixNumber.prototype);
27
+ Object.assign(number, { value: modulus === null ? value : mod(value, modulus), base });
28
+ return Object.freeze(number);
29
+ }
30
+ get isNegative() {
31
+ return this.value < 0n;
32
+ }
33
+ /** Digit values of the absolute value, most significant first. */
34
+ get digits() {
35
+ let remaining = abs(this.value);
36
+ const digits = []; // least significant first while building
37
+ if (this.base.overflow === "wrap") {
38
+ for (let i = this.base.radices.length - 1; i >= 0; i--) {
39
+ const radix = this.base.radices[i];
40
+ digits.push(remaining % radix);
41
+ remaining /= radix;
42
+ }
43
+ }
44
+ else {
45
+ for (let position = 0;; position++) {
46
+ const radix = this.base.radixAt(position);
47
+ if (radix === null) {
48
+ digits.push(remaining);
49
+ break;
50
+ }
51
+ digits.push(remaining % radix);
52
+ remaining /= radix;
53
+ if (remaining === 0n)
54
+ break;
55
+ }
56
+ }
57
+ return Object.freeze(digits.reverse());
58
+ }
59
+ /** The same value written in another base. */
60
+ to(base) {
61
+ return MixedRadixNumber.create(this.value, MixedRadix.of(base));
62
+ }
63
+ // -- Arithmetic --------------------------------------------------------------
64
+ add(other) {
65
+ return MixedRadixNumber.create(this.value + operandValue(this, other), this.base);
66
+ }
67
+ sub(other) {
68
+ return MixedRadixNumber.create(this.value - operandValue(this, other), this.base);
69
+ }
70
+ neg() {
71
+ return MixedRadixNumber.create(-this.value, this.base);
72
+ }
73
+ abs() {
74
+ return MixedRadixNumber.create(abs(this.value), this.base);
75
+ }
76
+ // -- Comparison (by value) -----------------------------------------------------
77
+ /** -1, 0 or 1 as this value is below, equal to or above `other`'s. */
78
+ compare(other) {
79
+ const value = other instanceof MixedRadixNumber ? other.value : toInteger(other);
80
+ return this.value < value ? -1 : this.value > value ? 1 : 0;
81
+ }
82
+ /** True when the values are equal, whatever the bases. */
83
+ equals(other) {
84
+ return this.compare(other) === 0;
85
+ }
86
+ // -- Conversion ------------------------------------------------------------------
87
+ toBigInt() {
88
+ return this.value;
89
+ }
90
+ toString() {
91
+ const sign = this.value < 0n ? "-" : "";
92
+ const digits = this.digits;
93
+ if (this.base.isUniform)
94
+ return sign + digits.map((d) => DIGIT_CHARS[Number(d)]).join("");
95
+ return sign + digits.join(SEPARATOR);
96
+ }
97
+ toJSON() {
98
+ return this.toString();
99
+ }
100
+ [Symbol.for("nodejs.util.inspect.custom")]() {
101
+ return `MixedRadixNumber('${this}', base='${this.base}')`;
102
+ }
103
+ }
104
+ /** The value of an arithmetic operand; text is parsed in the left operand's base. */
105
+ function operandValue(left, other) {
106
+ if (other instanceof MixedRadixNumber)
107
+ return other.value;
108
+ if (typeof other === "string")
109
+ return left.base.parse(other).value;
110
+ return toInteger(other);
111
+ }
@@ -1,9 +1,7 @@
1
- /** What is left of the leftmost radix: see the README. */
2
- export type Overflow = "extend" | "wrap" | "repeat";
1
+ import { type Overflow } from "./common.js";
2
+ import { MixedRadixNumber } from "./mixed-radix-number.js";
3
3
  /** Anything that can be turned into a base: `"24:60:60"`, `16`, `[24, 60, 60]`. */
4
4
  export type BaseLike = MixedRadix | string | number | bigint | readonly (number | bigint)[];
5
- /** An operand for arithmetic: a number, an integer, or text in the left operand's base. */
6
- export type NumberLike = MixedRadixNumber | string | number | bigint;
7
5
  export interface BaseOptions {
8
6
  overflow?: Overflow;
9
7
  }
@@ -60,34 +58,3 @@ export declare class MixedRadix {
60
58
  toString(): string;
61
59
  toJSON(): string;
62
60
  }
63
- /**
64
- * A signed integer of any size, written in a MixedRadix.
65
- *
66
- * Arithmetic is on values, so operands may be in different bases, integers,
67
- * or text in this number's base. Results use the left operand's base.
68
- *
69
- * ```ts
70
- * new MixedRadixNumber("23:59:59", "24:60:60").add(1).toString(); // "1:0:0:0"
71
- * ```
72
- */
73
- export declare class MixedRadixNumber {
74
- readonly value: bigint;
75
- readonly base: MixedRadix;
76
- constructor(number: string | number | bigint, base?: BaseLike);
77
- get isNegative(): boolean;
78
- /** Digit values of the absolute value, most significant first. */
79
- get digits(): readonly bigint[];
80
- /** The same value written in another base. */
81
- to(base: BaseLike): MixedRadixNumber;
82
- add(other: NumberLike): MixedRadixNumber;
83
- sub(other: NumberLike): MixedRadixNumber;
84
- neg(): MixedRadixNumber;
85
- abs(): MixedRadixNumber;
86
- /** -1, 0 or 1 as this value is below, equal to or above `other`'s. */
87
- compare(other: MixedRadixNumber | number | bigint): -1 | 0 | 1;
88
- /** True when the values are equal, whatever the bases. */
89
- equals(other: MixedRadixNumber | number | bigint): boolean;
90
- toBigInt(): bigint;
91
- toString(): string;
92
- toJSON(): string;
93
- }
@@ -1,39 +1,6 @@
1
- import { DigitOutOfRangeError, InvalidBaseError, InvalidNumberError } from "./errors.js";
2
- const OVERFLOWS = ["extend", "wrap", "repeat"];
3
- const SEPARATOR = ":";
4
- const OVERFLOW_SEPARATOR = "/";
5
- const DIGIT_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz";
6
- const MAX_COMPACT_RADIX = BigInt(DIGIT_CHARS.length);
7
- const BASE_SYNTAX = "expected radices of 2 or more separated by ':', like 16 or 24:60:60";
8
- const DIGIT_SYNTAX = "expected decimal digits separated by ':'";
9
- const isDecimal = (text) => /^[0-9]+$/.test(text);
10
- const defaultOverflow = (radixCount) => (radixCount === 1 ? "repeat" : "extend");
11
- const listLabel = (values) => `[${values.map(String).join(", ")}]`;
12
- function checkOverflow(base, overflow) {
13
- const known = OVERFLOWS.find((o) => o === overflow);
14
- if (known === undefined) {
15
- throw new InvalidBaseError(base, `unknown overflow '${overflow}' (expected extend, wrap or repeat)`);
16
- }
17
- return known;
18
- }
19
- /** A safe integer or bigint as a bigint, or undefined for anything else. */
20
- function asInteger(value) {
21
- if (typeof value === "bigint")
22
- return value;
23
- if (typeof value === "number" && Number.isSafeInteger(value))
24
- return BigInt(value);
25
- return undefined;
26
- }
27
- function toInteger(value) {
28
- const integer = asInteger(value);
29
- if (integer === undefined) {
30
- throw new TypeError(`expected a safe integer or a bigint, got ${String(value)}`);
31
- }
32
- return integer;
33
- }
34
- const abs = (value) => (value < 0n ? -value : value);
35
- /** Remainder that is never negative, for wrapping values into [0, modulus). */
36
- const mod = (value, modulus) => ((value % modulus) + modulus) % modulus;
1
+ import { DigitOutOfRangeError, InvalidBaseError, InvalidNumberError } from "../errors/index.js";
2
+ import { asInteger, BASE_SYNTAX, checkOverflow, DIGIT_CHARS, DIGIT_SYNTAX, defaultOverflow, isDecimal, listLabel, MAX_COMPACT_RADIX, OVERFLOW_SEPARATOR, SEPARATOR, toInteger, } from "./common.js";
3
+ import { MixedRadixNumber } from "./mixed-radix-number.js";
37
4
  /**
38
5
  * A base with one radix per digit position, most significant first.
39
6
  *
@@ -254,112 +221,3 @@ export class MixedRadix {
254
221
  return `MixedRadix('${this}')`;
255
222
  }
256
223
  }
257
- /**
258
- * A signed integer of any size, written in a MixedRadix.
259
- *
260
- * Arithmetic is on values, so operands may be in different bases, integers,
261
- * or text in this number's base. Results use the left operand's base.
262
- *
263
- * ```ts
264
- * new MixedRadixNumber("23:59:59", "24:60:60").add(1).toString(); // "1:0:0:0"
265
- * ```
266
- */
267
- export class MixedRadixNumber {
268
- value;
269
- base;
270
- constructor(number, base = 10) {
271
- const mixedRadix = MixedRadix.of(base);
272
- const built = typeof number === "string" ? mixedRadix.parse(number) : mixedRadix.fromInt(number);
273
- this.value = built.value;
274
- this.base = mixedRadix;
275
- Object.freeze(this);
276
- }
277
- /** @internal Makes a number from a value, wrapping it for `wrap` bases. */
278
- static create(value, base) {
279
- const modulus = base.modulus;
280
- const number = Object.create(MixedRadixNumber.prototype);
281
- Object.assign(number, { value: modulus === null ? value : mod(value, modulus), base });
282
- return Object.freeze(number);
283
- }
284
- get isNegative() {
285
- return this.value < 0n;
286
- }
287
- /** Digit values of the absolute value, most significant first. */
288
- get digits() {
289
- let remaining = abs(this.value);
290
- const digits = []; // least significant first while building
291
- if (this.base.overflow === "wrap") {
292
- for (let i = this.base.radices.length - 1; i >= 0; i--) {
293
- const radix = this.base.radices[i];
294
- digits.push(remaining % radix);
295
- remaining /= radix;
296
- }
297
- }
298
- else {
299
- for (let position = 0;; position++) {
300
- const radix = this.base.radixAt(position);
301
- if (radix === null) {
302
- digits.push(remaining);
303
- break;
304
- }
305
- digits.push(remaining % radix);
306
- remaining /= radix;
307
- if (remaining === 0n)
308
- break;
309
- }
310
- }
311
- return Object.freeze(digits.reverse());
312
- }
313
- /** The same value written in another base. */
314
- to(base) {
315
- return MixedRadixNumber.create(this.value, MixedRadix.of(base));
316
- }
317
- // -- Arithmetic --------------------------------------------------------------
318
- add(other) {
319
- return MixedRadixNumber.create(this.value + operandValue(this, other), this.base);
320
- }
321
- sub(other) {
322
- return MixedRadixNumber.create(this.value - operandValue(this, other), this.base);
323
- }
324
- neg() {
325
- return MixedRadixNumber.create(-this.value, this.base);
326
- }
327
- abs() {
328
- return MixedRadixNumber.create(abs(this.value), this.base);
329
- }
330
- // -- Comparison (by value) -----------------------------------------------------
331
- /** -1, 0 or 1 as this value is below, equal to or above `other`'s. */
332
- compare(other) {
333
- const value = other instanceof MixedRadixNumber ? other.value : toInteger(other);
334
- return this.value < value ? -1 : this.value > value ? 1 : 0;
335
- }
336
- /** True when the values are equal, whatever the bases. */
337
- equals(other) {
338
- return this.compare(other) === 0;
339
- }
340
- // -- Conversion ------------------------------------------------------------------
341
- toBigInt() {
342
- return this.value;
343
- }
344
- toString() {
345
- const sign = this.value < 0n ? "-" : "";
346
- const digits = this.digits;
347
- if (this.base.isUniform)
348
- return sign + digits.map((d) => DIGIT_CHARS[Number(d)]).join("");
349
- return sign + digits.join(SEPARATOR);
350
- }
351
- toJSON() {
352
- return this.toString();
353
- }
354
- [Symbol.for("nodejs.util.inspect.custom")]() {
355
- return `MixedRadixNumber('${this}', base='${this.base}')`;
356
- }
357
- }
358
- /** The value of an arithmetic operand; text is parsed in the left operand's base. */
359
- function operandValue(left, other) {
360
- if (other instanceof MixedRadixNumber)
361
- return other.value;
362
- if (typeof other === "string")
363
- return left.base.parse(other).value;
364
- return toInteger(other);
365
- }
@@ -0,0 +1,8 @@
1
+ import { InvalidNumberError } from "./invalid-number-error.js";
2
+ /** A digit is not below the radix of its position. */
3
+ export declare class DigitOutOfRangeError extends InvalidNumberError {
4
+ readonly digit: bigint;
5
+ readonly radix: bigint;
6
+ name: string;
7
+ constructor(number: string, digit: bigint, radix: bigint, char?: string);
8
+ }
@@ -0,0 +1,13 @@
1
+ import { InvalidNumberError } from "./invalid-number-error.js";
2
+ /** A digit is not below the radix of its position. */
3
+ export class DigitOutOfRangeError extends InvalidNumberError {
4
+ digit;
5
+ radix;
6
+ name = "DigitOutOfRangeError";
7
+ constructor(number, digit, radix, char) {
8
+ const shown = char !== undefined && !/^[0-9]$/.test(char) ? `'${char}' (${digit})` : `${digit}`;
9
+ super(number, `digit ${shown} is out of range for radix ${radix}`);
10
+ this.digit = digit;
11
+ this.radix = radix;
12
+ }
13
+ }
@@ -0,0 +1,4 @@
1
+ export { DigitOutOfRangeError } from "./digit-out-of-range-error.js";
2
+ export { InvalidBaseError } from "./invalid-base-error.js";
3
+ export { InvalidNumberError } from "./invalid-number-error.js";
4
+ export { MixedRadixError } from "./mixed-radix-error.js";
@@ -0,0 +1,4 @@
1
+ export { DigitOutOfRangeError } from "./digit-out-of-range-error.js";
2
+ export { InvalidBaseError } from "./invalid-base-error.js";
3
+ export { InvalidNumberError } from "./invalid-number-error.js";
4
+ export { MixedRadixError } from "./mixed-radix-error.js";
@@ -0,0 +1,8 @@
1
+ import { MixedRadixError } from "./mixed-radix-error.js";
2
+ /** A base could not be parsed or built. */
3
+ export declare class InvalidBaseError extends MixedRadixError {
4
+ readonly base: string;
5
+ readonly reason: string;
6
+ name: string;
7
+ constructor(base: string, reason: string);
8
+ }
@@ -0,0 +1,12 @@
1
+ import { MixedRadixError } from "./mixed-radix-error.js";
2
+ /** A base could not be parsed or built. */
3
+ export class InvalidBaseError extends MixedRadixError {
4
+ base;
5
+ reason;
6
+ name = "InvalidBaseError";
7
+ constructor(base, reason) {
8
+ super(`invalid base ${base}: ${reason}`);
9
+ this.base = base;
10
+ this.reason = reason;
11
+ }
12
+ }
@@ -0,0 +1,8 @@
1
+ import { MixedRadixError } from "./mixed-radix-error.js";
2
+ /** A number could not be parsed or built in its base. */
3
+ export declare class InvalidNumberError extends MixedRadixError {
4
+ readonly number: string;
5
+ readonly reason: string;
6
+ name: string;
7
+ constructor(number: string, reason: string);
8
+ }
@@ -0,0 +1,12 @@
1
+ import { MixedRadixError } from "./mixed-radix-error.js";
2
+ /** A number could not be parsed or built in its base. */
3
+ export class InvalidNumberError extends MixedRadixError {
4
+ number;
5
+ reason;
6
+ name = "InvalidNumberError";
7
+ constructor(number, reason) {
8
+ super(`invalid number ${number}: ${reason}`);
9
+ this.number = number;
10
+ this.reason = reason;
11
+ }
12
+ }
@@ -0,0 +1,4 @@
1
+ /** Base class for every error thrown by mixradix. */
2
+ export declare class MixedRadixError extends Error {
3
+ name: string;
4
+ }
@@ -0,0 +1,4 @@
1
+ /** Base class for every error thrown by mixradix. */
2
+ export class MixedRadixError extends Error {
3
+ name = "MixedRadixError";
4
+ }
package/dist/index.d.ts CHANGED
@@ -5,5 +5,5 @@
5
5
  * @module
6
6
  */
7
7
  export { add, type CalculateOptions, type ConvertOptions, convert, type NumberInput, sub, } from "./api.js";
8
- export { type BaseLike, type BaseOptions, MixedRadix, MixedRadixNumber, type NumberLike, type Overflow, } from "./core.js";
9
- export { DigitOutOfRangeError, InvalidBaseError, InvalidNumberError, MixedRadixError, } from "./errors.js";
8
+ export { type BaseLike, type BaseOptions, MixedRadix, MixedRadixNumber, type NumberLike, type Overflow, } from "./core/index.js";
9
+ export { DigitOutOfRangeError, InvalidBaseError, InvalidNumberError, MixedRadixError, } from "./errors/index.js";
package/dist/index.js CHANGED
@@ -5,5 +5,5 @@
5
5
  * @module
6
6
  */
7
7
  export { add, convert, sub, } from "./api.js";
8
- export { MixedRadix, MixedRadixNumber, } from "./core.js";
9
- export { DigitOutOfRangeError, InvalidBaseError, InvalidNumberError, MixedRadixError, } from "./errors.js";
8
+ export { MixedRadix, MixedRadixNumber, } from "./core/index.js";
9
+ export { DigitOutOfRangeError, InvalidBaseError, InvalidNumberError, MixedRadixError, } from "./errors/index.js";
@@ -0,0 +1,6 @@
1
+ /** A bad command line: printed with the usage text, exit code 2. */
2
+ export declare class UsageError extends Error {
3
+ readonly usage: string;
4
+ readonly prog: string;
5
+ constructor(usage: string, prog: string, message: string);
6
+ }
@@ -0,0 +1,10 @@
1
+ /** A bad command line: printed with the usage text, exit code 2. */
2
+ export class UsageError extends Error {
3
+ usage;
4
+ prog;
5
+ constructor(usage, prog, message) {
6
+ super(message);
7
+ this.usage = usage;
8
+ this.prog = prog;
9
+ }
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixradix",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Add, subtract and convert integers of any size in mixed radix bases (like 24:60:60), with a CLI",
5
5
  "keywords": [
6
6
  "mixed-radix",
package/dist/errors.d.ts DELETED
@@ -1,25 +0,0 @@
1
- /** Base class for every error thrown by mixradix. */
2
- export declare class MixedRadixError extends Error {
3
- name: string;
4
- }
5
- /** A base could not be parsed or built. */
6
- export declare class InvalidBaseError extends MixedRadixError {
7
- readonly base: string;
8
- readonly reason: string;
9
- name: string;
10
- constructor(base: string, reason: string);
11
- }
12
- /** A number could not be parsed or built in its base. */
13
- export declare class InvalidNumberError extends MixedRadixError {
14
- readonly number: string;
15
- readonly reason: string;
16
- name: string;
17
- constructor(number: string, reason: string);
18
- }
19
- /** A digit is not below the radix of its position. */
20
- export declare class DigitOutOfRangeError extends InvalidNumberError {
21
- readonly digit: bigint;
22
- readonly radix: bigint;
23
- name: string;
24
- constructor(number: string, digit: bigint, radix: bigint, char?: string);
25
- }
package/dist/errors.js DELETED
@@ -1,38 +0,0 @@
1
- /** Base class for every error thrown by mixradix. */
2
- export class MixedRadixError extends Error {
3
- name = "MixedRadixError";
4
- }
5
- /** A base could not be parsed or built. */
6
- export class InvalidBaseError extends MixedRadixError {
7
- base;
8
- reason;
9
- name = "InvalidBaseError";
10
- constructor(base, reason) {
11
- super(`invalid base ${base}: ${reason}`);
12
- this.base = base;
13
- this.reason = reason;
14
- }
15
- }
16
- /** A number could not be parsed or built in its base. */
17
- export class InvalidNumberError extends MixedRadixError {
18
- number;
19
- reason;
20
- name = "InvalidNumberError";
21
- constructor(number, reason) {
22
- super(`invalid number ${number}: ${reason}`);
23
- this.number = number;
24
- this.reason = reason;
25
- }
26
- }
27
- /** A digit is not below the radix of its position. */
28
- export class DigitOutOfRangeError extends InvalidNumberError {
29
- digit;
30
- radix;
31
- name = "DigitOutOfRangeError";
32
- constructor(number, digit, radix, char) {
33
- const shown = char !== undefined && !/^[0-9]$/.test(char) ? `'${char}' (${digit})` : `${digit}`;
34
- super(number, `digit ${shown} is out of range for radix ${radix}`);
35
- this.digit = digit;
36
- this.radix = radix;
37
- }
38
- }