From 02cdf7577832e6f51676e4f3d0cec277ce1068c4 Mon Sep 17 00:00:00 2001 From: Matt Magoffin Date: Thu, 21 Sep 2023 15:55:05 +1200 Subject: [PATCH] Build from latest source. --- dist/nifty-tou.d.ts | 150 +++++++++++- docs/md/nifty-tou.chronofield.md | 21 ++ ...fty-tou.chronofieldparser._constructor_.md | 20 ++ .../nifty-tou.chronofieldparser.forlocale.md | 28 +++ docs/md/nifty-tou.chronofieldparser.locale.md | 13 + docs/md/nifty-tou.chronofieldparser.md | 34 +++ docs/md/nifty-tou.chronofieldparser.parse.md | 27 +++ .../nifty-tou.chronofieldparser.parserange.md | 40 +++ ...ifty-tou.chronofieldvalue._constructor_.md | 22 ++ docs/md/nifty-tou.chronofieldvalue.field.md | 13 + docs/md/nifty-tou.chronofieldvalue.md | 29 +++ docs/md/nifty-tou.chronofieldvalue.name.md | 13 + .../nifty-tou.chronofieldvalue.shortname.md | 13 + docs/md/nifty-tou.chronofieldvalue.value.md | 13 + docs/md/nifty-tou.intrange.md | 1 + docs/md/nifty-tou.intrange.parserange.md | 27 +++ docs/md/nifty-tou.md | 9 + .../nifty-tou.numberparser._constructor_.md | 20 ++ docs/md/nifty-tou.numberparser.locale.md | 13 + docs/md/nifty-tou.numberparser.md | 35 +++ docs/md/nifty-tou.numberparser.norm.md | 26 ++ docs/md/nifty-tou.numberparser.parse.md | 26 ++ docs/md/nifty-tou.utils.md | 1 + docs/md/nifty-tou.utils.splitrange.md | 28 +++ etc/nifty-tou.api.md | 39 ++- lib/main/ChronoFieldParser.d.ts | 93 +++++++ lib/main/ChronoFieldParser.d.ts.map | 1 + lib/main/ChronoFieldParser.js | 228 ++++++++++++++++++ lib/main/ChronoFieldParser.js.map | 1 + lib/main/IntRange.d.ts | 9 + lib/main/IntRange.d.ts.map | 2 +- lib/main/IntRange.js | 23 ++ lib/main/IntRange.js.map | 2 +- lib/main/NumberParser.d.ts | 32 +++ lib/main/NumberParser.d.ts.map | 1 + lib/main/NumberParser.js | 63 +++++ lib/main/NumberParser.js.map | 1 + lib/main/index.d.ts | 2 + lib/main/index.d.ts.map | 2 +- lib/main/index.js | 2 + lib/main/index.js.map | 2 +- lib/main/utils.d.ts | 11 + lib/main/utils.d.ts.map | 2 +- lib/main/utils.js | 24 ++ lib/main/utils.js.map | 2 +- 45 files changed, 1156 insertions(+), 8 deletions(-) create mode 100644 docs/md/nifty-tou.chronofield.md create mode 100644 docs/md/nifty-tou.chronofieldparser._constructor_.md create mode 100644 docs/md/nifty-tou.chronofieldparser.forlocale.md create mode 100644 docs/md/nifty-tou.chronofieldparser.locale.md create mode 100644 docs/md/nifty-tou.chronofieldparser.md create mode 100644 docs/md/nifty-tou.chronofieldparser.parse.md create mode 100644 docs/md/nifty-tou.chronofieldparser.parserange.md create mode 100644 docs/md/nifty-tou.chronofieldvalue._constructor_.md create mode 100644 docs/md/nifty-tou.chronofieldvalue.field.md create mode 100644 docs/md/nifty-tou.chronofieldvalue.md create mode 100644 docs/md/nifty-tou.chronofieldvalue.name.md create mode 100644 docs/md/nifty-tou.chronofieldvalue.shortname.md create mode 100644 docs/md/nifty-tou.chronofieldvalue.value.md create mode 100644 docs/md/nifty-tou.intrange.parserange.md create mode 100644 docs/md/nifty-tou.numberparser._constructor_.md create mode 100644 docs/md/nifty-tou.numberparser.locale.md create mode 100644 docs/md/nifty-tou.numberparser.md create mode 100644 docs/md/nifty-tou.numberparser.norm.md create mode 100644 docs/md/nifty-tou.numberparser.parse.md create mode 100644 docs/md/nifty-tou.utils.splitrange.md create mode 100644 lib/main/ChronoFieldParser.d.ts create mode 100644 lib/main/ChronoFieldParser.d.ts.map create mode 100644 lib/main/ChronoFieldParser.js create mode 100644 lib/main/ChronoFieldParser.js.map create mode 100644 lib/main/NumberParser.d.ts create mode 100644 lib/main/NumberParser.d.ts.map create mode 100644 lib/main/NumberParser.js create mode 100644 lib/main/NumberParser.js.map diff --git a/dist/nifty-tou.d.ts b/dist/nifty-tou.d.ts index 01f3c68..d50a89e 100644 --- a/dist/nifty-tou.d.ts +++ b/dist/nifty-tou.d.ts @@ -12,6 +12,100 @@ */ declare function cconcat(s1?: string, s2?: string): string; +/** + * An enumeration of supported chronological fields of the Gregorian calendar. + * @public + */ +export declare enum ChronoField { + /** The month of year, from January (1) to December (12). */ + MONTH_OF_YEAR = 1, + /** The day of the week, from Monday (1) to Sunday (7). */ + DAY_OF_WEEK = 2 +} + +/** + * Class to parse locale-specific chronological field names of the Gregorian calendar. + * @public + */ +export declare class ChronoFieldParser { + #private; + /** + * Get a parser for a given locale. + * + * This method will instantiate and cache parsers, returning cached instances + * if already avaialble. + * + * @param locale - the locale of the parser to get + * @returns the parser + */ + static forLocale(locale: string): ChronoFieldParser; + /** + * Constructor. + * + * @param locale - the desired locale + */ + constructor(locale: string); + /** + * Get the locale. + */ + get locale(): string; + /** + * Parse a field value. + * + * @param field - the field to treat `val` as + * @param value - the field value to parse + * @returns the associated field value, or undefined if not found + */ + parse(field: ChronoField, value: string): ChronoFieldValue; + /** + * Parse a chronological field range string. + * + * A "range string" is a string formatted like `VALUE - VALUE`. Whitespace + * is ignored, and the `- VALUE` portion can be omitted for a singleton + * range. For example, in the `en-US` locale, `Jan-Dec` would be parsed as + * `[1..12]`. + * + * @example + * Here are some basic examples: + * + * ```ts + * const p = ChronoFieldParser.forLocale('en-US'); + * p.parseRange(ChronoField.MONTH_OF_YEAR, 'Jan-Dec'); // [1..12] + * p.parseRange(ChronoField.MONTH_OF_YEAR, '4-6'); // [4..6] + * p.parseRange(ChronoField.DAY_OF_WEEK, 'Wednesday'); // [3..3] + * ``` + * + * @param field - the field to parse the range values as + * @param value - the range string to parse + * @returns the parsed range, or `undefined` if not parsable as a range + */ + parseRange(field: ChronoField, value: string): IntRange; +} + +/** + * A chronological field value. + * @public + */ +export declare class ChronoFieldValue { + #private; + /** + * Constructor. + * + * @param field - the chronological field + * @param names - the value names, from longest to shortest + * @param value - the value + */ + constructor(field: ChronoField, names: string[], value: number); + /** Get the field. */ + get field(): ChronoField; + /** Get the full name. */ + get name(): string; + /** Get the short name. */ + get shortName(): string; + /** Get the value. */ + get value(): number; +} + /** * An immutable number range with min/max values. * @public @@ -30,6 +124,15 @@ export declare class IntRange { * Create a range. */ static rangeOf(min: number, max: number): IntRange; + /** + * Parse a range array into an `IntRange`. + * + * @param value - the range array to parse; can have 1 or 2 elements; all elements must have number values + * @param bounds - the optional bounds (inclusive) to enforce; if the parsed range + * @returns the parsed range, or `undefined` if a range could not be parsed or extends + * beyond the given `bounds` then `undefined` will be returned + */ + static parseRange(array: string[], bounds?: IntRange): IntRange; /** * Get the minimum value. */ @@ -132,6 +235,38 @@ export declare class IntRange { static description(full: IntRange, r: IntRange): string; } +/** + * A locale-specific number parser. + * + * Adapted from Mike Bostock's https://observablehq.com/\@mbostock/localized-number-parsing + * @public + */ +export declare class NumberParser { + #private; + /** + * Constructor. + * + * @param locale - the desired locale + */ + constructor(locale: string); + /** Get the locale. */ + get locale(): string; + /** + * Normalize a locale-specific number string. + * + * @param s - the number string to parse in this instance's locale + * @returns the number string normalized into a JavaScript number string + */ + norm(s: string): string; + /** + * Parse a locale-specific number string. + * + * @param s - the number string to parse in this instance's locale + * @returns the parsed number, or `undefined` + */ + parse(s: string): number; +} + /** * Verify that a variable is undefined or of a given type. * @@ -166,6 +301,18 @@ declare function prefix(prefix?: string, s?: string): string; */ declare function required(arg: T, name: string, type?: new (...args: any[]) => any): T; +/** + * Split a string based on a range delimiter pattern. + * + * A range delimited string has the pattern `VALUE - VALUE`, where whitespace + * at the start, around the `-` delimiter, and at the end is not significant. + * + * @param range - the range string to split into components, whitespace trimmed + * @returns the split range, of length 1 or 2, or `undefined` if `range` is undefined + * @public + */ +declare function splitRange(range: string): string[]; + /** * An identifiable tariff rate. * @@ -284,7 +431,8 @@ declare namespace Utils { cconcat, optional, prefix, - required + required, + splitRange } } export { Utils } diff --git a/docs/md/nifty-tou.chronofield.md b/docs/md/nifty-tou.chronofield.md new file mode 100644 index 0000000..52adc59 --- /dev/null +++ b/docs/md/nifty-tou.chronofield.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoField](./nifty-tou.chronofield.md) + +## ChronoField enum + +An enumeration of supported chronological fields of the Gregorian calendar. + +**Signature:** + +```typescript +export declare enum ChronoField +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| DAY\_OF\_WEEK | 2 | The day of the week, from Monday (1) to Sunday (7). | +| MONTH\_OF\_YEAR | 1 | The month of year, from January (1) to December (12). | + diff --git a/docs/md/nifty-tou.chronofieldparser._constructor_.md b/docs/md/nifty-tou.chronofieldparser._constructor_.md new file mode 100644 index 0000000..c1ba7b0 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldparser._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldParser](./nifty-tou.chronofieldparser.md) > [(constructor)](./nifty-tou.chronofieldparser._constructor_.md) + +## ChronoFieldParser.(constructor) + +Constructor. + +**Signature:** + +```typescript +constructor(locale: string); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| locale | string | the desired locale | + diff --git a/docs/md/nifty-tou.chronofieldparser.forlocale.md b/docs/md/nifty-tou.chronofieldparser.forlocale.md new file mode 100644 index 0000000..b4d720c --- /dev/null +++ b/docs/md/nifty-tou.chronofieldparser.forlocale.md @@ -0,0 +1,28 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldParser](./nifty-tou.chronofieldparser.md) > [forLocale](./nifty-tou.chronofieldparser.forlocale.md) + +## ChronoFieldParser.forLocale() method + +Get a parser for a given locale. + +This method will instantiate and cache parsers, returning cached instances if already avaialble. + +**Signature:** + +```typescript +static forLocale(locale: string): ChronoFieldParser; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| locale | string | the locale of the parser to get | + +**Returns:** + +[ChronoFieldParser](./nifty-tou.chronofieldparser.md) + +the parser + diff --git a/docs/md/nifty-tou.chronofieldparser.locale.md b/docs/md/nifty-tou.chronofieldparser.locale.md new file mode 100644 index 0000000..755e4c9 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldparser.locale.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldParser](./nifty-tou.chronofieldparser.md) > [locale](./nifty-tou.chronofieldparser.locale.md) + +## ChronoFieldParser.locale property + +Get the locale. + +**Signature:** + +```typescript +get locale(): string; +``` diff --git a/docs/md/nifty-tou.chronofieldparser.md b/docs/md/nifty-tou.chronofieldparser.md new file mode 100644 index 0000000..bd6a3d4 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldparser.md @@ -0,0 +1,34 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldParser](./nifty-tou.chronofieldparser.md) + +## ChronoFieldParser class + +Class to parse locale-specific chronological field names of the Gregorian calendar. + +**Signature:** + +```typescript +export declare class ChronoFieldParser +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(locale)](./nifty-tou.chronofieldparser._constructor_.md) | | Constructor. | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [locale](./nifty-tou.chronofieldparser.locale.md) | readonly | string | Get the locale. | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [forLocale(locale)](./nifty-tou.chronofieldparser.forlocale.md) | static |

Get a parser for a given locale.

This method will instantiate and cache parsers, returning cached instances if already avaialble.

| +| [parse(field, value)](./nifty-tou.chronofieldparser.parse.md) | | Parse a field value. | +| [parseRange(field, value)](./nifty-tou.chronofieldparser.parserange.md) | |

Parse a chronological field range string.

A "range string" is a string formatted like VALUE - VALUE. Whitespace is ignored, and the - VALUE portion can be omitted for a singleton range. For example, in the en-US locale, Jan-Dec would be parsed as [1..12].

| + diff --git a/docs/md/nifty-tou.chronofieldparser.parse.md b/docs/md/nifty-tou.chronofieldparser.parse.md new file mode 100644 index 0000000..1e4e153 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldparser.parse.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldParser](./nifty-tou.chronofieldparser.md) > [parse](./nifty-tou.chronofieldparser.parse.md) + +## ChronoFieldParser.parse() method + +Parse a field value. + +**Signature:** + +```typescript +parse(field: ChronoField, value: string): ChronoFieldValue; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| field | [ChronoField](./nifty-tou.chronofield.md) | the field to treat val as | +| value | string | the field value to parse | + +**Returns:** + +[ChronoFieldValue](./nifty-tou.chronofieldvalue.md) + +the associated field value, or undefined if not found + diff --git a/docs/md/nifty-tou.chronofieldparser.parserange.md b/docs/md/nifty-tou.chronofieldparser.parserange.md new file mode 100644 index 0000000..8b8ff8a --- /dev/null +++ b/docs/md/nifty-tou.chronofieldparser.parserange.md @@ -0,0 +1,40 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldParser](./nifty-tou.chronofieldparser.md) > [parseRange](./nifty-tou.chronofieldparser.parserange.md) + +## ChronoFieldParser.parseRange() method + +Parse a chronological field range string. + +A "range string" is a string formatted like `VALUE - VALUE`. Whitespace is ignored, and the `- VALUE` portion can be omitted for a singleton range. For example, in the `en-US` locale, `Jan-Dec` would be parsed as `[1..12]`. + +**Signature:** + +```typescript +parseRange(field: ChronoField, value: string): IntRange; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| field | [ChronoField](./nifty-tou.chronofield.md) | the field to parse the range values as | +| value | string | the range string to parse | + +**Returns:** + +[IntRange](./nifty-tou.intrange.md) + +the parsed range, or `undefined` if not parsable as a range + +## Example + +Here are some basic examples: + +```ts +const p = ChronoFieldParser.forLocale('en-US'); +p.parseRange(ChronoField.MONTH_OF_YEAR, 'Jan-Dec'); // [1..12] +p.parseRange(ChronoField.MONTH_OF_YEAR, '4-6'); // [4..6] +p.parseRange(ChronoField.DAY_OF_WEEK, 'Wednesday'); // [3..3] +``` + diff --git a/docs/md/nifty-tou.chronofieldvalue._constructor_.md b/docs/md/nifty-tou.chronofieldvalue._constructor_.md new file mode 100644 index 0000000..0658a2b --- /dev/null +++ b/docs/md/nifty-tou.chronofieldvalue._constructor_.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) > [(constructor)](./nifty-tou.chronofieldvalue._constructor_.md) + +## ChronoFieldValue.(constructor) + +Constructor. + +**Signature:** + +```typescript +constructor(field: ChronoField, names: string[], value: number); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| field | [ChronoField](./nifty-tou.chronofield.md) | the chronological field | +| names | string\[\] | the value names, from longest to shortest | +| value | number | the value | + diff --git a/docs/md/nifty-tou.chronofieldvalue.field.md b/docs/md/nifty-tou.chronofieldvalue.field.md new file mode 100644 index 0000000..b0e7c26 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldvalue.field.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) > [field](./nifty-tou.chronofieldvalue.field.md) + +## ChronoFieldValue.field property + +Get the field. + +**Signature:** + +```typescript +get field(): ChronoField; +``` diff --git a/docs/md/nifty-tou.chronofieldvalue.md b/docs/md/nifty-tou.chronofieldvalue.md new file mode 100644 index 0000000..1597e2e --- /dev/null +++ b/docs/md/nifty-tou.chronofieldvalue.md @@ -0,0 +1,29 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) + +## ChronoFieldValue class + +A chronological field value. + +**Signature:** + +```typescript +export declare class ChronoFieldValue +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(field, names, value)](./nifty-tou.chronofieldvalue._constructor_.md) | | Constructor. | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [field](./nifty-tou.chronofieldvalue.field.md) | readonly | [ChronoField](./nifty-tou.chronofield.md) | Get the field. | +| [name](./nifty-tou.chronofieldvalue.name.md) | readonly | string | Get the full name. | +| [shortName](./nifty-tou.chronofieldvalue.shortname.md) | readonly | string | Get the short name. | +| [value](./nifty-tou.chronofieldvalue.value.md) | readonly | number | Get the value. | + diff --git a/docs/md/nifty-tou.chronofieldvalue.name.md b/docs/md/nifty-tou.chronofieldvalue.name.md new file mode 100644 index 0000000..a81b944 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldvalue.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) > [name](./nifty-tou.chronofieldvalue.name.md) + +## ChronoFieldValue.name property + +Get the full name. + +**Signature:** + +```typescript +get name(): string; +``` diff --git a/docs/md/nifty-tou.chronofieldvalue.shortname.md b/docs/md/nifty-tou.chronofieldvalue.shortname.md new file mode 100644 index 0000000..8d818c4 --- /dev/null +++ b/docs/md/nifty-tou.chronofieldvalue.shortname.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) > [shortName](./nifty-tou.chronofieldvalue.shortname.md) + +## ChronoFieldValue.shortName property + +Get the short name. + +**Signature:** + +```typescript +get shortName(): string; +``` diff --git a/docs/md/nifty-tou.chronofieldvalue.value.md b/docs/md/nifty-tou.chronofieldvalue.value.md new file mode 100644 index 0000000..205dc4f --- /dev/null +++ b/docs/md/nifty-tou.chronofieldvalue.value.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) > [value](./nifty-tou.chronofieldvalue.value.md) + +## ChronoFieldValue.value property + +Get the value. + +**Signature:** + +```typescript +get value(): number; +``` diff --git a/docs/md/nifty-tou.intrange.md b/docs/md/nifty-tou.intrange.md index 0c1a7f9..2341684 100644 --- a/docs/md/nifty-tou.intrange.md +++ b/docs/md/nifty-tou.intrange.md @@ -42,6 +42,7 @@ export default class IntRange | [intersects(o)](./nifty-tou.intrange.intersects.md) | | Test if this range intersects with a given range. | | [mergeWith(o)](./nifty-tou.intrange.mergewith.md) | | Merge this range with a given range, returning the merged range. | | [of(value)](./nifty-tou.intrange.of.md) | static | Create a singleton range, where the minimum and maximum are equal. | +| [parseRange(array, bounds)](./nifty-tou.intrange.parserange.md) | static | Parse a range array into an IntRange. | | [rangeOf(min, max)](./nifty-tou.intrange.rangeof.md) | static | Create a range. | | [toString()](./nifty-tou.intrange.tostring.md) | | Get a string representation. | diff --git a/docs/md/nifty-tou.intrange.parserange.md b/docs/md/nifty-tou.intrange.parserange.md new file mode 100644 index 0000000..95e8542 --- /dev/null +++ b/docs/md/nifty-tou.intrange.parserange.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [IntRange](./nifty-tou.intrange.md) > [parseRange](./nifty-tou.intrange.parserange.md) + +## IntRange.parseRange() method + +Parse a range array into an `IntRange`. + +**Signature:** + +```typescript +static parseRange(array: string[], bounds?: IntRange): IntRange; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| array | string\[\] | | +| bounds | [IntRange](./nifty-tou.intrange.md) | _(Optional)_ the optional bounds (inclusive) to enforce; if the parsed range | + +**Returns:** + +[IntRange](./nifty-tou.intrange.md) + +the parsed range, or `undefined` if a range could not be parsed or extends beyond the given `bounds` then `undefined` will be returned + diff --git a/docs/md/nifty-tou.md b/docs/md/nifty-tou.md index c47eff5..f6dcc19 100644 --- a/docs/md/nifty-tou.md +++ b/docs/md/nifty-tou.md @@ -8,10 +8,19 @@ | Class | Description | | --- | --- | +| [ChronoFieldParser](./nifty-tou.chronofieldparser.md) | Class to parse locale-specific chronological field names of the Gregorian calendar. | +| [ChronoFieldValue](./nifty-tou.chronofieldvalue.md) | A chronological field value. | | [IntRange](./nifty-tou.intrange.md) | An immutable number range with min/max values. | +| [NumberParser](./nifty-tou.numberparser.md) |

