utilium 1.3.1 → 1.3.3
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/buffer.js +1 -1
- package/dist/debugging.js +4 -2
- package/dist/internal/primitives.d.ts +1 -1
- package/dist/internal/primitives.js +15 -1
- package/dist/internal/struct.d.ts +1 -1
- package/dist/internal/struct.js +7 -3
- package/dist/objects.d.ts +3 -0
- package/dist/objects.js +16 -5
- package/dist/requests.js +4 -1
- package/dist/string.d.ts +4 -1
- package/dist/struct.js +6 -9
- package/dist/types.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +3 -1
- package/package.json +1 -1
- package/src/buffer.ts +6 -2
- package/src/debugging.ts +11 -2
- package/src/fs.ts +6 -1
- package/src/internal/primitives.ts +21 -3
- package/src/internal/struct.ts +23 -6
- package/src/objects.ts +43 -11
- package/src/requests.ts +14 -3
- package/src/string.ts +7 -2
- package/src/struct.ts +29 -14
- package/src/types.ts +41 -10
- package/src/version.ts +8 -2
package/dist/buffer.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
2
|
/**
|
3
3
|
* Grows a buffer if it isn't large enough
|
4
4
|
* @returns The original buffer if resized successfully, or a newly created buffer
|
package/dist/debugging.js
CHANGED
@@ -15,7 +15,9 @@ function defaultStringify(value) {
|
|
15
15
|
if (value === null)
|
16
16
|
return 'null';
|
17
17
|
if (ArrayBuffer.isView(value)) {
|
18
|
-
const length = 'length' in value
|
18
|
+
const length = 'length' in value
|
19
|
+
? value.length
|
20
|
+
: value.byteLength / value.constructor.BYTES_PER_ELEMENT;
|
19
21
|
return `${value.constructor.name.replaceAll('Array', '').toLowerCase()}[${length}]`;
|
20
22
|
}
|
21
23
|
if (Array.isArray(value))
|
@@ -33,7 +35,7 @@ function defaultStringify(value) {
|
|
33
35
|
* Create a function that can be used to decorate classes and non-field members.
|
34
36
|
*/
|
35
37
|
export function createLogDecorator(options) {
|
36
|
-
const { output = console.log, separator = '#', returnValue = false, stringify = defaultStringify, className = true } = options;
|
38
|
+
const { output = console.log, separator = '#', returnValue = false, stringify = defaultStringify, className = true, } = options;
|
37
39
|
return function log(value, context) {
|
38
40
|
if (context.kind == 'class') {
|
39
41
|
return function (...args) {
|
@@ -5,7 +5,7 @@ type BitsToBytes = {
|
|
5
5
|
'64': 8;
|
6
6
|
'128': 16;
|
7
7
|
};
|
8
|
-
export type Size<T extends string> = T extends `${'int' | 'uint' | 'float'}${infer bits}` ?
|
8
|
+
export type Size<T extends string> = T extends `${'int' | 'uint' | 'float'}${infer bits}` ? bits extends keyof BitsToBytes ? BitsToBytes[bits] : never : never;
|
9
9
|
export declare const types: readonly ["int8", "uint8", "int16", "uint16", "int32", "uint32", "int64", "uint64", "int128", "uint128", "float32", "float64", "float128"];
|
10
10
|
export type Type = (typeof types)[number];
|
11
11
|
export type Valid = Type | Capitalize<Type> | 'char';
|
@@ -1,5 +1,19 @@
|
|
1
1
|
import { capitalize } from '../string.js';
|
2
|
-
export const types = [
|
2
|
+
export const types = [
|
3
|
+
'int8',
|
4
|
+
'uint8',
|
5
|
+
'int16',
|
6
|
+
'uint16',
|
7
|
+
'int32',
|
8
|
+
'uint32',
|
9
|
+
'int64',
|
10
|
+
'uint64',
|
11
|
+
'int128',
|
12
|
+
'uint128',
|
13
|
+
'float32',
|
14
|
+
'float64',
|
15
|
+
'float128',
|
16
|
+
];
|
3
17
|
export const valids = [...types, ...types.map(t => capitalize(t)), 'char'];
|
4
18
|
export const regex = /^(u?int|float)(8|16|32|64|128)$/i;
|
5
19
|
export function normalize(type) {
|
@@ -71,7 +71,7 @@ export interface InstanceLike<T extends Metadata = Metadata> {
|
|
71
71
|
constructor: StaticLike<T>;
|
72
72
|
}
|
73
73
|
export declare function isInstance<T extends Metadata = Metadata>(arg: unknown): arg is Instance<T>;
|
74
|
-
export declare function checkInstance<T extends Metadata = Metadata>(arg: unknown): asserts arg is Instance<T>;
|
74
|
+
export declare function checkInstance<T extends Metadata = Metadata>(arg: unknown): asserts arg is Instance<T> & Record<keyof any, any>;
|
75
75
|
export declare function isStruct<T extends Metadata = Metadata>(arg: unknown): arg is Instance<T> | Static<T>;
|
76
76
|
export declare function checkStruct<T extends Metadata = Metadata>(arg: unknown): asserts arg is Instance<T> | Static<T>;
|
77
77
|
export type Like<T extends Metadata = Metadata> = InstanceLike<T> | StaticLike<T>;
|
package/dist/internal/struct.js
CHANGED
@@ -44,14 +44,17 @@ export function symbol_metadata(arg) {
|
|
44
44
|
return symbol_metadata;
|
45
45
|
}
|
46
46
|
export function isStatic(arg) {
|
47
|
-
return typeof arg == 'function'
|
47
|
+
return (typeof arg == 'function'
|
48
|
+
&& symbol_metadata(arg) in arg
|
49
|
+
&& isValidMetadata(arg[symbol_metadata(arg)]));
|
48
50
|
}
|
49
51
|
export function isInstance(arg) {
|
50
52
|
return arg != null && typeof arg == 'object' && isStatic(arg.constructor);
|
51
53
|
}
|
52
54
|
export function checkInstance(arg) {
|
53
55
|
if (!isInstance(arg)) {
|
54
|
-
throw new TypeError((typeof arg == 'function' ? arg.name : typeof arg == 'object' && arg ? arg.constructor.name : arg)
|
56
|
+
throw new TypeError((typeof arg == 'function' ? arg.name : typeof arg == 'object' && arg ? arg.constructor.name : arg)
|
57
|
+
+ ' is not a struct instance');
|
55
58
|
}
|
56
59
|
}
|
57
60
|
export function isStruct(arg) {
|
@@ -59,6 +62,7 @@ export function isStruct(arg) {
|
|
59
62
|
}
|
60
63
|
export function checkStruct(arg) {
|
61
64
|
if (!isStruct(arg)) {
|
62
|
-
throw new TypeError((typeof arg == 'function' ? arg.name : typeof arg == 'object' && arg ? arg.constructor.name : arg)
|
65
|
+
throw new TypeError((typeof arg == 'function' ? arg.name : typeof arg == 'object' && arg ? arg.constructor.name : arg)
|
66
|
+
+ ' is not a struct');
|
63
67
|
}
|
64
68
|
}
|
package/dist/objects.d.ts
CHANGED
@@ -19,6 +19,7 @@ export type Entries<T extends object> = ({
|
|
19
19
|
}[keyof T] & unknown[])[];
|
20
20
|
export declare function isJSON(str: string): boolean;
|
21
21
|
export declare function resolveConstructors(object: object): string[];
|
22
|
+
export declare function getAllPrototypes(object: object): IterableIterator<object>;
|
22
23
|
/**
|
23
24
|
* Allows you to convert an object with specific member types into a Map that will give you the correct type for the correct member
|
24
25
|
*/
|
@@ -32,3 +33,5 @@ export interface ConstMap<T extends Partial<Record<keyof any, any>>, K extends k
|
|
32
33
|
export declare function map<const T extends Partial<Record<any, any>>>(items: T): Map<keyof T, T[keyof T]>;
|
33
34
|
export declare function getByString(object: Record<string, any>, path: string, separator?: RegExp): Record<string, any>;
|
34
35
|
export declare function setByString(object: Record<string, any>, path: string, value: unknown, separator?: RegExp): Record<string, any>;
|
36
|
+
/** Binds a class member to the instance */
|
37
|
+
export declare function bound(value: unknown, { name, addInitializer }: ClassMethodDecoratorContext): void;
|
package/dist/objects.js
CHANGED
@@ -18,7 +18,7 @@ export function assignWithDefaults(to, from, defaults = to) {
|
|
18
18
|
try {
|
19
19
|
to[key] = from[key] ?? defaults[key] ?? to[key];
|
20
20
|
}
|
21
|
-
catch
|
21
|
+
catch {
|
22
22
|
// Do nothing
|
23
23
|
}
|
24
24
|
}
|
@@ -28,19 +28,22 @@ export function isJSON(str) {
|
|
28
28
|
JSON.parse(str);
|
29
29
|
return true;
|
30
30
|
}
|
31
|
-
catch
|
31
|
+
catch {
|
32
32
|
return false;
|
33
33
|
}
|
34
34
|
}
|
35
35
|
export function resolveConstructors(object) {
|
36
36
|
const constructors = [];
|
37
|
-
let prototype = object;
|
38
|
-
while (prototype && !['Function', 'Object'].includes(prototype.constructor.name)) {
|
39
|
-
prototype = Object.getPrototypeOf(prototype);
|
37
|
+
for (let prototype = object; prototype && !['Function', 'Object'].includes(prototype.constructor.name); prototype = Object.getPrototypeOf(prototype)) {
|
40
38
|
constructors.push(prototype.constructor.name);
|
41
39
|
}
|
42
40
|
return constructors;
|
43
41
|
}
|
42
|
+
export function* getAllPrototypes(object) {
|
43
|
+
for (let prototype = object; prototype; prototype = Object.getPrototypeOf(prototype)) {
|
44
|
+
yield prototype;
|
45
|
+
}
|
46
|
+
}
|
44
47
|
export function map(items) {
|
45
48
|
return new Map(Object.entries(items));
|
46
49
|
}
|
@@ -56,3 +59,11 @@ export function setByString(object, path, value, separator = /[.[\]'"]/) {
|
|
56
59
|
.filter(p => p)
|
57
60
|
.reduce((o, p, i) => (o[p] = path.split(separator).filter(p => p).length === ++i ? value : o[p] || {}), object);
|
58
61
|
}
|
62
|
+
/** Binds a class member to the instance */
|
63
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
64
|
+
export function bound(value, { name, addInitializer }) {
|
65
|
+
addInitializer(function () {
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
67
|
+
this[name] = this[name].bind(this);
|
68
|
+
});
|
69
|
+
}
|
package/dist/requests.js
CHANGED
@@ -42,7 +42,10 @@ export async function get(url, options, init = {}) {
|
|
42
42
|
const { headers } = await fetch(req, { method: 'HEAD' });
|
43
43
|
const size = parseInt(headers.get('Content-Length') ?? '');
|
44
44
|
if (typeof size != 'number')
|
45
|
-
throw {
|
45
|
+
throw {
|
46
|
+
tag: 'size',
|
47
|
+
message: 'Response is missing content-length header and no size was provided',
|
48
|
+
};
|
46
49
|
options.size = size;
|
47
50
|
}
|
48
51
|
const { size, start, end } = options;
|
package/dist/string.d.ts
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
export declare function capitalize<T extends string>(value: T): Capitalize<T>;
|
2
2
|
export declare function uncapitalize<T extends string>(value: T): Uncapitalize<T>;
|
3
3
|
export type ConcatString<T extends string[]> = T extends [infer F extends string, ...infer R extends string[]] ? `${F}${ConcatString<R>}` : '';
|
4
|
-
export type Join<T extends string[], S extends string = ','> = T extends [
|
4
|
+
export type Join<T extends string[], S extends string = ','> = T extends [
|
5
|
+
infer F extends string,
|
6
|
+
...infer R extends string[]
|
7
|
+
] ? `${F}${R extends [] ? '' : `${S}${Join<R, S>}`}` : '';
|
5
8
|
export type Whitespace = ' ' | '\t';
|
6
9
|
export type Trim<T extends string> = T extends `${Whitespace}${infer R extends string}` ? Trim<R> : T;
|
package/dist/struct.js
CHANGED
@@ -91,7 +91,6 @@ export function serialize(instance) {
|
|
91
91
|
for (const [name, { type, length, offset }] of members) {
|
92
92
|
for (let i = 0; i < (length || 1); i++) {
|
93
93
|
const iOff = offset + sizeof(type) * i;
|
94
|
-
// @ts-expect-error 7053
|
95
94
|
let value = length > 0 ? instance[name][i] : instance[name];
|
96
95
|
if (typeof value == 'string') {
|
97
96
|
value = value.charCodeAt(0);
|
@@ -139,13 +138,11 @@ export function deserialize(instance, _buffer) {
|
|
139
138
|
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
140
139
|
for (const [name, { type, offset, length }] of members) {
|
141
140
|
for (let i = 0; i < (length || 1); i++) {
|
142
|
-
// @ts-expect-error 7053
|
143
141
|
let object = length > 0 ? instance[name] : instance;
|
144
142
|
const key = length > 0 ? i : name, iOff = offset + sizeof(type) * i;
|
145
|
-
// @ts-expect-error 7053
|
146
143
|
if (typeof instance[name] == 'string') {
|
147
|
-
|
148
|
-
|
144
|
+
instance[name] =
|
145
|
+
instance[name].slice(0, i) + String.fromCharCode(view.getUint8(iOff)) + instance[name].slice(i + 1);
|
149
146
|
continue;
|
150
147
|
}
|
151
148
|
if (!primitive.isType(type)) {
|
@@ -169,14 +166,14 @@ export function deserialize(instance, _buffer) {
|
|
169
166
|
}
|
170
167
|
if (fn == 'getInt128') {
|
171
168
|
object[key] =
|
172
|
-
(view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
173
|
-
view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
169
|
+
(view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
170
|
+
| view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
174
171
|
continue;
|
175
172
|
}
|
176
173
|
if (fn == 'getUint128') {
|
177
174
|
object[key] =
|
178
|
-
(view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
179
|
-
view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
175
|
+
(view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
176
|
+
| view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
180
177
|
continue;
|
181
178
|
}
|
182
179
|
if (fn == 'getFloat128') {
|
package/dist/types.d.ts
CHANGED
@@ -147,7 +147,7 @@ export type IsTuple<T> = T extends [] ? false : T extends [infer _Head, ...infer
|
|
147
147
|
/**
|
148
148
|
* Flattens a tuple
|
149
149
|
*/
|
150
|
-
export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest] ?
|
150
|
+
export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest] ? U extends unknown[] ? [...U, ...FlattenTuple<Rest>] : [U, ...FlattenTuple<Rest>] : [];
|
151
151
|
/**
|
152
152
|
* Flattens an array or tuple
|
153
153
|
*/
|
package/dist/version.d.ts
CHANGED
@@ -2,7 +2,7 @@ export type Sep = '_' | '-';
|
|
2
2
|
export type Part = `${number}.${number}.${number}`;
|
3
3
|
export type WithPre = `${Part}${Sep}${string}${Sep | '.'}${Part | number}`;
|
4
4
|
export type Full = Part | WithPre;
|
5
|
-
type Type<S extends string, Acc extends string = ''> = S extends `${infer First}${infer Rest}` ?
|
5
|
+
type Type<S extends string, Acc extends string = ''> = S extends `${infer First}${infer Rest}` ? First extends Sep | '.' ? Acc : Type<Rest, `${Acc}${First}`> : Acc;
|
6
6
|
export type Parse<T extends Full, StripCore extends boolean> = T extends `${infer Core}${Sep}${infer Rest}` ? Rest extends `${infer U}` ? {
|
7
7
|
full: T;
|
8
8
|
core: Core;
|
package/dist/version.js
CHANGED
@@ -2,6 +2,8 @@ import { capitalize } from './string.js';
|
|
2
2
|
export const regex = /^(?<core>\d+\.\d+\.\d+)(?:[-_](?<type>[^-_.]+)[-_.](?<pre>\d*(?:\.\d+)*))?/;
|
3
3
|
export function parse(full, stripCore) {
|
4
4
|
const { type, pre, core } = regex.exec(full).groups;
|
5
|
-
const display = type
|
5
|
+
const display = type
|
6
|
+
? `${stripCore && core == '1.0.0' ? '' : core + ' '}${capitalize(type)}${pre ? ` ${pre}` : ''}`
|
7
|
+
: core;
|
6
8
|
return { full, core, pre, type, display };
|
7
9
|
}
|
package/package.json
CHANGED
package/src/buffer.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
2
|
|
3
3
|
/**
|
4
4
|
* A generic ArrayBufferView (typed array) constructor
|
@@ -7,7 +7,11 @@ export interface ArrayBufferViewConstructor {
|
|
7
7
|
readonly prototype: ArrayBufferView<ArrayBufferLike>;
|
8
8
|
new (length: number): ArrayBufferView<ArrayBuffer>;
|
9
9
|
new (array: ArrayLike<number>): ArrayBufferView<ArrayBuffer>;
|
10
|
-
new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
|
10
|
+
new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
|
11
|
+
buffer: TArrayBuffer,
|
12
|
+
byteOffset?: number,
|
13
|
+
length?: number
|
14
|
+
): ArrayBufferView<TArrayBuffer>;
|
11
15
|
new (array: ArrayLike<number> | ArrayBuffer): ArrayBufferView<ArrayBuffer>;
|
12
16
|
}
|
13
17
|
|
package/src/debugging.ts
CHANGED
@@ -40,7 +40,10 @@ function defaultStringify(value: unknown): string {
|
|
40
40
|
case 'object':
|
41
41
|
if (value === null) return 'null';
|
42
42
|
if (ArrayBuffer.isView(value)) {
|
43
|
-
const length =
|
43
|
+
const length =
|
44
|
+
'length' in value
|
45
|
+
? (value.length as number)
|
46
|
+
: value.byteLength / (value.constructor as any).BYTES_PER_ELEMENT;
|
44
47
|
return `${value.constructor.name.replaceAll('Array', '').toLowerCase()}[${length}]`;
|
45
48
|
}
|
46
49
|
if (Array.isArray(value)) return `unknown[${value.length}]`;
|
@@ -60,7 +63,13 @@ type LoggableDecoratorContext = Exclude<DecoratorContext, ClassFieldDecoratorCon
|
|
60
63
|
* Create a function that can be used to decorate classes and non-field members.
|
61
64
|
*/
|
62
65
|
export function createLogDecorator(options: CreateLoggerOptions) {
|
63
|
-
const {
|
66
|
+
const {
|
67
|
+
output = console.log,
|
68
|
+
separator = '#',
|
69
|
+
returnValue = false,
|
70
|
+
stringify = defaultStringify,
|
71
|
+
className = true,
|
72
|
+
} = options;
|
64
73
|
|
65
74
|
return function log<T extends (...args: any[]) => any>(value: T, context: LoggableDecoratorContext): T {
|
66
75
|
if (context.kind == 'class') {
|
package/src/fs.ts
CHANGED
@@ -51,7 +51,12 @@ export abstract class FileMap<V> implements Map<string, V> {
|
|
51
51
|
|
52
52
|
export type JSONObject<Key extends string | number | symbol = string> = { [K in Key]: JSONValue };
|
53
53
|
|
54
|
-
export type JSONValue<Key extends string | number | symbol = string> =
|
54
|
+
export type JSONValue<Key extends string | number | symbol = string> =
|
55
|
+
| string
|
56
|
+
| number
|
57
|
+
| boolean
|
58
|
+
| JSONObject<Key>
|
59
|
+
| Array<JSONValue>;
|
55
60
|
|
56
61
|
export interface JSONFileMapOptions {
|
57
62
|
/**
|
@@ -8,9 +8,27 @@ type BitsToBytes = {
|
|
8
8
|
'128': 16;
|
9
9
|
};
|
10
10
|
|
11
|
-
export type Size<T extends string> = T extends `${'int' | 'uint' | 'float'}${infer bits}`
|
12
|
-
|
13
|
-
|
11
|
+
export type Size<T extends string> = T extends `${'int' | 'uint' | 'float'}${infer bits}`
|
12
|
+
? bits extends keyof BitsToBytes
|
13
|
+
? BitsToBytes[bits]
|
14
|
+
: never
|
15
|
+
: never;
|
16
|
+
|
17
|
+
export const types = [
|
18
|
+
'int8',
|
19
|
+
'uint8',
|
20
|
+
'int16',
|
21
|
+
'uint16',
|
22
|
+
'int32',
|
23
|
+
'uint32',
|
24
|
+
'int64',
|
25
|
+
'uint64',
|
26
|
+
'int128',
|
27
|
+
'uint128',
|
28
|
+
'float32',
|
29
|
+
'float64',
|
30
|
+
'float128',
|
31
|
+
] as const;
|
14
32
|
|
15
33
|
export type Type = (typeof types)[number];
|
16
34
|
|
package/src/internal/struct.ts
CHANGED
@@ -107,7 +107,8 @@ export function _polyfill_contextMetadata(target: object): void {
|
|
107
107
|
* Gets a reference to Symbol.metadata, even on platforms that do not expose it globally (like Node)
|
108
108
|
*/
|
109
109
|
export function symbol_metadata(arg: ClassLike): typeof Symbol.metadata {
|
110
|
-
const symbol_metadata =
|
110
|
+
const symbol_metadata =
|
111
|
+
Symbol.metadata || Object.getOwnPropertySymbols(arg).find(s => s.description == 'Symbol.metadata');
|
111
112
|
_polyfill_contextMetadata(arg);
|
112
113
|
if (!symbol_metadata) {
|
113
114
|
throw new ReferenceError('Could not get a reference to Symbol.metadata');
|
@@ -117,7 +118,11 @@ export function symbol_metadata(arg: ClassLike): typeof Symbol.metadata {
|
|
117
118
|
}
|
118
119
|
|
119
120
|
export function isStatic<T extends Metadata = Metadata>(arg: unknown): arg is Static<T> {
|
120
|
-
return
|
121
|
+
return (
|
122
|
+
typeof arg == 'function'
|
123
|
+
&& symbol_metadata(arg as ClassLike) in arg
|
124
|
+
&& isValidMetadata(arg[symbol_metadata(arg as ClassLike)])
|
125
|
+
);
|
121
126
|
}
|
122
127
|
|
123
128
|
export interface Instance<T extends Metadata = Metadata> {
|
@@ -132,9 +137,14 @@ export function isInstance<T extends Metadata = Metadata>(arg: unknown): arg is
|
|
132
137
|
return arg != null && typeof arg == 'object' && isStatic(arg.constructor);
|
133
138
|
}
|
134
139
|
|
135
|
-
export function checkInstance<T extends Metadata = Metadata>(
|
140
|
+
export function checkInstance<T extends Metadata = Metadata>(
|
141
|
+
arg: unknown
|
142
|
+
): asserts arg is Instance<T> & Record<keyof any, any> {
|
136
143
|
if (!isInstance(arg)) {
|
137
|
-
throw new TypeError(
|
144
|
+
throw new TypeError(
|
145
|
+
(typeof arg == 'function' ? arg.name : typeof arg == 'object' && arg ? arg.constructor.name : arg)
|
146
|
+
+ ' is not a struct instance'
|
147
|
+
);
|
138
148
|
}
|
139
149
|
}
|
140
150
|
|
@@ -144,10 +154,17 @@ export function isStruct<T extends Metadata = Metadata>(arg: unknown): arg is In
|
|
144
154
|
|
145
155
|
export function checkStruct<T extends Metadata = Metadata>(arg: unknown): asserts arg is Instance<T> | Static<T> {
|
146
156
|
if (!isStruct(arg)) {
|
147
|
-
throw new TypeError(
|
157
|
+
throw new TypeError(
|
158
|
+
(typeof arg == 'function' ? arg.name : typeof arg == 'object' && arg ? arg.constructor.name : arg)
|
159
|
+
+ ' is not a struct'
|
160
|
+
);
|
148
161
|
}
|
149
162
|
}
|
150
163
|
|
151
164
|
export type Like<T extends Metadata = Metadata> = InstanceLike<T> | StaticLike<T>;
|
152
165
|
|
153
|
-
export type Size<T extends primitive.Valid | StaticLike | InstanceLike> = T extends primitive.Valid
|
166
|
+
export type Size<T extends primitive.Valid | StaticLike | InstanceLike> = T extends primitive.Valid
|
167
|
+
? primitive.Size<T>
|
168
|
+
: T extends Like<infer M>
|
169
|
+
? M['size']
|
170
|
+
: number;
|
package/src/objects.ts
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
import type { UnionToTuple } from './types.js';
|
2
2
|
|
3
|
-
export function filterObject<O extends object, R extends object>(
|
3
|
+
export function filterObject<O extends object, R extends object>(
|
4
|
+
object: O,
|
5
|
+
predicate: (key: keyof O, value: O[keyof O]) => boolean
|
6
|
+
): R {
|
4
7
|
const entries = Object.entries(object) as [keyof O, O[keyof O]][];
|
5
8
|
return Object.fromEntries(entries.filter(([key, value]) => predicate(key, value))) as R;
|
6
9
|
}
|
7
10
|
|
8
11
|
export function pick<T extends object, K extends keyof T>(object: T, ...keys: readonly K[]): Pick<T, K>;
|
9
12
|
export function pick<T extends object, K extends keyof T>(object: T, ...keys: readonly (readonly K[])[]): Pick<T, K>;
|
10
|
-
export function pick<T extends object, K extends keyof T>(
|
13
|
+
export function pick<T extends object, K extends keyof T>(
|
14
|
+
object: T,
|
15
|
+
...keys: readonly K[] | readonly (readonly K[])[]
|
16
|
+
): Pick<T, K> {
|
11
17
|
const picked = {} as Pick<T, K>;
|
12
18
|
for (const key of keys.flat() as K[]) {
|
13
19
|
picked[key] = object[key];
|
@@ -17,16 +23,23 @@ export function pick<T extends object, K extends keyof T>(object: T, ...keys: re
|
|
17
23
|
|
18
24
|
export function omit<T extends object, K extends keyof T>(object: T, ...keys: readonly K[]): Omit<T, K>;
|
19
25
|
export function omit<T extends object, K extends keyof T>(object: T, ...keys: readonly (readonly K[])[]): Omit<T, K>;
|
20
|
-
export function omit<T extends object, K extends keyof T>(
|
26
|
+
export function omit<T extends object, K extends keyof T>(
|
27
|
+
object: T,
|
28
|
+
...keys: readonly K[] | readonly (readonly K[])[]
|
29
|
+
): Omit<T, K> {
|
21
30
|
return filterObject<T, Omit<T, K>>(object, key => !keys.flat().includes(key as K));
|
22
31
|
}
|
23
32
|
|
24
|
-
export function assignWithDefaults<To extends Record<keyof any, any>, From extends Partial<To>>(
|
33
|
+
export function assignWithDefaults<To extends Record<keyof any, any>, From extends Partial<To>>(
|
34
|
+
to: To,
|
35
|
+
from: From,
|
36
|
+
defaults: Partial<To> = to
|
37
|
+
): void {
|
25
38
|
const keys = new Set<keyof To | keyof From>([...Object.keys(to), ...Object.keys(from)]);
|
26
39
|
for (const key of keys) {
|
27
40
|
try {
|
28
41
|
to[key] = from[key] ?? defaults[key] ?? to[key];
|
29
|
-
} catch
|
42
|
+
} catch {
|
30
43
|
// Do nothing
|
31
44
|
}
|
32
45
|
}
|
@@ -35,7 +48,8 @@ export function assignWithDefaults<To extends Record<keyof any, any>, From exten
|
|
35
48
|
/**
|
36
49
|
* Entries of T
|
37
50
|
*/
|
38
|
-
export type EntriesTuple<T extends object> = UnionToTuple<{ [K in keyof T]: [K, T[K]] }[keyof T]>
|
51
|
+
export type EntriesTuple<T extends object> = UnionToTuple<{ [K in keyof T]: [K, T[K]] }[keyof T]>
|
52
|
+
& [unknown, unknown][];
|
39
53
|
|
40
54
|
/**
|
41
55
|
* Entries of T
|
@@ -46,25 +60,34 @@ export function isJSON(str: string) {
|
|
46
60
|
try {
|
47
61
|
JSON.parse(str);
|
48
62
|
return true;
|
49
|
-
} catch
|
63
|
+
} catch {
|
50
64
|
return false;
|
51
65
|
}
|
52
66
|
}
|
53
67
|
|
54
68
|
export function resolveConstructors(object: object): string[] {
|
55
69
|
const constructors = [];
|
56
|
-
|
57
|
-
|
58
|
-
prototype
|
70
|
+
for (
|
71
|
+
let prototype = object;
|
72
|
+
prototype && !['Function', 'Object'].includes(prototype.constructor.name);
|
73
|
+
prototype = Object.getPrototypeOf(prototype)
|
74
|
+
) {
|
59
75
|
constructors.push(prototype.constructor.name);
|
60
76
|
}
|
61
77
|
return constructors;
|
62
78
|
}
|
63
79
|
|
80
|
+
export function* getAllPrototypes(object: object): IterableIterator<object> {
|
81
|
+
for (let prototype = object; prototype; prototype = Object.getPrototypeOf(prototype)) {
|
82
|
+
yield prototype;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
64
86
|
/**
|
65
87
|
* Allows you to convert an object with specific member types into a Map that will give you the correct type for the correct member
|
66
88
|
*/
|
67
|
-
export interface ConstMap<T extends Partial<Record<keyof any, any>>, K extends keyof any = keyof T, V = T[keyof T]>
|
89
|
+
export interface ConstMap<T extends Partial<Record<keyof any, any>>, K extends keyof any = keyof T, V = T[keyof T]>
|
90
|
+
extends Map<K, V> {
|
68
91
|
get<TK extends keyof T>(key: TK): T[TK];
|
69
92
|
get(key: K): V;
|
70
93
|
set<TK extends keyof T>(key: TK, value: T[TK]): this;
|
@@ -89,3 +112,12 @@ export function setByString(object: Record<string, any>, path: string, value: un
|
|
89
112
|
.filter(p => p)
|
90
113
|
.reduce((o, p, i) => (o[p] = path.split(separator).filter(p => p).length === ++i ? value : o[p] || {}), object);
|
91
114
|
}
|
115
|
+
|
116
|
+
/** Binds a class member to the instance */
|
117
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
118
|
+
export function bound(value: unknown, { name, addInitializer }: ClassMethodDecoratorContext) {
|
119
|
+
addInitializer(function (this: any) {
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
121
|
+
this[name] = this[name].bind(this);
|
122
|
+
});
|
123
|
+
}
|
package/src/requests.ts
CHANGED
@@ -22,7 +22,11 @@ export type CacheOptions = cache.Options;
|
|
22
22
|
*/
|
23
23
|
export const resourcesCache = new Map<string, cache.Resource<string> | undefined>();
|
24
24
|
|
25
|
-
export type Issue =
|
25
|
+
export type Issue =
|
26
|
+
| { tag: 'status'; response: Response }
|
27
|
+
| { tag: 'buffer'; response: Response; message: string }
|
28
|
+
| { tag: 'fetch' | 'size'; message: string }
|
29
|
+
| Error;
|
26
30
|
|
27
31
|
/**
|
28
32
|
* @deprecated Use `Issue`
|
@@ -103,7 +107,11 @@ export async function get(url: string, options: GetOptions, init: RequestInit =
|
|
103
107
|
|
104
108
|
const { headers } = await fetch(req, { method: 'HEAD' });
|
105
109
|
const size = parseInt(headers.get('Content-Length') ?? '');
|
106
|
-
if (typeof size != 'number')
|
110
|
+
if (typeof size != 'number')
|
111
|
+
throw {
|
112
|
+
tag: 'size',
|
113
|
+
message: 'Response is missing content-length header and no size was provided',
|
114
|
+
} satisfies Issue;
|
107
115
|
options.size = size;
|
108
116
|
}
|
109
117
|
|
@@ -171,7 +179,10 @@ export function getCached(url: string, options: GetOptions): { data?: Uint8Array
|
|
171
179
|
|
172
180
|
if (overlapStart >= overlapEnd) continue;
|
173
181
|
|
174
|
-
data.set(
|
182
|
+
data.set(
|
183
|
+
region.data.subarray(overlapStart - region.offset, overlapEnd - region.offset),
|
184
|
+
overlapStart - start
|
185
|
+
);
|
175
186
|
}
|
176
187
|
}
|
177
188
|
|
package/src/string.ts
CHANGED
@@ -6,9 +6,14 @@ export function uncapitalize<T extends string>(value: T): Uncapitalize<T> {
|
|
6
6
|
return (value.at(0)!.toLowerCase() + value.slice(1)) as Uncapitalize<T>;
|
7
7
|
}
|
8
8
|
|
9
|
-
export type ConcatString<T extends string[]> = T extends [infer F extends string, ...infer R extends string[]]
|
9
|
+
export type ConcatString<T extends string[]> = T extends [infer F extends string, ...infer R extends string[]]
|
10
|
+
? `${F}${ConcatString<R>}`
|
11
|
+
: '';
|
10
12
|
|
11
|
-
export type Join<T extends string[], S extends string = ','> = T extends [
|
13
|
+
export type Join<T extends string[], S extends string = ','> = T extends [
|
14
|
+
infer F extends string,
|
15
|
+
...infer R extends string[],
|
16
|
+
]
|
12
17
|
? `${F}${R extends [] ? '' : `${S}${Join<R, S>}`}`
|
13
18
|
: '';
|
14
19
|
|
package/src/struct.ts
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
import * as primitive from './internal/primitives.js';
|
2
|
-
import type {
|
2
|
+
import type {
|
3
|
+
DecoratorContext,
|
4
|
+
InstanceLike,
|
5
|
+
Member,
|
6
|
+
MemberInit,
|
7
|
+
Metadata,
|
8
|
+
Options,
|
9
|
+
Size,
|
10
|
+
StaticLike,
|
11
|
+
} from './internal/struct.js';
|
3
12
|
import { checkInstance, checkStruct, isStatic, symbol_metadata, type MemberContext } from './internal/struct.js';
|
4
13
|
import { capitalize } from './string.js';
|
5
14
|
import type { ClassLike } from './types.js';
|
@@ -48,7 +57,10 @@ export function align(value: number, alignment: number): number {
|
|
48
57
|
* Decorates a class as a struct
|
49
58
|
*/
|
50
59
|
export function struct(options: Partial<Options> = {}) {
|
51
|
-
return function _decorateStruct<const T extends StaticLike>(
|
60
|
+
return function _decorateStruct<const T extends StaticLike>(
|
61
|
+
target: T,
|
62
|
+
context: ClassDecoratorContext & DecoratorContext
|
63
|
+
): T {
|
52
64
|
context.metadata ??= {};
|
53
65
|
context.metadata[Symbol.struct_init] ||= [];
|
54
66
|
let size = 0;
|
@@ -110,7 +122,6 @@ export function serialize(instance: unknown): Uint8Array {
|
|
110
122
|
for (let i = 0; i < (length || 1); i++) {
|
111
123
|
const iOff = offset + sizeof(type) * i;
|
112
124
|
|
113
|
-
// @ts-expect-error 7053
|
114
125
|
let value = length! > 0 ? instance[name][i] : instance[name];
|
115
126
|
if (typeof value == 'string') {
|
116
127
|
value = value.charCodeAt(0);
|
@@ -165,21 +176,20 @@ export function deserialize(instance: unknown, _buffer: ArrayBufferLike | ArrayB
|
|
165
176
|
checkInstance(instance);
|
166
177
|
const { options, members } = instance.constructor[symbol_metadata(instance.constructor)][Symbol.struct_metadata];
|
167
178
|
|
168
|
-
const buffer =
|
179
|
+
const buffer =
|
180
|
+
_buffer instanceof Uint8Array ? _buffer : new Uint8Array('buffer' in _buffer ? _buffer.buffer : _buffer);
|
169
181
|
|
170
182
|
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
171
183
|
|
172
184
|
for (const [name, { type, offset, length }] of members) {
|
173
185
|
for (let i = 0; i < (length || 1); i++) {
|
174
|
-
// @ts-expect-error 7053
|
175
186
|
let object = length! > 0 ? instance[name] : instance;
|
176
187
|
const key = length! > 0 ? i : name,
|
177
188
|
iOff = offset + sizeof(type) * i;
|
178
189
|
|
179
|
-
// @ts-expect-error 7053
|
180
190
|
if (typeof instance[name] == 'string') {
|
181
|
-
|
182
|
-
|
191
|
+
instance[name] =
|
192
|
+
instance[name].slice(0, i) + String.fromCharCode(view.getUint8(iOff)) + instance[name].slice(i + 1);
|
183
193
|
continue;
|
184
194
|
}
|
185
195
|
|
@@ -208,15 +218,15 @@ export function deserialize(instance: unknown, _buffer: ArrayBufferLike | ArrayB
|
|
208
218
|
|
209
219
|
if (fn == 'getInt128') {
|
210
220
|
object[key] =
|
211
|
-
(view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
212
|
-
view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
221
|
+
(view.getBigInt64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
222
|
+
| view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
213
223
|
continue;
|
214
224
|
}
|
215
225
|
|
216
226
|
if (fn == 'getUint128') {
|
217
227
|
object[key] =
|
218
|
-
(view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
219
|
-
view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
228
|
+
(view.getBigUint64(iOff + (!options.bigEndian ? 8 : 0), !options.bigEndian) << BigInt(64))
|
229
|
+
| view.getBigUint64(iOff + (!options.bigEndian ? 0 : 8), !options.bigEndian);
|
220
230
|
continue;
|
221
231
|
}
|
222
232
|
|
@@ -233,7 +243,10 @@ export function deserialize(instance: unknown, _buffer: ArrayBufferLike | ArrayB
|
|
233
243
|
function _member<T extends primitive.Valid>(type: T) {
|
234
244
|
function _structMemberDecorator<const V>(length: number): (value: V, context: MemberContext) => V;
|
235
245
|
function _structMemberDecorator<const V>(value: V, context: MemberContext): V;
|
236
|
-
function _structMemberDecorator<const V>(
|
246
|
+
function _structMemberDecorator<const V>(
|
247
|
+
valueOrLength: V | number,
|
248
|
+
context?: MemberContext
|
249
|
+
): V | ((value: V, context: MemberContext) => V) {
|
237
250
|
if (typeof valueOrLength == 'number') {
|
238
251
|
return member(type, valueOrLength);
|
239
252
|
}
|
@@ -248,4 +261,6 @@ function _member<T extends primitive.Valid>(type: T) {
|
|
248
261
|
*
|
249
262
|
* Instead of writing `@member(type)` you can write `@types.type`, or `@types.type(length)` for arrays
|
250
263
|
*/
|
251
|
-
export const types = Object.fromEntries(primitive.valids.map(t => [t, _member(t)])) as {
|
264
|
+
export const types = Object.fromEntries(primitive.valids.map(t => [t, _member(t)])) as {
|
265
|
+
[K in primitive.Valid]: ReturnType<typeof _member<K>>;
|
266
|
+
};
|
package/src/types.ts
CHANGED
@@ -2,7 +2,11 @@
|
|
2
2
|
* Expands the type T (for intellisense and debugging)
|
3
3
|
* @see https://stackoverflow.com/a/69288824/17637456
|
4
4
|
*/
|
5
|
-
export type Expand<T> = T extends (...args: infer A) => infer R
|
5
|
+
export type Expand<T> = T extends (...args: infer A) => infer R
|
6
|
+
? (...args: Expand<A>) => Expand<R>
|
7
|
+
: T extends infer O
|
8
|
+
? { [K in keyof O]: O[K] }
|
9
|
+
: never;
|
6
10
|
|
7
11
|
/**
|
8
12
|
* Recursivly expands the type T (for intellisense and debugging)
|
@@ -52,14 +56,22 @@ export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
|
|
52
56
|
* @see https://dev.to/tmhao2005/ts-useful-advanced-types-3k5e
|
53
57
|
*/
|
54
58
|
export type NestedKeys<T extends object> = {
|
55
|
-
[P in keyof T & (string | number)]: T[P] extends Date
|
59
|
+
[P in keyof T & (string | number)]: T[P] extends Date
|
60
|
+
? `${P}`
|
61
|
+
: T[P] extends Record<string, unknown>
|
62
|
+
? `${P}` | `${P}.${NestedKeys<T[P]>}`
|
63
|
+
: `${P}`;
|
56
64
|
}[keyof T & (string | number)];
|
57
65
|
|
58
66
|
/**
|
59
67
|
* @see https://dev.to/tmhao2005/ts-useful-advanced-types-3k5e
|
60
68
|
*/
|
61
69
|
export type PartialRecursive<T> = {
|
62
|
-
[P in keyof T]?: T[P] extends (infer U)[]
|
70
|
+
[P in keyof T]?: T[P] extends (infer U)[]
|
71
|
+
? PartialRecursive<U>[]
|
72
|
+
: T[P] extends object | undefined
|
73
|
+
? PartialRecursive<T[P]>
|
74
|
+
: T[P];
|
63
75
|
};
|
64
76
|
|
65
77
|
/**
|
@@ -68,7 +80,9 @@ export type PartialRecursive<T> = {
|
|
68
80
|
*/
|
69
81
|
export type UnionKeys<T> = T extends T ? keyof T : never;
|
70
82
|
|
71
|
-
type StrictUnionHelper<T, TAll> = T extends unknown
|
83
|
+
type StrictUnionHelper<T, TAll> = T extends unknown
|
84
|
+
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>>
|
85
|
+
: never;
|
72
86
|
|
73
87
|
/**
|
74
88
|
* @see https://stackoverflow.com/a/65805753/17637456
|
@@ -130,7 +144,8 @@ export type Remove<A extends unknown[], B extends unknown[]> = Empty extends B ?
|
|
130
144
|
*/
|
131
145
|
export type Length<T extends { length: number }> = T['length'];
|
132
146
|
|
133
|
-
type _FromLength<N extends number, R extends unknown[] = Empty> =
|
147
|
+
type _FromLength<N extends number, R extends unknown[] = Empty> =
|
148
|
+
Length<R> extends N ? R : _FromLength<N, Unshift<R, 0>>;
|
134
149
|
|
135
150
|
/**
|
136
151
|
* Creates a tuple of length N
|
@@ -162,12 +177,20 @@ export type Subtract<A extends number, B extends number> = Length<Remove<_FromLe
|
|
162
177
|
/**
|
163
178
|
* Gets the type of an array's members
|
164
179
|
*/
|
165
|
-
export type Member<T, D = null> = D extends 0
|
180
|
+
export type Member<T, D = null> = D extends 0
|
181
|
+
? T
|
182
|
+
: T extends (infer U)[]
|
183
|
+
? Member<U, D extends number ? Decrement<D> : null>
|
184
|
+
: T;
|
166
185
|
|
167
186
|
/**
|
168
187
|
* Flattens an array
|
169
188
|
*/
|
170
|
-
export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[]
|
189
|
+
export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[]
|
190
|
+
? Member<Exclude<U, A>, D>[]
|
191
|
+
: A extends unknown[]
|
192
|
+
? { [K in keyof A]: Member<A[K], D> }
|
193
|
+
: A;
|
171
194
|
|
172
195
|
/**
|
173
196
|
* Whether T is a tuple
|
@@ -178,7 +201,11 @@ export type IsTuple<T> = T extends [] ? false : T extends [infer _Head, ...infer
|
|
178
201
|
/**
|
179
202
|
* Flattens a tuple
|
180
203
|
*/
|
181
|
-
export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest]
|
204
|
+
export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest]
|
205
|
+
? U extends unknown[]
|
206
|
+
? [...U, ...FlattenTuple<Rest>]
|
207
|
+
: [U, ...FlattenTuple<Rest>]
|
208
|
+
: [];
|
182
209
|
|
183
210
|
/**
|
184
211
|
* Flattens an array or tuple
|
@@ -195,7 +222,9 @@ export type Tuple<T, N extends number> = _Tuple<T, N>;
|
|
195
222
|
/**
|
196
223
|
* Makes all members of the tuple T optional
|
197
224
|
*/
|
198
|
-
export type OptionalTuple<T extends unknown[]> = T extends [infer Head, ...infer Tail]
|
225
|
+
export type OptionalTuple<T extends unknown[]> = T extends [infer Head, ...infer Tail]
|
226
|
+
? [Head?, ...OptionalTuple<Tail>]
|
227
|
+
: T;
|
199
228
|
|
200
229
|
/**
|
201
230
|
* Keys of a Map
|
@@ -220,7 +249,9 @@ export type LastOfUnion<T> = UnionToIntersection<T extends any ? () => T : never
|
|
220
249
|
* Converts a union to a tuple
|
221
250
|
* @see https://stackoverflow.com/a/55128956/17637456
|
222
251
|
*/
|
223
|
-
export type UnionToTuple<T, L = LastOfUnion<T>, N = [T] extends [never] ? true : false> = true extends N
|
252
|
+
export type UnionToTuple<T, L = LastOfUnion<T>, N = [T] extends [never] ? true : false> = true extends N
|
253
|
+
? []
|
254
|
+
: Push<UnionToTuple<Exclude<T, L>>, L>;
|
224
255
|
|
225
256
|
/**
|
226
257
|
* Makes properties with keys assignable to K in T required
|
package/src/version.ts
CHANGED
@@ -8,7 +8,11 @@ export type WithPre = `${Part}${Sep}${string}${Sep | '.'}${Part | number}`;
|
|
8
8
|
|
9
9
|
export type Full = Part | WithPre;
|
10
10
|
|
11
|
-
type Type<S extends string, Acc extends string = ''> = S extends `${infer First}${infer Rest}`
|
11
|
+
type Type<S extends string, Acc extends string = ''> = S extends `${infer First}${infer Rest}`
|
12
|
+
? First extends Sep | '.'
|
13
|
+
? Acc
|
14
|
+
: Type<Rest, `${Acc}${First}`>
|
15
|
+
: Acc;
|
12
16
|
|
13
17
|
export type Parse<T extends Full, StripCore extends boolean> = T extends `${infer Core}${Sep}${infer Rest}`
|
14
18
|
? Rest extends `${infer U}`
|
@@ -43,6 +47,8 @@ export function parse<const T extends Full>(full: T): Parse<T, false>;
|
|
43
47
|
export function parse<const T extends Full, const S extends boolean>(full: T, stripCore: S): Parse<T, S>;
|
44
48
|
export function parse<const T extends Full, const S extends boolean>(full: T, stripCore?: S): Parse<T, S> {
|
45
49
|
const { type, pre, core } = regex.exec(full)!.groups!;
|
46
|
-
const display = type
|
50
|
+
const display = type
|
51
|
+
? `${stripCore && core == '1.0.0' ? '' : core + ' '}${capitalize(type)}${pre ? ` ${pre}` : ''}`
|
52
|
+
: core;
|
47
53
|
return { full, core, pre, type, display } as Parse<T, S>;
|
48
54
|
}
|