8000 refactor!: generate type maps · unjs/undio@c2ff49e · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit c2ff49e

Browse files
committed
refactor!: generate type maps
1 parent bee1e1e commit c2ff49e

15 files changed

+329
-187
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020
"dist"
2121
],
2222
"scripts": {
23-
"build": "unbuild",
23+
"build": "pnpm gen-maps && unbuild",
2424
"dev": "vitest dev",
25+
"gen-maps": "jiti ./scripts/gen-maps.ts",
2526
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test",
2627
"lint:fix": "automd && eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test -w",
2728
"prepack": "pnpm build",
@@ -45,4 +46,4 @@
4546
"vitest": "^1.4.0"
4647
},
4748
"packageManager": "pnpm@8.12.1"
48-
}
49+
}

scripts/gen-maps.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { writeFileSync } from "node:fs";
2+
3+
const types = [
4+
"arrayBuffer",
5+
"blob",
6+
"dataView",
7+
"numberArray",
8+
"readableStream",
9+
"response",
10+
"string",
11+
"uint8Array",
12+
];
13+
14+
const importLines: string[] = [];
15+
const code: string[] = [];
16+
17+
for (const to of types) {
18+
const toAssertName = `assert${upperFirst(to)}`;
19+
importLines.push(toAssertName);
20+
code.push(`export const _to${upperFirst(to)} = {`);
21+
for (const from of types) {
22+
if (to === from) {
23+
code.push(
24+
` ${upperFirst(from)}: (input: unknown) => (${toAssertName}(input), input),`,
25+
);
26+
continue;
27+
}
28+
const fnName = `${from}To${upperFirst(to)}`;
29+
importLines.push(fnName);
30+
code.push(` ${upperFirst(from)}: ${fnName},`);
31+
}
32+
code.push("} as const;", "");
33+
}
34+
35+
const genCode = `// Auto generated using gen-maps script
36+
import {
37+
${importLines.map((l) => `${l},`).join("\n ")}
38+
} from "./data-types";
39+
40+
${code.join("\n")}
41+
export const _to = {
42+
${types.map((t) => `${upperFirst(t)}: _to${upperFirst(t)},`).join("\n ")}\n} as const;
43+
`;
44+
45+
writeFileSync(
46+
new URL("../src/convert-maps.ts", import.meta.url),
47+
genCode,
48+
"utf8",
49+
);
50+
51+
function upperFirst(str: string) {
52+
return str[0].toUpperCase() + str.slice(1);
53+
}