A locale-specific number parser.

Adapted from Mike Bostock's https://observablehq.com/@mbostock/localized-number-parsing

| | [TariffRate](./nifty-tou.tariffrate.md) |

An identifiable tariff rate.

Note that amount is stored as a string to maintain precision.

| | [TemporalRangesTariff](./nifty-tou.temporalrangestariff.md) |

A tariff with time-based range rules.

The rules associated with this tariff are represented by a set of date ranges that serve as the constraints that must be satisfied by a given date for the rule to apply.

| +## Enumerations + +| Enumeration | Description | +| --- | --- | +| [ChronoField](./nifty-tou.chronofield.md) | An enumeration of supported chronological fields of the Gregorian calendar. | + ## Namespaces | Namespace | Description | diff --git a/docs/md/nifty-tou.numberparser._constructor_.md b/docs/md/nifty-tou.numberparser._constructor_.md new file mode 100644 index 0000000..032dec3 --- /dev/null +++ b/docs/md/nifty-tou.numberparser._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [NumberParser](./nifty-tou.numberparser.md) > [(constructor)](./nifty-tou.numberparser._constructor_.md) + +## NumberParser.(constructor) + +Constructor. + +**Signature:** + +```typescript +constructor(locale: string); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| locale | string | the desired locale | + diff --git a/docs/md/nifty-tou.numberparser.locale.md b/docs/md/nifty-tou.numberparser.locale.md new file mode 100644 index 0000000..b834d19 --- /dev/null +++ b/docs/md/nifty-tou.numberparser.locale.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [NumberParser](./nifty-tou.numberparser.md) > [locale](./nifty-tou.numberparser.locale.md) + +## NumberParser.locale property + +Get the locale. + +**Signature:** + +```typescript +get locale(): string; +``` diff --git a/docs/md/nifty-tou.numberparser.md b/docs/md/nifty-tou.numberparser.md new file mode 100644 index 0000000..463c09c --- /dev/null +++ b/docs/md/nifty-tou.numberparser.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [NumberParser](./nifty-tou.numberparser.md) + +## NumberParser class + +A locale-specific number parser. + +Adapted from Mike Bostock's https://observablehq.com/@mbostock/localized-number-parsing + +**Signature:** + +```typescript +export default class NumberParser +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(locale)](./nifty-tou.numberparser._constructor_.md) | | Constructor. | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [locale](./nifty-tou.numberparser.locale.md) | readonly | string | Get the locale. | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [norm(s)](./nifty-tou.numberparser.norm.md) | | Normalize a locale-specific number string. | +| [parse(s)](./nifty-tou.numberparser.parse.md) | | Parse a locale-specific number string. | + diff --git a/docs/md/nifty-tou.numberparser.norm.md b/docs/md/nifty-tou.numberparser.norm.md new file mode 100644 index 0000000..cef2ecf --- /dev/null +++ b/docs/md/nifty-tou.numberparser.norm.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [NumberParser](./nifty-tou.numberparser.md) > [norm](./nifty-tou.numberparser.norm.md) + +## NumberParser.norm() method + +Normalize a locale-specific number string. + +**Signature:** + +```typescript +norm(s: string): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| s | string | the number string to parse in this instance's locale | + +**Returns:** + +string + +the number string normalized into a JavaScript number string + diff --git a/docs/md/nifty-tou.numberparser.parse.md b/docs/md/nifty-tou.numberparser.parse.md new file mode 100644 index 0000000..c393990 --- /dev/null +++ b/docs/md/nifty-tou.numberparser.parse.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [NumberParser](./nifty-tou.numberparser.md) > [parse](./nifty-tou.numberparser.parse.md) + +## NumberParser.parse() method + +Parse a locale-specific number string. + +**Signature:** + +```typescript +parse(s: string): number; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| s | string | the number string to parse in this instance's locale | + +**Returns:** + +number + +the parsed number, or `undefined` + diff --git a/docs/md/nifty-tou.utils.md b/docs/md/nifty-tou.utils.md index 056fea1..8625cc9 100644 --- a/docs/md/nifty-tou.utils.md +++ b/docs/md/nifty-tou.utils.md @@ -12,4 +12,5 @@ | [optional(arg, name, type)](./nifty-tou.utils.optional.md) | Verify that a variable is undefined or of a given type. | | [prefix(prefix, s)](./nifty-tou.utils.prefix.md) |

