@sapphire/lexure 1.0.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.
@@ -0,0 +1,378 @@
1
+ import { Option, Result } from '@sapphire/result';
2
+ import type { Parameter } from './lexer/streams/ParameterStream';
3
+ import type { ParserResult } from './parser/ParserResult';
4
+ export declare class ArgumentStream {
5
+ readonly results: ParserResult;
6
+ state: ArgumentStream.State;
7
+ constructor(results: ParserResult);
8
+ /**
9
+ * Whether or not all ordered parameters were used.
10
+ */
11
+ get finished(): boolean;
12
+ /**
13
+ * The amount of ordered parameters.
14
+ */
15
+ get length(): number;
16
+ /**
17
+ * The remaining amount of ordered parameters.
18
+ */
19
+ get remaining(): number;
20
+ /**
21
+ * The amount of ordered parameters that have been used.
22
+ */
23
+ get used(): number;
24
+ /**
25
+ * Retrieves the value of the next unused ordered token.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // Assume args are '1 2 3':
30
+ *
31
+ * console.log(args.single());
32
+ * // Ok { value: '1' }
33
+ *
34
+ * console.log(args.single());
35
+ * // Ok { value: '2' }
36
+ *
37
+ * console.log(args.single());
38
+ * // Ok { value: '3' }
39
+ *
40
+ * console.log(args.single());
41
+ * // None
42
+ * ```
43
+ *
44
+ * @returns The value, if any.
45
+ */
46
+ single(): Option<string>;
47
+ /**
48
+ * Retrieves the value of the next unused ordered token, but only if it could be transformed.
49
+ *
50
+ * @note This does not support asynchronous results, refer to {@link singleMapAsync}.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const parse = (value) => {
55
+ * const number = Number(value);
56
+ * return Number.isNaN(number) ? Option.none : Option.some(number);
57
+ * };
58
+ *
59
+ * // Assume args are '1 2 3':
60
+ *
61
+ * console.log(args.singleMap(parse));
62
+ * // Some { value: 1 }
63
+ *
64
+ * console.log(args.singleMap(parse));
65
+ * // Some { value: 2 }
66
+ *
67
+ * console.log(args.singleMap(parse));
68
+ * // Some { value: 3 }
69
+ *
70
+ * console.log(args.singleMap(parse));
71
+ * // None
72
+ * ```
73
+ *
74
+ * @typeparam T The output type.
75
+ * @param predicate The predicate that determines the parameter's mapped value, or nothing if failed.
76
+ * @param useAnyways Whether to consider the parameter used even if the mapping failed. Defaults to `false`.
77
+ * @returns The mapped value, if any.
78
+ */
79
+ singleMap<T>(predicate: (value: string) => Option<T>, useAnyways?: boolean): Option<T>;
80
+ /**
81
+ * Retrieves the value of the next unused ordered token, but only if it could be transformed.
82
+ *
83
+ * @note This is an asynchronous variant of {@link singleMap}.
84
+ *
85
+ * @typeparam T The output type.
86
+ * @param predicate The predicate that determines the parameter's mapped value, or nothing if failed.
87
+ * @param useAnyways Whether to consider the parameter used even if the mapping failed. Defaults to `false`.
88
+ * @returns The mapped value, if any.
89
+ */
90
+ singleMapAsync<T>(predicate: (value: string) => Promise<Option<T>>, useAnyways?: boolean): Promise<Option<T>>;
91
+ /**
92
+ * Finds and retrieves the next unused parameter and transforms it.
93
+ *
94
+ * @note This is a variant of {@link findMap} that returns the errors on failure.
95
+ * @note This does not support asynchronous results, refer to {@link singleParseAsync}.
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const parse = (value) => {
100
+ * const number = Number(value);
101
+ * return Number.isNaN(number)
102
+ * ? Result.err(`Could not parse ${value} to a number`)
103
+ * : Result.ok(number);
104
+ * };
105
+ *
106
+ * // Assume args are '1 2 3':
107
+ *
108
+ * console.log(args.singleParse(parse));
109
+ * // Ok { value: 1 }
110
+ *
111
+ * console.log(args.singleParse(parse));
112
+ * // Ok { value: 2 }
113
+ *
114
+ * console.log(args.singleParse(parse));
115
+ * // Ok { value: 3 }
116
+ *
117
+ * console.log(args.singleParse(parse));
118
+ * // Err { error: null }
119
+ * ```
120
+ *
121
+ * @typeparam T The output type.
122
+ * @typeparam E The error type.
123
+ * @param predicate The predicate that determines the parameter's transformed value, or nothing if failed.
124
+ * @param useAnyways Whether to consider the parameter used even if the transformation failed. Defaults to `false`.
125
+ * @returns The transformed value, if any.
126
+ */
127
+ singleParse<T, E>(predicate: (value: string) => Result<T, E>, useAnyways?: boolean): Result<T, E | null>;
128
+ /**
129
+ * Retrieves the value of the next unused ordered token, but only if it could be transformed.
130
+ *
131
+ * @note This is an asynchronous variant of {@link singleParse}.
132
+ *
133
+ * @typeparam T The output type.
134
+ * @typeparam E The error type.
135
+ * @param predicate The predicate that determines the parameter's mapped value, or nothing if failed.
136
+ * @param useAnyways Whether to consider the parameter used even if the mapping failed. Defaults to `false`.
137
+ * @returns The mapped value, if any.
138
+ */
139
+ singleParseAsync<T, E>(predicate: (value: string) => Promise<Result<T, E>>, useAnyways?: boolean): Promise<Result<T, E | null>>;
140
+ /**
141
+ * Returns the value of the first element in the array within `Option.some` where `predicate` returns `true`, and
142
+ * `Option.none` otherwise.
143
+ *
144
+ * @note This does not support asynchronous results, refer to {@link findAsync}.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * // Suppose args are from 'ba aa cc'.
149
+ *
150
+ * console.log(args.find((value) => value.startsWith('a')));
151
+ * // Some { value: 'aa' }
152
+ * ```
153
+ *
154
+ * @param predicate find calls `predicate` once for each unused ordered parameter, in ascending order, until it
155
+ * finds one where `predicate` returns `true`. If such an element is found, find immediately returns a `Option.some`
156
+ * with that element value. Otherwise, find returns `Option.none`.
157
+ * @param from The position where to start looking for unused parameters, defaults to current position.
158
+ * @returns The found parameter's value.
159
+ */
160
+ find(predicate: (value: string) => boolean, from?: number): Option<string>;
161
+ /**
162
+ * Returns the value of the first element in the array within `Option.some` where `predicate` returns `true`, and
163
+ * `Option.none` otherwise.
164
+ *
165
+ * @note This is an asynchronous variant of {@link find}.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * // Suppose args are from 'ba aa cc'.
170
+ *
171
+ * console.log(args.find((value) => value.startsWith('a')));
172
+ * // Some { value: 'aa' }
173
+ * ```
174
+ *
175
+ * @param predicate find calls `predicate` once for each unused ordered parameter, in ascending order, until it
176
+ * finds one where `predicate` returns `true`. If such an element is found, find immediately returns a `Option.some`
177
+ * with that element value. Otherwise, find returns `Option.none`.
178
+ * @param from The position where to start looking for unused parameters, defaults to current position.
179
+ * @returns The found parameter's value.
180
+ */
181
+ findAsync(predicate: (value: string) => Promise<boolean>, from?: number): Promise<Option<string>>;
182
+ /**
183
+ * Returns the value of the first element in the array within `Option.some` where `predicate` returns `Some`, and
184
+ * `Option.none` otherwise.
185
+ *
186
+ * @note This does not support asynchronous results, refer to {@link findMapAsync}.
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * // Suppose args are from 'ba aa cc'.
191
+ *
192
+ * console.log(args.find((value) => value.startsWith('a')));
193
+ * // Some { value: 'aa' }
194
+ * ```
195
+ *
196
+ * @typeparam T The output type.
197
+ * @param predicate find calls `predicate` once for each unused ordered parameter, in ascending order, until it
198
+ * finds one where `predicate` returns `Some`. If such an element is found, find immediately returns the returned
199
+ * value. Otherwise, find returns `Option.none`.
200
+ * @param from The position where to start looking for unused parameters, defaults to current position.
201
+ * @returns The found parameter's value.
202
+ */
203
+ findMap<T>(predicate: (value: string) => Option<T>, from?: number): Option<T>;
204
+ /**
205
+ * Returns the value of the first element in the array within `Option.some` where `predicate` returns `Some`, and
206
+ * `Option.none` otherwise.
207
+ *
208
+ * @note This is an asynchronous variant of {@link findMap}.
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * // Suppose args are from 'ba aa cc'.
213
+ *
214
+ * console.log(args.find((value) => value.startsWith('a')));
215
+ * // Some { value: 'aa' }
216
+ * ```
217
+ *
218
+ * @typeparam T The output type.
219
+ * @param predicate find calls `predicate` once for each unused ordered parameter, in ascending order, until it
220
+ * finds one where `predicate` returns `Some`. If such an element is found, find immediately returns the returned
221
+ * value. Otherwise, find returns `Option.none`.
222
+ * @param from The position where to start looking for unused parameters, defaults to current position.
223
+ * @returns The found parameter's value.
224
+ */
225
+ findMapAsync<T>(predicate: (value: string) => Promise<Option<T>>, from?: number): Promise<Option<T>>;
226
+ /**
227
+ * Finds and retrieves the first unused parameter that could be transformed.
228
+ *
229
+ * @note This is a variant of {@link findMap} that returns the errors on failure.
230
+ * @note This does not support asynchronous results, refer to {@link findParseAsync}.
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * const parse = (value) => {
235
+ * const number = Number(value);
236
+ * return Number.isNaN(number)
237
+ * ? Result.err(`Could not parse ${value} to a number`)
238
+ * : Result.ok(number);
239
+ * };
240
+ *
241
+ * // Suppose args are from 'ba 1 cc'.
242
+ *
243
+ * console.log(args.findParse(parse));
244
+ * // Ok { value: 1 }
245
+ *
246
+ * console.log(args.findParse(parse));
247
+ * // Err {
248
+ * // error: [
249
+ * // 'Could not parse ba to a number',
250
+ * // 'Could not parse cc to a number'
251
+ * // ]
252
+ * // }
253
+ * ```
254
+ *
255
+ * @typeparam T The output type.
256
+ * @typeparam E The error type.
257
+ * @param predicate `findParse` calls `predicate` once for each unused ordered parameter, in ascending order, until
258
+ * it finds one where `predicate` returns `Ok`. If such an element is found, `findParse` immediately returns the
259
+ * returned value. Otherwise, `findParse` returns `Result.Err` with all the returned errors.
260
+ * @param from The position where to start looking for unused parameters, defaults to current position.
261
+ * @returns The found parameter's value.
262
+ */
263
+ findParse<T, E>(predicate: (value: string) => Result<T, E>, from?: number): Result<T, E[]>;
264
+ /**
265
+ * Finds and retrieves the first unused parameter that could be transformed.
266
+ *
267
+ * @note This is a variant of {@link findMapAsync} that returns the errors on failure.
268
+ * @note This is an asynchronous variant of {@link findParse}.
269
+ *
270
+ * @typeparam T The output type.
271
+ * @typeparam E The error type.
272
+ * @param predicate `findParse` calls `predicate` once for each unused ordered parameter, in ascending order, until
273
+ * it finds one where `predicate` returns `Ok`. If such an element is found, `findParse` immediately returns the
274
+ * returned value. Otherwise, `findParse` returns `Result.Err` with all the returned errors.
275
+ * @param from The position where to start looking for unused parameters, defaults to current position.
276
+ * @returns The found parameter's value.
277
+ */
278
+ findParseAsync<T, E>(predicate: (value: string) => Promise<Result<T, E>>, from?: number): Promise<Result<T, E[]>>;
279
+ /**
280
+ * Retrieves multiple unused parameters.
281
+ *
282
+ * @example
283
+ * ```typescript
284
+ * // Assume args are '1 2 3':
285
+ *
286
+ * console.log(join(args.many().unwrap()));
287
+ * // '1 2 3'
288
+ * ```
289
+ *
290
+ * @example
291
+ * ```typescript
292
+ * // Assume args are '1 2 3':
293
+ *
294
+ * console.log(join(args.many(2).unwrap()));
295
+ * // '1 2'
296
+ * ```
297
+ *
298
+ * @param limit The maximum amount of parameters to retrieve, defaults to `Infinity`.
299
+ * @param from The position where to start looking for unused parameters, defaults to current position.
300
+ * @returns The unused parameters within the range.
301
+ */
302
+ many(limit?: number, from?: number): Option<Parameter[]>;
303
+ filter(predicate: (value: string) => boolean, from?: number): Option<string[]>;
304
+ filterAsync(predicate: (value: string) => Promise<boolean>, from?: number): Promise<Option<string[]>>;
305
+ filterMap<T>(predicate: (value: string) => Option<T>, from?: number): Option<T[]>;
306
+ filterMapAsync<T>(predicate: (value: string) => Promise<Option<T>>, from?: number): Promise<Option<T[]>>;
307
+ /**
308
+ * Checks whether any of the flags were given.
309
+ *
310
+ * @example
311
+ * ```typescript
312
+ * // Assume args are '--f --g':
313
+ *
314
+ * console.log(args.flag('f'));
315
+ * // true
316
+ *
317
+ * console.log(args.flag('g', 'h'));
318
+ * // true
319
+ *
320
+ * console.log(args.flag('h'));
321
+ * // false
322
+ * ```
323
+ *
324
+ * @param keys The names of the flags to check.
325
+ * @returns Whether or not any of the flags were given.
326
+ */
327
+ flag(...keys: readonly string[]): boolean;
328
+ /**
329
+ * Gets the last value of any option. When there are multiple names, the last value of the last found name is given.
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * // Assume args are '--a=1 --b=2 --c=3'.
334
+ * console.log(args.option('a'));
335
+ * // Some { value: '1' }
336
+ *
337
+ * console.log(args.option('b', 'c'));
338
+ * // Some { value: '3' }
339
+ *
340
+ * console.log(args.option('d'));
341
+ * // None {}
342
+ * ```
343
+ *
344
+ * @param keys The names of the options to check.
345
+ * @returns The last value of the option, if any.
346
+ */
347
+ option(...keys: readonly string[]): Option<string>;
348
+ /**
349
+ * Gets all values from all options.
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * // Assume args are '--a=1 --a=1 --b=2 --c=3'.
354
+ * console.log(args.option('a'));
355
+ * // Some { value: ['1', '1'] }
356
+ *
357
+ * console.log(args.option('b', 'c'));
358
+ * // Some { value: ['2', '3'] }
359
+ *
360
+ * console.log(args.option('d'));
361
+ * // None {}
362
+ * ```
363
+ *
364
+ * @param keys The names of the options to check.
365
+ * @returns The values from all the options concatenated, if any.
366
+ */
367
+ options(...keys: readonly string[]): Option<readonly string[]>;
368
+ save(): ArgumentStream.State;
369
+ restore(state: ArgumentStream.State): void;
370
+ reset(): void;
371
+ }
372
+ export declare namespace ArgumentStream {
373
+ interface State {
374
+ used: Set<number>;
375
+ position: number;
376
+ }
377
+ }
378
+ //# sourceMappingURL=ArgumentStream.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { ParameterStream } from './streams/ParameterStream';
2
+ import { TokenStream } from './streams/raw/TokenStream';
3
+ export declare class Lexer {
4
+ readonly quotes: readonly [open: string, close: string][];
5
+ readonly separator: string;
6
+ constructor(options?: Lexer.Options);
7
+ run(input: string): ParameterStream;
8
+ raw(input: string): TokenStream;
9
+ }
10
+ export declare namespace Lexer {
11
+ interface Options {
12
+ separator?: string;
13
+ quotes?: readonly [open: string, close: string][];
14
+ }
15
+ }
16
+ //# sourceMappingURL=Lexer.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { QuotedParameter } from './parameters/QuotedParameter';
2
+ import { WordParameter } from './parameters/WordParameter';
3
+ import { type Token } from './raw/TokenStream';
4
+ export declare class ParameterStream {
5
+ private readonly stream;
6
+ private separators;
7
+ constructor(stream: Iterable<Token>);
8
+ [Symbol.iterator](): Iterator<Parameter, string[]>;
9
+ }
10
+ export declare type Parameter = QuotedParameter | WordParameter;
11
+ //# sourceMappingURL=ParameterStream.d.ts.map
@@ -0,0 +1,7 @@
1
+ export declare abstract class BaseParameter {
2
+ readonly separators: readonly string[];
3
+ constructor(separators: readonly string[]);
4
+ get leading(): string;
5
+ abstract get raw(): string;
6
+ }
7
+ //# sourceMappingURL=BaseParameter.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { QuotedToken } from '../raw/TokenStream';
2
+ import { BaseParameter } from './BaseParameter';
3
+ export declare class QuotedParameter extends BaseParameter {
4
+ readonly value: string;
5
+ readonly open: string;
6
+ readonly close: string;
7
+ constructor(separators: readonly string[], part: Omit<QuotedToken, 'type'>);
8
+ get raw(): string;
9
+ }
10
+ //# sourceMappingURL=QuotedParameter.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { WordToken } from '../raw/TokenStream';
2
+ import { BaseParameter } from './BaseParameter';
3
+ export declare class WordParameter extends BaseParameter {
4
+ readonly value: string;
5
+ constructor(separators: readonly string[], part: Omit<WordToken, 'type'>);
6
+ get raw(): string;
7
+ }
8
+ //# sourceMappingURL=WordParameter.d.ts.map
@@ -0,0 +1,34 @@
1
+ import type { Lexer } from '../../Lexer';
2
+ export declare class TokenStream implements Iterable<Token> {
3
+ private readonly input;
4
+ private readonly quotes;
5
+ private readonly separator;
6
+ private position;
7
+ constructor(lexer: Lexer, input: string);
8
+ get finished(): boolean;
9
+ [Symbol.iterator](): Iterator<Token>;
10
+ private getPossibleSeparator;
11
+ private getPossibleQuotedArgument;
12
+ private getParameter;
13
+ }
14
+ export declare enum TokenType {
15
+ Parameter = 0,
16
+ Quoted = 1,
17
+ Separator = 2
18
+ }
19
+ export declare type Token = WordToken | QuotedToken | SeparatorToken;
20
+ export interface WordToken {
21
+ readonly type: TokenType.Parameter;
22
+ readonly value: string;
23
+ }
24
+ export interface QuotedToken {
25
+ readonly type: TokenType.Quoted;
26
+ readonly value: string;
27
+ readonly open: string;
28
+ readonly close: string;
29
+ }
30
+ export interface SeparatorToken {
31
+ readonly type: TokenType.Separator;
32
+ readonly value: string;
33
+ }
34
+ //# sourceMappingURL=TokenStream.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { Parameter } from '../lexer/streams/ParameterStream';
2
+ import type { IUnorderedStrategy } from './strategies/IUnorderedStrategy';
3
+ import { ParserResult } from './ParserResult';
4
+ export declare class Parser {
5
+ strategy: IUnorderedStrategy;
6
+ constructor(strategy?: IUnorderedStrategy);
7
+ setUnorderedStrategy(strategy: IUnorderedStrategy): this;
8
+ run(input: Iterable<Parameter>): ParserResult;
9
+ }
10
+ //# sourceMappingURL=Parser.d.ts.map
@@ -0,0 +1,14 @@
1
+ import type { Parameter } from '../lexer/streams/ParameterStream';
2
+ import type { Parser } from './Parser';
3
+ export declare class ParserResult {
4
+ readonly ordered: Parameter[];
5
+ readonly flags: Set<string>;
6
+ readonly options: Map<string, string[]>;
7
+ private readonly strategy;
8
+ constructor(parser: Parser);
9
+ parse(parameters: Iterable<Parameter>): this;
10
+ private parsePossibleFlag;
11
+ private parsePossibleOptions;
12
+ private parseOrdered;
13
+ }
14
+ //# sourceMappingURL=ParserResult.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { Option } from '@sapphire/result';
2
+ import type { IUnorderedStrategy } from './IUnorderedStrategy';
3
+ export declare class EmptyStrategy implements IUnorderedStrategy {
4
+ matchFlag(): Option<string>;
5
+ matchOption(): Option<readonly [key: string, value: string]>;
6
+ }
7
+ //# sourceMappingURL=EmptyStrategy.d.ts.map
@@ -0,0 +1,14 @@
1
+ import type { Option } from '@sapphire/result';
2
+ export interface IUnorderedStrategy {
3
+ /**
4
+ * Matches a flag.
5
+ * @param input The string to match.
6
+ */
7
+ matchFlag(input: string): Option<string>;
8
+ /**
9
+ * Matches an option.
10
+ * @param input The string to match.
11
+ */
12
+ matchOption(input: string): Option<readonly [key: string, value: string]>;
13
+ }
14
+ //# sourceMappingURL=IUnorderedStrategy.d.ts.map
@@ -0,0 +1,10 @@
1
+ import { Option } from '@sapphire/result';
2
+ import type { IUnorderedStrategy } from './IUnorderedStrategy';
3
+ export declare class PrefixedStrategy implements IUnorderedStrategy {
4
+ readonly prefixes: readonly string[];
5
+ readonly separators: readonly string[];
6
+ constructor(prefixes: readonly string[], separators: readonly string[]);
7
+ matchFlag(input: string): Option<string>;
8
+ matchOption(input: string): Option<readonly [key: string, value: string]>;
9
+ }
10
+ //# sourceMappingURL=PrefixedStrategy.d.ts.map
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@sapphire/lexure",
3
+ "version": "1.0.0",
4
+ "description": "Parser and utilities for non-technical user input",
5
+ "author": "@sapphire",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "module": "dist/index.mjs",
9
+ "browser": "dist/index.global.js",
10
+ "unpkg": "dist/index.global.js",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js",
15
+ "types": "./dist/index.d.ts"
16
+ },
17
+ "sideEffects": false,
18
+ "homepage": "https://github.com/sapphiredev/utilities/tree/main/packages/lexure",
19
+ "scripts": {
20
+ "test": "vitest run",
21
+ "lint": "eslint src tests --ext ts --fix -c ../../.eslintrc",
22
+ "build": "tsup && tsc -b src",
23
+ "prepack": "yarn build",
24
+ "bump": "cliff-jumper",
25
+ "check-update": "cliff-jumper --dry-run"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/sapphiredev/utilities.git",
30
+ "directory": "packages/lexure"
31
+ },
32
+ "files": [
33
+ "dist/**/*.js*",
34
+ "dist/**/*.mjs*",
35
+ "dist/**/*.d*"
36
+ ],
37
+ "engines": {
38
+ "node": ">=v14.0.0",
39
+ "npm": ">=7.0.0"
40
+ },
41
+ "keywords": [
42
+ "@sapphire/lexure",
43
+ "bot",
44
+ "discord",
45
+ "lexure",
46
+ "promise",
47
+ "sapphire",
48
+ "standalone",
49
+ "ts",
50
+ "typescript",
51
+ "yarn"
52
+ ],
53
+ "bugs": {
54
+ "url": "https://github.com/sapphiredev/utilities/issues"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "dependencies": {
60
+ "@sapphire/result": "^2.0.1"
61
+ },
62
+ "devDependencies": {
63
+ "@favware/cliff-jumper": "^1.8.5",
64
+ "tsup": "^6.1.3",
65
+ "typescript": "^4.7.4"
66
+ }
67
+ }