src/convert-maps.ts

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Auto generated using gen-maps script
2+
import {
3+
assertArrayBuffer,
4+
blobToArrayBuffer,
5+
dataViewToArrayBuffer,
6+
numberArrayToArrayBuffer,
7+
readableStreamToArrayBuffer,
8+
responseToArrayBuffer,
9+
stringToArrayBuffer,
10+
uint8ArrayToArrayBuffer,
11+
assertBlob,
12+
arrayBufferToBlob,
13+
dataViewToBlob,
14+
numberArrayToBlob,
15+
readableStreamToBlob,
16+
responseToBlob,
17+
stringToBlob,
18+
uint8ArrayToBlob,
19+
assertDataView,
20+
arrayBufferToDataView,
21+
blobToDataView,
22+
numberArrayToDataView,
23+
readableStreamToDataView,
24+
responseToDataView,
25+
stringToDataView,
26+
uint8ArrayToDataView,
27+
assertNumberArray,
28+
arrayBufferToNumberArray,
29+
blobToNumberArray,
30+
dataViewToNumberArray,
31+
readableStreamToNumberArray,
32+
responseToNumberArray,
33+
stringToNumberArray,
34+
uint8ArrayToNumberArray,
35+
assertReadableStream,
36+
arrayBufferToReadableStream,
37+
blobToReadableStream,
38+
dataViewToReadableStream,
39+
numberArrayToReadableStream,
40+
responseToReadableStream,
41+
stringToReadableStream,
42+
uint8ArrayToReadableStream,
43+
assertResponse,
44+
arrayBufferToResponse,
45+
blobToResponse,
46+
dataViewToResponse,
47+
numberArrayToResponse,
48+
readableStreamToResponse,
49+
stringToResponse,
50+
uint8ArrayToResponse,
51+
assertString,
52+
arrayBufferToString,
53+
blobToString,
54+
dataViewToString,
55+
numberArrayToString,
56+
readableStreamToString,
57+
responseToString,
58+
uint8ArrayToString,
59+
assertUint8Array,
60+
arrayBufferToUint8Array,
61+
blobToUint8Array,
62+
dataViewToUint8Array,
63+
numberArrayToUint8Array,
64+
readableStreamToUint8Array,
65+
responseToUint8Array,
66+
stringToUint8Array,
67+
} from "./data-types";
68+
69+
export const _toArrayBuffer = {
70+
ArrayBuffer: (input: unknown) => (assertArrayBuffer(input), input),
71+
Blob: blobToArrayBuffer,
72+
DataView: dataViewToArrayBuffer,
73+
NumberArray: numberArrayToArrayBuffer,
74+
ReadableStream: readableStreamToArrayBuffer,
75+
Response: responseToArrayBuffer,
76+
String: stringToArrayBuffer,
77+
Uint8Array: uint8ArrayToArrayBuffer,
78+
} as const;
79+
80+
export const _toBlob = {
81+
ArrayBuffer: arrayBufferToBlob,
82+
Blob: (input: unknown) => (assertBlob(input), input),
83+
DataView: dataViewToBlob,
84+
NumberArray: numberArrayToBlob,
85+
ReadableStream: readableStreamToBlob,
86+
Response: responseToBlob,
87+
String: stringToBlob,
88+
Uint8Array: uint8ArrayToBlob,
89+
} as const;
90+
91+
export const _toDataView = {
92+
ArrayBuffer: arrayBufferToDataView,
93+
Blob: blobToDataView,
94+
DataView: (input: unknown) => (assertDataView(input), input),
95+
NumberArray: numberArrayToDataView,
96+
ReadableStream: readableStreamToDataView,
97+
Response: responseToDataView,
98+
String: stringToDataView,
99+
Uint8Array: uint8ArrayToDataView,
100+
} as const;
101+
102+
export const _toNumberArray = {
103+
ArrayBuffer: arrayBufferToNumberArray,
104+
Blob: blobToNumberArray,
105+
DataView: dataViewToNumberArray,
106+
NumberArray: (input: unknown) => (assertNumberArray(input), input),
107+
ReadableStream: readableStreamToNumberArray,
108+
Response: responseToNumberArray,
109+
String: stringToNumberArray,
110+
Uint8Array: uint8ArrayToNumberArray,
111+
} as const;
112+
113+
export const _toReadableStream = {
114+
ArrayBuffer: arrayBufferToReadableStream,
115+
Blob: blobToReadableStream,
116+
DataView: dataViewToReadableStream,
117+
NumberArray: numberArrayToReadableStream,
118+
ReadableStream: (input: unknown) => (assertReadableStream(input), input),
119+
Response: responseToReadableStream,
120+
String: stringToReadableStream,
121+
Uint8Array: uint8ArrayToReadableStream,
122+
} as const;
123+
124+
export const _toResponse = {
125+
ArrayBuffer: arrayBufferToResponse,
126+
Blob: blobToResponse,
127+
DataView: dataViewToResponse,
128+
NumberArray: numberArrayToResponse,
129+
ReadableStream: readableStreamToResponse,
130+
Response: (input: unknown) => (assertResponse(input), input),
131+
String: stringToResponse,
132+
Uint8Array: uint8ArrayToResponse,
133+
} as const;
134+
135+
export const _toString = {
136+
ArrayBuffer: arrayBufferToString,
137+
Blob: blobToString,
138+
DataView: dataViewToString,
139+
NumberArray: numberArrayToString,
140+
ReadableStream: readableStreamToString,
141+
Response: responseToString,
142+
String: (input: unknown) => (assertString(input), input),
143+
Uint8Array: uint8ArrayToString,
144+
} as const;
145+
146+
export const _toUint8Array = {
147+
ArrayBuffer: arrayBufferToUint8Array,
148+
Blob: blobToUint8Array,
149+
DataView: dataViewToUint8Array,
150+
NumberArray: numberArrayToUint8Array,
151+
ReadableStream: readableStreamToUint8Array,
152+
Response: responseToUint8Array,
153+
String: stringToUint8Array,
154+
Uint8Array: (input: unknown) => (assertUint8Array(input), input),
155+
} as const;
156+
157+
export const _to = {
158+
ArrayBuffer: _toArrayBuffer,
159+
Blob: _toBlob,
160+
DataView: _toDataView,
161+
NumberArray: _toNumberArray,
162+
ReadableStream: _toReadableStream,
163+
Response: _toResponse,
164+
String: _toString,
165+
Uint8Array: _toUint8Array,
166+
} as const;