Prefix an optional string.

If prefix or s have no length then s is returned as-is. Otherwise the strings are concatenated.

| | [required(arg, name, type)](./nifty-tou.utils.required.md) | Verify that a variable is defined and optionally of a given type. | +| [splitRange(range)](./nifty-tou.utils.splitrange.md) |

Split a string based on a range delimiter pattern.

A range delimited string has the pattern VALUE - VALUE, where whitespace at the start, around the - delimiter, and at the end is not significant.

| diff --git a/docs/md/nifty-tou.utils.splitrange.md b/docs/md/nifty-tou.utils.splitrange.md new file mode 100644 index 0000000..7d3e1e5 --- /dev/null +++ b/docs/md/nifty-tou.utils.splitrange.md @@ -0,0 +1,28 @@ + + +[Home](./index.md) > [nifty-tou](./nifty-tou.md) > [Utils](./nifty-tou.utils.md) > [splitRange](./nifty-tou.utils.splitrange.md) + +## Utils.splitRange() function + +Split a string based on a range delimiter pattern. + +A range delimited string has the pattern `VALUE - VALUE`, where whitespace at the start, around the `-` delimiter, and at the end is not significant. + +**Signature:** + +```typescript +export declare function splitRange(range: string): string[]; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| range | string | the range string to split into components, whitespace trimmed | + +**Returns:** + +string\[\] + +the split range, of length 1 or 2, or `undefined` if `range` is undefined + diff --git a/etc/nifty-tou.api.md b/etc/nifty-tou.api.md index 62328be..37ebf47 100644 --- a/etc/nifty-tou.api.md +++ b/etc/nifty-tou.api.md @@ -7,6 +7,30 @@ // @public function cconcat(s1?: string, s2?: string): string; +// @public +export enum ChronoField { + DAY_OF_WEEK = 2, + MONTH_OF_YEAR = 1 +} + +// @public +export class ChronoFieldParser { + constructor(locale: string); + static forLocale(locale: string): ChronoFieldParser; + get locale(): string; + parse(field: ChronoField, value: string): ChronoFieldValue; + parseRange(field: ChronoField, value: string): IntRange; +} + +// @public +export class ChronoFieldValue { + constructor(field: ChronoField, names: string[], value: number); + get field(): ChronoField; + get name(): string; + get shortName(): string; + get value(): number; +} + // @public export class IntRange { constructor(min: number, max: number); @@ -25,10 +49,19 @@ export class IntRange { mergeWith(o: IntRange): IntRange; get min(): number; static of(value: number): IntRange; + static parseRange(array: string[], bounds?: IntRange): IntRange; static rangeOf(min: number, max: number): IntRange; toString(): string; } +// @public +export class NumberParser { + constructor(locale: string); + get locale(): string; + norm(s: string): string; + parse(s: string): number; +} + // @public function optional(arg: T, name: string, type?: new (...args: any[]) => any): T; @@ -38,6 +71,9 @@ function prefix(prefix?: string, s?: string): string; // @public function required(arg: T, name: string, type?: new (...args: any[]) => any): T; +// @public +function splitRange(range: string): string[]; + // @public export class TariffRate { constructor(id: string, amount: string, description?: string); @@ -69,7 +105,8 @@ declare namespace Utils { cconcat, optional, prefix, - required + required, + splitRange } } export { Utils } diff --git a/lib/main/ChronoFieldParser.d.ts b/lib/main/ChronoFieldParser.d.ts new file mode 100644 index 0000000..e6e0652 --- /dev/null +++ b/lib/main/ChronoFieldParser.d.ts @@ -0,0 +1,93 @@ +import IntRange from "./IntRange.js"; +/** + * An enumeration of supported chronological fields of the Gregorian calendar. + * @public + */ +export declare enum ChronoField { + /** The month of year, from January (1) to December (12). */ + MONTH_OF_YEAR = 1, + /** The day of the week, from Monday (1) to Sunday (7). */ + DAY_OF_WEEK = 2 +} +/** + * A chronological field value. + * @public + */ +export declare class ChronoFieldValue { + #private; + /** + * Constructor. + * + * @param field - the chronological field + * @param names - the value names, from longest to shortest + * @param value - the value + */ + constructor(field: ChronoField, names: string[], value: number); + /** Get the field. */ + get field(): ChronoField; + /** Get the full name. */ + get name(): string; + /** Get the short name. */ + get shortName(): string; + /** Get the value. */ + get value(): number; +} +/** + * Class to parse locale-specific chronological field names of the Gregorian calendar. + * @public + */ +export declare class ChronoFieldParser { + #private; + /** + * Get a parser for a given locale. + * + * This method will instantiate and cache parsers, returning cached instances + * if already avaialble. + * + * @param locale - the locale of the parser to get + * @returns the parser + */ + static forLocale(locale: string): ChronoFieldParser; + /** + * Constructor. + * + * @param locale - the desired locale + */ + constructor(locale: string); + /** + * Get the locale. + */ + get locale(): string; + /** + * Parse a field value. + * + * @param field - the field to treat `val` as + * @param value - the field value to parse + * @returns the associated field value, or undefined if not found + */ + parse(field: ChronoField, value: string): ChronoFieldValue; + /** + * Parse a chronological field range string. + * + * A "range string" is a string formatted like `VALUE - VALUE`. Whitespace + * is ignored, and the `- VALUE` portion can be omitted for a singleton + * range. For example, in the `en-US` locale, `Jan-Dec` would be parsed as + * `[1..12]`. + * + * @example + * Here are some basic examples: + * + * ```ts + * const p = ChronoFieldParser.forLocale('en-US'); + * p.parseRange(ChronoField.MONTH_OF_YEAR, 'Jan-Dec'); // [1..12] + * p.parseRange(ChronoField.MONTH_OF_YEAR, '4-6'); // [4..6] + * p.parseRange(ChronoField.DAY_OF_WEEK, 'Wednesday'); // [3..3] + * ``` + * + * @param field - the field to parse the range values as + * @param value - the range string to parse + * @returns the parsed range, or `undefined` if not parsable as a range + */ + parseRange(field: ChronoField, value: string): IntRange; +} +//# sourceMappingURL=ChronoFieldParser.d.ts.map \ No newline at end of file diff --git a/lib/main/ChronoFieldParser.d.ts.map b/lib/main/ChronoFieldParser.d.ts.map new file mode 100644 index 0000000..ceb5ed4 --- /dev/null +++ b/lib/main/ChronoFieldParser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ChronoFieldParser.d.ts","sourceRoot":"","sources":["../../src/main/ChronoFieldParser.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAGrC;;;GAGG;AACH,oBAAY,WAAW;IACtB,4DAA4D;IAC5D,aAAa,IAAI;IAEjB,0DAA0D;IAC1D,WAAW,IAAI;CACf;AAED;;;GAGG;AACH,qBAAa,gBAAgB;;IAK5B;;;;;;OAMG;gBACS,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM;IAS9D,qBAAqB;IACrB,IAAI,KAAK,IAAI,WAAW,CAEvB;IAED,yBAAyB;IACzB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0BAA0B;IAC1B,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,qBAAqB;IACrB,IAAI,KAAK,IAAI,MAAM,CAElB;CACD;AASD;;;GAGG;AACH,qBAAa,iBAAiB;;IAO7B;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM;IAS/B;;;;OAIG;gBACS,MAAM,EAAE,MAAM;IAQ1B;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IA+FD;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB;IAY1D;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;CAiBvD"} \ No newline at end of file diff --git a/lib/main/ChronoFieldParser.js b/lib/main/ChronoFieldParser.js new file mode 100644 index 0000000..6d8a1c4 --- /dev/null +++ b/lib/main/ChronoFieldParser.js @@ -0,0 +1,228 @@ +var _a; +import IntRange from "./IntRange.js"; +import { splitRange } from "./utils.js"; +/** + * An enumeration of supported chronological fields of the Gregorian calendar. + * @public + */ +export var ChronoField; +(function (ChronoField) { + /** The month of year, from January (1) to December (12). */ + ChronoField[ChronoField["MONTH_OF_YEAR"] = 1] = "MONTH_OF_YEAR"; + /** The day of the week, from Monday (1) to Sunday (7). */ + ChronoField[ChronoField["DAY_OF_WEEK"] = 2] = "DAY_OF_WEEK"; +})(ChronoField || (ChronoField = {})); +/** + * A chronological field value. + * @public + */ +export class ChronoFieldValue { + #field; + #names; + #value; + /** + * Constructor. + * + * @param field - the chronological field + * @param names - the value names, from longest to shortest + * @param value - the value + */ + constructor(field, names, value) { + this.#field = field; + this.#names = names; + this.#value = value; + if (!names || names.length < 1) { + throw new TypeError(`The names array must must not be empty.`); + } + } + /** Get the field. */ + get field() { + return this.#field; + } + /** Get the full name. */ + get name() { + return this.#names[0]; + } + /** Get the short name. */ + get shortName() { + return this.#names.length > 1 ? this.#names[1] : this.#names[0]; + } + /** Get the value. */ + get value() { + return this.#value; + } +} +// a cache of parser instance, for locale keys +const PARSER_CACHE = new Map(); +const BOUNDS = new Map(); +BOUNDS.set(ChronoField.MONTH_OF_YEAR, new IntRange(1, 12)); +BOUNDS.set(ChronoField.DAY_OF_WEEK, new IntRange(1, 7)); +/** + * Class to parse locale-specific chronological field names of the Gregorian calendar. + * @public + */ +export class ChronoFieldParser { + #locale; + // note the string keys in these maps are locale lower-case values to support + // case-insensitive matching + #values; + /** + * Get a parser for a given locale. + * + * This method will instantiate and cache parsers, returning cached instances + * if already avaialble. + * + * @param locale - the locale of the parser to get + * @returns the parser + */ + static forLocale(locale) { + let p = PARSER_CACHE.get(locale); + if (!p) { + p = new _a(locale); + PARSER_CACHE.set(locale, p); + } + return p; + } + /** + * Constructor. + * + * @param locale - the desired locale + */ + constructor(locale) { + this.#locale = locale; + this.#values = new Map(); + this.#computeMonths(locale); + this.#computeWeekdays(locale); + } + /** + * Get the locale. + */ + get locale() { + return this.#locale; + } + /** + * Compute a set of keys and names of a date field. + * + * @param date - the date to use for field formatting + * @param names - the array to populate with field names, in the order of the given `formats` + * @param formats - the list of formats to apply to date to generate field names + * @returns array of date key names + */ + static #computeKeysAndNames(date, names, ...formats) { + const keys = []; + for (const fmt of formats) { + // generate name and remove all punctuation, e.g. some short names include a period + const name = fmt.format(date).replace(/\p{P}/gu, ""); + names.splice(names.length, 0, name); + keys.splice(keys.length, 0, name); + // generate a key version with diacritic characters replaced with non-accented version + // e.g. replace é with e + const norm = name.normalize("NFD").replace(/\p{Diacritic}/gu, ""); + if (norm !== name) { + keys.splice(keys.length, 0, norm); + } + } + return keys; + } + #computeMonths(locale) { + const intlFull = new Intl.DateTimeFormat(locale, { + month: "long", + timeZone: "UTC", + }); + const intlShort = new Intl.DateTimeFormat(locale, { + month: "short", + timeZone: "UTC", + }); + const values = new Map(); + for (let i = 0; i < 12; i += 1) { + const date = new Date(Date.UTC(2024, i, 1)); + const val = i + 1; + const names = []; + const keys = _a.#computeKeysAndNames(date, names, intlFull, intlShort); + const value = new ChronoFieldValue(ChronoField.MONTH_OF_YEAR, names, val); + for (const key of keys) { + values.set(key.toLocaleLowerCase(locale), value); + } + } + this.#values.set(ChronoField.MONTH_OF_YEAR, values); + } + #computeWeekdays(locale) { + const intlFull = new Intl.DateTimeFormat(locale, { + weekday: "long", + timeZone: "UTC", + }); + const intlShort = new Intl.DateTimeFormat(locale, { + weekday: "short", + timeZone: "UTC", + }); + const values = new Map(); + for (let i = 1; i <= 7; i += 1) { + const date = new Date(Date.UTC(2024, 0, i)); // 2024-01-01 is a Monday + const names = []; + const keys = _a.#computeKeysAndNames(date, names, intlFull, intlShort); + const value = new ChronoFieldValue(ChronoField.DAY_OF_WEEK, names, i); + for (const key of keys) { + values.set(key.toLocaleLowerCase(locale), value); + } + } + this.#values.set(ChronoField.DAY_OF_WEEK, values); + } + /** + * Parse a field value. + * + * @param field - the field to treat `val` as + * @param value - the field value to parse + * @returns the associated field value, or undefined if not found + */ + parse(field, value) { + if (!value) { + return undefined; + } + const values = this.#values.get(field); + if (!values) { + throw new TypeError(`Unsupported ChronoField [${field}].`); + } + const lcValue = value.toLocaleLowerCase(this.#locale); + return values.get(lcValue); + } + /** + * Parse a chronological field range string. + * + * A "range string" is a string formatted like `VALUE - VALUE`. Whitespace + * is ignored, and the `- VALUE` portion can be omitted for a singleton + * range. For example, in the `en-US` locale, `Jan-Dec` would be parsed as + * `[1..12]`. + * + * @example + * Here are some basic examples: + * + * ```ts + * const p = ChronoFieldParser.forLocale('en-US'); + * p.parseRange(ChronoField.MONTH_OF_YEAR, 'Jan-Dec'); // [1..12] + * p.parseRange(ChronoField.MONTH_OF_YEAR, '4-6'); // [4..6] + * p.parseRange(ChronoField.DAY_OF_WEEK, 'Wednesday'); // [3..3] + * ``` + * + * @param field - the field to parse the range values as + * @param value - the range string to parse + * @returns the parsed range, or `undefined` if not parsable as a range + */ + parseRange(field, value) { + if (!field) { + return undefined; + } + const a = splitRange(value); + if (!a) { + return undefined; + } + const l = this.parse(field, a[0]); + const r = a.length > 1 ? this.parse(field, a[1]) : l; + if (l && r) { + return new IntRange(l.value, r.value); + } + // try as numbers, constrained by field bounds + return IntRange.parseRange(a, BOUNDS.get(field)); + } +} +_a = ChronoFieldParser; +//# sourceMappingURL=ChronoFieldParser.js.map \ No newline at end of file diff --git a/lib/main/ChronoFieldParser.js.map b/lib/main/ChronoFieldParser.js.map new file mode 100644 index 0000000..ec36069 --- /dev/null +++ b/lib/main/ChronoFieldParser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ChronoFieldParser.js","sourceRoot":"","sources":["../../src/main/ChronoFieldParser.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/lib/main/IntRange.d.ts b/lib/main/IntRange.d.ts index 5d2c5db..d8b7014 100644 --- a/lib/main/IntRange.d.ts +++ b/lib/main/IntRange.d.ts @@ -16,6 +16,15 @@ export default class IntRange { * Create a range. */ static rangeOf(min: number, max: number): IntRange; + /** + * Parse a range array into an `IntRange`. + * + * @param value - the range array to parse; can have 1 or 2 elements; all elements must have number values + * @param bounds - the optional bounds (inclusive) to enforce; if the parsed range + * @returns the parsed range, or `undefined` if a range could not be parsed or extends + * beyond the given `bounds` then `undefined` will be returned + */ + static parseRange(array: string[], bounds?: IntRange): IntRange; /** * Get the minimum value. */ diff --git a/lib/main/IntRange.d.ts.map b/lib/main/IntRange.d.ts.map index 11dca10..0a5d63f 100644 --- a/lib/main/IntRange.d.ts.map +++ b/lib/main/IntRange.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"IntRange.d.ts","sourceRoot":"","sources":["../../src/main/IntRange.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAI5B;;OAEG;gBACS,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAKpC;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;IAIlC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ;IAIlD;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAOhC;;;;;;OAMG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI9C;;;;;OAKG;IACH,aAAa,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAInC;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAOhC;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAIhC;;;;;;;;OAQG;IACH,YAAY,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAQlC;;;;;OAKG;IACH,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ;IAahC;;;;;;;OAOG;IACH,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM;IAI9B;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAUzB;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM;CAGvD"} \ No newline at end of file +{"version":3,"file":"IntRange.d.ts","sourceRoot":"","sources":["../../src/main/IntRange.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAI5B;;OAEG;gBACS,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAKpC;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;IAIlC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ;IAIlD;;;;;;;OAOG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ;IAgB/D;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAOhC;;;;;;OAMG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI9C;;;;;OAKG;IACH,aAAa,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAInC;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAOhC;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAIhC;;;;;;;;OAQG;IACH,YAAY,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAQlC;;;;;OAKG;IACH,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ;IAahC;;;;;;;OAOG;IACH,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM;IAI9B;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAUzB;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM;CAGvD"} \ No newline at end of file diff --git a/lib/main/IntRange.js b/lib/main/IntRange.js index 6764a79..ab7d083 100644 --- a/lib/main/IntRange.js +++ b/lib/main/IntRange.js @@ -24,6 +24,29 @@ export default class IntRange { static rangeOf(min, max) { return new IntRange(min, max); } + /** + * Parse a range array into an `IntRange`. + * + * @param value - the range array to parse; can have 1 or 2 elements; all elements must have number values + * @param bounds - the optional bounds (inclusive) to enforce; if the parsed range + * @returns the parsed range, or `undefined` if a range could not be parsed or extends + * beyond the given `bounds` then `undefined` will be returned + */ + static parseRange(array, bounds) { + if (!(array && array.length)) { + return undefined; + } + const n1 = +array[0]; + const n2 = array.length > 1 ? +array[1] : n1; + if (!Number.isNaN(n1) && !Number.isNaN(n2)) { + const r = new IntRange(n1, n2); + // validate range within given bounds + if (!bounds || (r.min >= bounds.min && r.max <= bounds.max)) { + return r; + } + } + return undefined; + } /** * Get the minimum value. */ diff --git a/lib/main/IntRange.js.map b/lib/main/IntRange.js.map index 8e5f0d0..9a84685 100644 --- a/lib/main/IntRange.js.map +++ b/lib/main/IntRange.js.map @@ -1 +1 @@ -{"version":3,"file":"IntRange.js","sourceRoot":"","sources":["../../src/main/IntRange.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC5B,IAAI,CAAS;IACb,IAAI,CAAS;IAEb;;OAEG;IACH,YAAY,GAAW,EAAE,GAAW;QACnC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,KAAa;QACtB,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAW,EAAE,GAAW;QACtC,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAI,GAAG;QACN,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,IAAI,GAAG;QACN,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAa;QACrB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;YAC1C,OAAO,KAAK,CAAC;SACb;QACD,OAAO,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,GAAW,EAAE,GAAW;QACnC,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,CAAW;QACxB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,CAAW;QACrB,OAAO,CACN,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC;YAC1C,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAC1C,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,CAAW;QACrB,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC;IAC3D,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,CAAW;QACvB,OAAO,CACN,CAAC,IAAI,IAAI;YACT,CAAC,KAAK,SAAS;YACf,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAC1C,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,CAAW;QACpB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,0BAA0B,CAAC,EAAE,CAAC,CAAC;SAC/D;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAChD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAChD,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YACxC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG;gBAC5B,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,CAAW;QACpB,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,GAAQ;QACd,IAAI,IAAI,KAAK,GAAG,EAAE;YACjB,OAAO,IAAI,CAAC;SACZ;QACD,IAAI,CAAC,CAAC,GAAG,YAAY,QAAQ,CAAC,EAAE;YAC/B,OAAO,KAAK,CAAC;SACb;QACD,OAAO,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC;IACvC,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,IAAc,EAAE,CAAW;QAC7C,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAClD,CAAC;CACD"} \ No newline at end of file +{"version":3,"file":"IntRange.js","sourceRoot":"","sources":["../../src/main/IntRange.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/lib/main/NumberParser.d.ts b/lib/main/NumberParser.d.ts new file mode 100644 index 0000000..b2213fd --- /dev/null +++ b/lib/main/NumberParser.d.ts @@ -0,0 +1,32 @@ +/** + * A locale-specific number parser. + * + * Adapted from Mike Bostock's https://observablehq.com/\@mbostock/localized-number-parsing + * @public + */ +export default class NumberParser { + #private; + /** + * Constructor. + * + * @param locale - the desired locale + */ + constructor(locale: string); + /** Get the locale. */ + get locale(): string; + /** + * Normalize a locale-specific number string. + * + * @param s - the number string to parse in this instance's locale + * @returns the number string normalized into a JavaScript number string + */ + norm(s: string): string; + /** + * Parse a locale-specific number string. + * + * @param s - the number string to parse in this instance's locale + * @returns the parsed number, or `undefined` + */ + parse(s: string): number; +} +//# sourceMappingURL=NumberParser.d.ts.map \ No newline at end of file diff --git a/lib/main/NumberParser.d.ts.map b/lib/main/NumberParser.d.ts.map new file mode 100644 index 0000000..66bee0d --- /dev/null +++ b/lib/main/NumberParser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"NumberParser.d.ts","sourceRoot":"","sources":["../../src/main/NumberParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;;IAOhC;;;;OAIG;gBACS,MAAM,EAAE,MAAM;IAsB1B,sBAAsB;IACtB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;;OAKG;IACH,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAavB;;;;;OAKG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAIxB"} \ No newline at end of file diff --git a/lib/main/NumberParser.js b/lib/main/NumberParser.js new file mode 100644 index 0000000..f1384d0 --- /dev/null +++ b/lib/main/NumberParser.js @@ -0,0 +1,63 @@ +/** + * A locale-specific number parser. + * + * Adapted from Mike Bostock's https://observablehq.com/\@mbostock/localized-number-parsing + * @public + */ +export default class NumberParser { + #locale; + #group; + #decimal; + #numeral; + #index; + /** + * Constructor. + * + * @param locale - the desired locale + */ + constructor(locale) { + const parts = new Intl.NumberFormat(locale).formatToParts(12345.6); + const numerals = [ + ...new Intl.NumberFormat(locale, { useGrouping: false }).format(9876543210), + ].reverse(); + const index = new Map(numerals.map((d, i) => [d, i.toString()])); + this.#locale = locale; + this.#group = new RegExp(`[${parts.find((d) => d.type === "group").value}]`, "g"); + this.#decimal = new RegExp(`[${parts.find((d) => d.type === "decimal").value}]`); + this.#numeral = new RegExp(`[${numerals.join("")}]`, "g"); + this.#index = (d) => index.get(d); + } + /** Get the locale. */ + get locale() { + return this.#locale; + } + /** + * Normalize a locale-specific number string. + * + * @param s - the number string to parse in this instance's locale + * @returns the number string normalized into a JavaScript number string + */ + norm(s) { + if (s === undefined || s === null) { + return undefined; + } + s = s + .trim() + .replaceAll("+", "") + .replace(this.#group, "") + .replace(this.#decimal, ".") + .replace(this.#numeral, this.#index); + return s || undefined; + } + /** + * Parse a locale-specific number string. + * + * @param s - the number string to parse in this instance's locale + * @returns the parsed number, or `undefined` + */ + parse(s) { + s = this.norm(s); + return s ? +s : NaN; + } +} +//# sourceMappingURL=NumberParser.js.map \ No newline at end of file diff --git a/lib/main/NumberParser.js.map b/lib/main/NumberParser.js.map new file mode 100644 index 0000000..fbbb11e --- /dev/null +++ b/lib/main/NumberParser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NumberParser.js","sourceRoot":"","sources":["../../src/main/NumberParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IAChC,OAAO,CAAS;IAChB,MAAM,CAAS;IACf,QAAQ,CAAS;IACjB,QAAQ,CAAS;IACjB,MAAM,CAAwB;IAE9B;;;;OAIG;IACH,YAAY,MAAc;QACzB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG;YAChB,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAC9D,UAAU,CACV;SACD,CAAC,OAAO,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,IAAI,GAAG,CACpB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CACzC,CAAC;QACF,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACvB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,KAAK,GAAG,EAClD,GAAG,CACH,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,MAAM,CACzB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,KAAK,GAAG,CACpD,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,sBAAsB;IACtB,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,CAAS;QACb,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,EAAE;YAClC,OAAO,SAAS,CAAC;SACjB;QACD,CAAC,GAAG,CAAC;aACH,IAAI,EAAE;aACN,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC;aACnB,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;aACxB,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;aAC3B,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,SAAS,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,CAAS;QACd,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACrB,CAAC;CACD"} \ No newline at end of file diff --git a/lib/main/index.d.ts b/lib/main/index.d.ts index 1108665..d86a824 100644 --- a/lib/main/index.d.ts +++ b/lib/main/index.d.ts @@ -1,4 +1,6 @@ +export { ChronoField, ChronoFieldValue, ChronoFieldParser, } from "./ChronoFieldParser.js"; export { default as IntRange } from "./IntRange.js"; +export { default as NumberParser } from "./NumberParser.js"; export { default as TariffRate } from "./TariffRate.js"; export { default as TemporalRangesTariff } from "./TemporalRangesTariff.js"; import * as Utils from "./utils.js"; diff --git a/lib/main/index.d.ts.map b/lib/main/index.d.ts.map index a693d24..18f246d 100644 --- a/lib/main/index.d.ts.map +++ b/lib/main/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,CAAC"} \ No newline at end of file diff --git a/lib/main/index.js b/lib/main/index.js index 22140f7..8853ab1 100644 --- a/lib/main/index.js +++ b/lib/main/index.js @@ -1,4 +1,6 @@ +export { ChronoField, ChronoFieldValue, ChronoFieldParser, } from "./ChronoFieldParser.js"; export { default as IntRange } from "./IntRange.js"; +export { default as NumberParser } from "./NumberParser.js"; export { default as TariffRate } from "./TariffRate.js"; export { default as TemporalRangesTariff } from "./TemporalRangesTariff.js"; import * as Utils from "./utils.js"; diff --git a/lib/main/index.js.map b/lib/main/index.js.map index ceb4a24..033b41a 100644 --- a/lib/main/index.js.map +++ b/lib/main/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,CAAC"} \ No newline at end of file diff --git a/lib/main/utils.d.ts b/lib/main/utils.d.ts index 7bbc13c..8c08b68 100644 --- a/lib/main/utils.d.ts +++ b/lib/main/utils.d.ts @@ -42,4 +42,15 @@ export declare function prefix(prefix?: string, s?: string): string; * @public */ export declare function required(arg: T, name: string, type?: new (...args: any[]) => any): T; +/** + * Split a string based on a range delimiter pattern. + * + * A range delimited string has the pattern `VALUE - VALUE`, where whitespace + * at the start, around the `-` delimiter, and at the end is not significant. + * + * @param range - the range string to split into components, whitespace trimmed + * @returns the split range, of length 1 or 2, or `undefined` if `range` is undefined + * @public + */ +export declare function splitRange(range: string): string[]; //# sourceMappingURL=utils.d.ts.map \ No newline at end of file diff --git a/lib/main/utils.d.ts.map b/lib/main/utils.d.ts.map index f970ae3..7086b5e 100644 --- a/lib/main/utils.d.ts.map +++ b/lib/main/utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/main/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACzB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAChC,CAAC,CAoBH;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1D;AACD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACzB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAChC,CAAC,CAQH"} \ No newline at end of file +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/main/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACzB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAChC,CAAC,CAoBH;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1D;AACD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACzB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAChC,CAAC,CAQH;AAID;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAYlD"} \ No newline at end of file diff --git a/lib/main/utils.js b/lib/main/utils.js index 3c3beeb..4254c81 100644 --- a/lib/main/utils.js +++ b/lib/main/utils.js @@ -77,4 +77,28 @@ export function required(arg, name, type) { } return optional(arg, name, type); } +const RANGE_DELIMITER = /\s*-\s*/; +/** + * Split a string based on a range delimiter pattern. + * + * A range delimited string has the pattern `VALUE - VALUE`, where whitespace + * at the start, around the `-` delimiter, and at the end is not significant. + * + * @param range - the range string to split into components, whitespace trimmed + * @returns the split range, of length 1 or 2, or `undefined` if `range` is undefined + * @public + */ +export function splitRange(range) { + if (!range) { + return undefined; + } + range = range.trim(); + const a = range.split(RANGE_DELIMITER, 2); + for (let i = a.length - 1; i >= 0; i -= 1) { + if (!a[i]) { + a.splice(i, 1); + } + } + return a.length ? a : undefined; +} //# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/lib/main/utils.js.map b/lib/main/utils.js.map index 67114ec..47212a0 100644 --- a/lib/main/utils.js.map +++ b/lib/main/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/main/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAC,EAAW,EAAE,EAAW;IAC/C,IAAI,CAAC,EAAE,EAAE;QACR,OAAO,EAAE,CAAC;KACV;SAAM,IAAI,CAAC,EAAE,EAAE;QACf,OAAO,EAAE,CAAC;KACV;IACD,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACvB,GAAM,EACN,IAAY,EACZ,IAAkC;IAElC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;QACtC,OAAO,GAAG,CAAC;KACX;IACD,IACC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC;QAC5C,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC;QAC5C,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC,CAAC,EAC7D;QACD,MAAM,IAAI,SAAS,CAClB,OAAO,IAAI,uBACV,IAAI,KAAK,MAAM;YACd,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,KAAK,MAAM;gBACjB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,IAAI,CAAC,IACT,GAAG,CACH,CAAC;KACF;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CAAC,MAAe,EAAE,CAAU;IACjD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;QACnB,OAAO,CAAC,CAAC;KACT;IACD,OAAO,MAAM,GAAG,CAAC,CAAC;AACnB,CAAC;AACD;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACvB,GAAM,EACN,IAAY,EACZ,IAAkC;IAElC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;QACtC,MAAM,IAAI,SAAS,CAAC,OAAO,IAAI,0BAA0B,CAAC,CAAC;KAC3D;IACD,IAAI,CAAC,IAAI,EAAE;QACV,OAAO,GAAG,CAAC;KACX;IACD,OAAO,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC"} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/main/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAC,EAAW,EAAE,EAAW;IAC/C,IAAI,CAAC,EAAE,EAAE;QACR,OAAO,EAAE,CAAC;KACV;SAAM,IAAI,CAAC,EAAE,EAAE;QACf,OAAO,EAAE,CAAC;KACV;IACD,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACvB,GAAM,EACN,IAAY,EACZ,IAAkC;IAElC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;QACtC,OAAO,GAAG,CAAC;KACX;IACD,IACC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC;QAC5C,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC;QAC5C,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC,CAAC,EAC7D;QACD,MAAM,IAAI,SAAS,CAClB,OAAO,IAAI,uBACV,IAAI,KAAK,MAAM;YACd,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,KAAK,MAAM;gBACjB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,IAAI,CAAC,IACT,GAAG,CACH,CAAC;KACF;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CAAC,MAAe,EAAE,CAAU;IACjD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;QACnB,OAAO,CAAC,CAAC;KACT;IACD,OAAO,MAAM,GAAG,CAAC,CAAC;AACnB,CAAC;AACD;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACvB,GAAM,EACN,IAAY,EACZ,IAAkC;IAElC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;QACtC,MAAM,IAAI,SAAS,CAAC,OAAO,IAAI,0BAA0B,CAAC,CAAC;KAC3D;IACD,IAAI,CAAC,IAAI,EAAE;QACV,OAAO,GAAG,CAAC;KACX;IACD,OAAO,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,eAAe,GAAW,SAAS,CAAC;AAE1C;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,IAAI,CAAC,KAAK,EAAE;QACX,OAAO,SAAS,CAAC;KACjB;IACD,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACrB,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;QAC1C,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;YACV,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACf;KACD;IACD,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjC,CAAC"} \ No newline at end of file