src/convert.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { DataType, DataTypeName } from "./types";
2+
import { detectType } from "./detect";
3+
import {
4+
_toArrayBuffer,
5+
_toBlob,
6+
_toDataView,
7+
_toNumberArray,
8+
_toReadableStream,
9+
_toResponse,
10+
_toString,
11+
_toUint8Array,
12+
_to,
13+
} from "./convert-maps";
14+
15+
/**
16+
* Convert from any value to any supported data type
17+
*/
18+
export function convertTo<T extends DataTypeName>(
19+
toType: T,
20+
input: DataType,
21+
): any {
22+
const _map = _to[toType];
23+
if (!_map) {
24+
throw new Error(`Conversion to ${toType} is not supported.`);
25+
}
26+
const fromType = detectType(input);
27+
return _convertTo(fromType, input, _map);
28+
}
29+
30+
/**
31+
* Convert from any value to [ArrayBuffer][ArrayBuffer]
32+
* @group ArrayBuffer
33+
*/
34+
export const toArrayBuffer = (input: DataType) =>
35+
_convertTo<ArrayBuffer>("ArrayBuffer", input, _toArrayBuffer);
36+
37+
/**
38+
* Convert from any value to [Blob][Blob]
39+
* @group Blob
40+
*/
41+
export const toBlob = (input: DataType) =>
42+
_convertTo<Blob>("Blob", input, _toBlob);
43+
44+
/**
45+
* Convert from any value to [DataView][DataView]
46+
* @group DataView
47+
*/
48+
export const toDataView = (input: DataType) =>
49+
_convertTo<DataView>("DataView", input, _toDataView);
50+
51+
/**
52+
* Convert from any value to [Number Array][Number Array]
53+
* @group NumberArray
54+
*/
55+
export const toNumberArray = (input: DataType) =>
56+
_convertTo<number[]>("NumberArray", input, _toNumberArray);
57+
58+
/**
59+
* Convert from any value to [ReadableStream][ReadableStream]
60+
* @group ReadableStream
61+
*/
62+
export const toReadableStream = (input: DataType) =>
63+
_convertTo<ReadableStream>("ReadableStream", input, _toReadableStream);
64+
65+
/**
66+
* Convert from any value to [Response][Response]
67+
* @group ReadableStream
68+
*/
69+
export const toResponse = (input: DataType) =>
70+
_convertTo<ReadableStream>("Response", input, _toResponse);
71+
72+
/**
73+
* Convert from any value to [String][String]
74+
* @group String
75+
*/
76+
export const toString = (input: DataType) =>
77+
_convertTo<string>("String", input, _toString);
78+
79+
/**
80+
* Convert from any value to [Uinit8Array][Uinit8Array]
81+
* @group Uinit8Array
82+
*/
83+
export const toUnit8Array = (input: DataType) =>
84+
_convertTo<string>("Uint8Array", input, _toUint8Array);
85+
86+
function _convertTo<T extends DataType>(
87+
name: DataTypeName,
88+
input: DataType,
89+
map: Record<DataTypeName, any /* (input: DataType) => T */>,
90+
) {
91+
const converter = map[name];
92+
if (converter === undefined) {
93+
throw new Error(`Conversion from ${name} is not supported.`);
94+
}
95+
return converter(input);
96+
}

src/data-types/_utils.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
import { detectType } from "../detect";
2-
import { DataTypeName, DataType } from "../types";
3-
import {} from "./array-buffer";
4-
51
type TestFn<T> = (input: unknown) => input is T;
62

73
export function assertType<T>(
@@ -13,22 +9,3 @@ export function assertType<T>(
139
throw new TypeError(`Expected ${name} type but got ${typeof test}.`);
1410
}
1511
}
16-
17-
type DataNameToType = Record<DataTypeName, DataType>;
18-
export type ConvertMap<FROM extends DataType> = {
19-
[TO in DataTypeName]: (
20-
input: FROM,
21-
) => DataNameToType[TO] | Promise<DataNameToType[TO]>;
22-
};
23-
24-
export function convertTo<T extends DataType>(
25-
name: string,
26-
input: DataType,
27-
convertMap: ConvertMap<T>,
28-
) {
29-
const typeName = detectType(input);
30-
if (typeName in convertMap) {
31-
return convertMap[typeName](input as T);
32-
}
33-
throw new TypeError(`Cannot convert ${typeName} to ${name}.`);
34-
}

0 commit comments

Comments
 (0)
0