expand-my-type 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -2
- package/dist/cli.js +214 -0
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -32,14 +32,67 @@ Under the hood, it uses the [TypeScript Compiler API][ts-compiler-api] to expand
|
|
|
32
32
|
the type expression and optionally formats the output using
|
|
33
33
|
[Prettier][prettier].
|
|
34
34
|
|
|
35
|
-
#
|
|
35
|
+
# CLI
|
|
36
|
+
|
|
37
|
+
### Installation
|
|
38
|
+
|
|
39
|
+
To install the CLI globally, run:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npm install -g expand-my-type
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Alternatively, the CLI can be run using `npx`:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
npx expand-my-type
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### CLI Usage
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Usage:
|
|
55
|
+
expand-my-type [options] <source-file> <expression>
|
|
56
|
+
|
|
57
|
+
Options:
|
|
58
|
+
-h, --help Show this help message
|
|
59
|
+
-p, --prettify Prettify the output
|
|
60
|
+
-P, --no-prettify Do not prettify the output
|
|
61
|
+
-c, --tsconfig <file> Use the specified tsconfig.json file
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Given a file named `example.ts` with the following contents:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
interface SomeInterface {
|
|
68
|
+
a: number;
|
|
69
|
+
b?: string;
|
|
70
|
+
c: number | undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
type SomeType = {
|
|
74
|
+
d: number;
|
|
75
|
+
e: SomeInterface;
|
|
76
|
+
f: () => void;
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Running the following command expands the type expression `SomeType["e"]`:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
expand-my-type example.ts 'SomeType["e"]'
|
|
84
|
+
# Output:
|
|
85
|
+
# { a: number; b?: string; c: number }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
# API
|
|
36
89
|
|
|
37
90
|
This package exports a function named `expandMyType` that can be used in one of
|
|
38
91
|
the following ways:
|
|
39
92
|
|
|
40
93
|
1. Expand the type expression in a source file:
|
|
41
94
|
|
|
42
|
-
Given a file named `example.ts` with the following
|
|
95
|
+
Given a file named `example.ts` with the following contents:
|
|
43
96
|
|
|
44
97
|
```typescript
|
|
45
98
|
interface SomeInterface {
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/create-expander-compiler-host.ts
|
|
4
|
+
import ts from "typescript";
|
|
5
|
+
var createExpanderCompilerHost = (sourceFileName2, typeExpression2, compilerOptions, getSourceFileFunction) => {
|
|
6
|
+
const customCompilerHost = ts.createCompilerHost(compilerOptions ?? {});
|
|
7
|
+
const originalGetSourceFile = customCompilerHost.getSourceFile;
|
|
8
|
+
customCompilerHost.getSourceFile = (fileName, ...args) => {
|
|
9
|
+
if (fileName === sourceFileName2) {
|
|
10
|
+
const sourceFile = (getSourceFileFunction ?? originalGetSourceFile)(
|
|
11
|
+
fileName,
|
|
12
|
+
...args
|
|
13
|
+
);
|
|
14
|
+
if (sourceFile === void 0) {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
const sourceText = [
|
|
18
|
+
...[
|
|
19
|
+
"type __TYPE_EXPANDER_RESULT__ = __TYPE_EXPANDER_EXPAND__<__TYPE_EXPANDER_EXPRESSION__>;",
|
|
20
|
+
`type __TYPE_EXPANDER_EXPRESSION__ = ${typeExpression2};`,
|
|
21
|
+
"type __TYPE_EXPANDER_EXPAND__<T> = {",
|
|
22
|
+
" [K in keyof T]: __TYPE_EXPANDER_EXPAND__<T[K]>;",
|
|
23
|
+
"} & {};"
|
|
24
|
+
],
|
|
25
|
+
sourceFile.getFullText()
|
|
26
|
+
].join("\n");
|
|
27
|
+
return ts.createSourceFile(
|
|
28
|
+
fileName,
|
|
29
|
+
sourceText,
|
|
30
|
+
sourceFile.languageVersion,
|
|
31
|
+
true
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return originalGetSourceFile(fileName, ...args);
|
|
35
|
+
};
|
|
36
|
+
return customCompilerHost;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/index.ts
|
|
40
|
+
import { format } from "prettier";
|
|
41
|
+
import ts2 from "typescript";
|
|
42
|
+
var findTypeExpanderResultNode = (node) => {
|
|
43
|
+
if (node.getChildCount() == 0) {
|
|
44
|
+
if (!ts2.isIdentifier(node)) {
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
return node;
|
|
48
|
+
}
|
|
49
|
+
return ts2.forEachChild(node, findTypeExpanderResultNode);
|
|
50
|
+
};
|
|
51
|
+
async function expandMyType(options) {
|
|
52
|
+
if (options.typeExpression.trim() === "") {
|
|
53
|
+
return "never";
|
|
54
|
+
}
|
|
55
|
+
if ("sourceText" in options) {
|
|
56
|
+
const sourceFile2 = ts2.createSourceFile(
|
|
57
|
+
"test.ts",
|
|
58
|
+
options.sourceText,
|
|
59
|
+
ts2.ScriptTarget.Latest,
|
|
60
|
+
true
|
|
61
|
+
);
|
|
62
|
+
return expandMyType({
|
|
63
|
+
sourceFileName: "test.ts",
|
|
64
|
+
typeExpression: options.typeExpression,
|
|
65
|
+
getSourceFileFunction: () => sourceFile2,
|
|
66
|
+
tsCompilerOptions: options.tsCompilerOptions
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const tsCompilerOptions = options.tsCompilerOptions ?? {
|
|
70
|
+
noEmit: true,
|
|
71
|
+
allowSyntheticDefaultImports: true,
|
|
72
|
+
allowArbitraryExtensions: true,
|
|
73
|
+
allowImportingTsExtensions: true,
|
|
74
|
+
allowJs: true
|
|
75
|
+
};
|
|
76
|
+
const compilerHost = createExpanderCompilerHost(
|
|
77
|
+
options.sourceFileName,
|
|
78
|
+
options.typeExpression,
|
|
79
|
+
tsCompilerOptions,
|
|
80
|
+
options.getSourceFileFunction
|
|
81
|
+
);
|
|
82
|
+
const program = ts2.createProgram(
|
|
83
|
+
[options.sourceFileName],
|
|
84
|
+
tsCompilerOptions,
|
|
85
|
+
compilerHost
|
|
86
|
+
);
|
|
87
|
+
const sourceFile = program.getSourceFile(options.sourceFileName);
|
|
88
|
+
if (!sourceFile) {
|
|
89
|
+
throw new Error("Source file not found!");
|
|
90
|
+
}
|
|
91
|
+
const firstIdentifier = findTypeExpanderResultNode(sourceFile);
|
|
92
|
+
if (!firstIdentifier) {
|
|
93
|
+
throw new Error("No node found!");
|
|
94
|
+
}
|
|
95
|
+
const typeChecker = program.getTypeChecker();
|
|
96
|
+
const expandedType = typeChecker.typeToString(
|
|
97
|
+
typeChecker.getTypeAtLocation(firstIdentifier),
|
|
98
|
+
void 0,
|
|
99
|
+
ts2.TypeFormatFlags.NodeBuilderFlagsMask
|
|
100
|
+
);
|
|
101
|
+
if (options.prettify && options.prettify.enabled === false) {
|
|
102
|
+
return expandedType;
|
|
103
|
+
}
|
|
104
|
+
const dummyTypeName = "__TYPE_EXPANDER_RESULT__";
|
|
105
|
+
return (await format(
|
|
106
|
+
`type ${dummyTypeName} = ${expandedType}`,
|
|
107
|
+
options.prettify?.options ?? {
|
|
108
|
+
parser: "typescript",
|
|
109
|
+
semi: false
|
|
110
|
+
}
|
|
111
|
+
)).trim().substring(`type ${dummyTypeName} = `.length);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/cli.ts
|
|
115
|
+
import path from "node:path";
|
|
116
|
+
import { parseArgs } from "node:util";
|
|
117
|
+
import ts3 from "typescript";
|
|
118
|
+
var tryParse = (options) => {
|
|
119
|
+
let result2;
|
|
120
|
+
try {
|
|
121
|
+
result2 = parseArgs({
|
|
122
|
+
options,
|
|
123
|
+
tokens: true,
|
|
124
|
+
allowPositionals: true
|
|
125
|
+
});
|
|
126
|
+
} catch (error2) {
|
|
127
|
+
return {
|
|
128
|
+
error: error2,
|
|
129
|
+
values: {},
|
|
130
|
+
positionals: []
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const { tokens, values: values2, positionals: positionals2 } = result2;
|
|
134
|
+
for (const token of tokens ?? []) {
|
|
135
|
+
if (token.kind === "option-terminator" || token.kind === "positional") {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (token.name.startsWith("no-")) {
|
|
139
|
+
const positiveName = token.name.slice("no-".length);
|
|
140
|
+
values2[positiveName] = false;
|
|
141
|
+
delete values2[token.name];
|
|
142
|
+
} else {
|
|
143
|
+
values2[token.name] = token.value ?? true;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
error: void 0,
|
|
148
|
+
values: values2,
|
|
149
|
+
positionals: positionals2
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
var { error, values, positionals } = tryParse({
|
|
153
|
+
help: {
|
|
154
|
+
type: "boolean",
|
|
155
|
+
short: "h"
|
|
156
|
+
},
|
|
157
|
+
prettify: {
|
|
158
|
+
type: "boolean",
|
|
159
|
+
short: "p",
|
|
160
|
+
default: true
|
|
161
|
+
},
|
|
162
|
+
"no-prettify": {
|
|
163
|
+
type: "boolean",
|
|
164
|
+
short: "P"
|
|
165
|
+
},
|
|
166
|
+
tsconfig: {
|
|
167
|
+
type: "string",
|
|
168
|
+
short: "c"
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
if (error) {
|
|
172
|
+
console.error(error.message);
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
var usagePrompt = [
|
|
176
|
+
"Usage:",
|
|
177
|
+
" expand-my-type [options] <source-file> <expression>",
|
|
178
|
+
"",
|
|
179
|
+
"Options:",
|
|
180
|
+
" -h, --help Show this help message",
|
|
181
|
+
" -p, --prettify Prettify the output",
|
|
182
|
+
" -P, --no-prettify Do not prettify the output",
|
|
183
|
+
" -c, --tsconfig <file> Use the specified tsconfig.json file"
|
|
184
|
+
].join("\n");
|
|
185
|
+
if (positionals.length !== 2) {
|
|
186
|
+
console.error(usagePrompt);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
if (values.help) {
|
|
190
|
+
console.error(usagePrompt);
|
|
191
|
+
process.exit(0);
|
|
192
|
+
}
|
|
193
|
+
var [sourceFileName, typeExpression] = positionals;
|
|
194
|
+
var { prettify, tsconfig: tsConfigFileName } = values;
|
|
195
|
+
var tsParsedCommandLine;
|
|
196
|
+
if (tsConfigFileName) {
|
|
197
|
+
const configFile = ts3.readConfigFile(tsConfigFileName, ts3.sys.readFile);
|
|
198
|
+
const compilerOptions = ts3.parseJsonConfigFileContent(
|
|
199
|
+
configFile.config,
|
|
200
|
+
ts3.sys,
|
|
201
|
+
"./"
|
|
202
|
+
);
|
|
203
|
+
tsParsedCommandLine = compilerOptions;
|
|
204
|
+
}
|
|
205
|
+
var result = await expandMyType({
|
|
206
|
+
sourceFileName: path.resolve(sourceFileName),
|
|
207
|
+
typeExpression,
|
|
208
|
+
prettify: {
|
|
209
|
+
enabled: prettify
|
|
210
|
+
},
|
|
211
|
+
tsCompilerOptions: tsParsedCommandLine?.options
|
|
212
|
+
});
|
|
213
|
+
console.log(result);
|
|
214
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NyZWF0ZS1leHBhbmRlci1jb21waWxlci1ob3N0LnRzIiwgIi4uL3NyYy9pbmRleC50cyIsICIuLi9zcmMvY2xpLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY3VzdG9tIGNvbXBpbGVyIGhvc3QgdGhhdCBhdWdtZW50cyB0aGUgc3BlY2lmaWVkIHNvdXJjZSBmaWxlIGZvciBleHBhbmRpbmcgYSB0eXBlIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIHNvdXJjZUZpbGVOYW1lIE5hbWUgb2YgdGhlIHNvdXJjZSBmaWxlIHRvIGF1Z21lbnQuXG4gKiBAcGFyYW0gdHlwZUV4cHJlc3Npb24gVHlwZSBleHByZXNzaW9uLlxuICogQHBhcmFtIGNvbXBpbGVyT3B0aW9ucyBUeXBlU2NyaXB0IGNvbXBpbGVyIG9wdGlvbnMuXG4gKiBAcGFyYW0gZ2V0U291cmNlRmlsZUZ1bmN0aW9uIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYHRzLkNvbXBpbGVySG9zdFtcImdldFNvdXJjZUZpbGVcIl1gIGZ1bmN0aW9uLlxuICogQHJldHVybnMgQSBjdXN0b20gY29tcGlsZXIgaG9zdCB0aGF0IHJldHVybnMgYW4gYXVnbWVudGVkIHNvdXJjZSBmaWxlIHRoYXQgY2FuIGJlIHVzZWQgdG8gZXhwYW5kIHRoZSB0eXBlIGV4cHJlc3Npb24uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVFeHBhbmRlckNvbXBpbGVySG9zdCA9IChcbiAgc291cmNlRmlsZU5hbWU6IHN0cmluZyxcbiAgdHlwZUV4cHJlc3Npb246IHN0cmluZyxcbiAgY29tcGlsZXJPcHRpb25zPzogdHMuQ29tcGlsZXJPcHRpb25zLFxuICBnZXRTb3VyY2VGaWxlRnVuY3Rpb24/OiB0cy5Db21waWxlckhvc3RbXCJnZXRTb3VyY2VGaWxlXCJdLFxuKSA9PiB7XG4gIGNvbnN0IGN1c3RvbUNvbXBpbGVySG9zdCA9IHRzLmNyZWF0ZUNvbXBpbGVySG9zdChjb21waWxlck9wdGlvbnMgPz8ge30pO1xuICBjb25zdCBvcmlnaW5hbEdldFNvdXJjZUZpbGUgPSBjdXN0b21Db21waWxlckhvc3QuZ2V0U291cmNlRmlsZTtcblxuICBjdXN0b21Db21waWxlckhvc3QuZ2V0U291cmNlRmlsZSA9IChmaWxlTmFtZSwgLi4uYXJncykgPT4ge1xuICAgIGlmIChmaWxlTmFtZSA9PT0gc291cmNlRmlsZU5hbWUpIHtcbiAgICAgIGNvbnN0IHNvdXJjZUZpbGUgPSAoZ2V0U291cmNlRmlsZUZ1bmN0aW9uID8/IG9yaWdpbmFsR2V0U291cmNlRmlsZSkoXG4gICAgICAgIGZpbGVOYW1lLFxuICAgICAgICAuLi5hcmdzLFxuICAgICAgKTtcblxuICAgICAgaWYgKHNvdXJjZUZpbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3VyY2VUZXh0ID0gW1xuICAgICAgICAuLi5bXG4gICAgICAgICAgXCJ0eXBlIF9fVFlQRV9FWFBBTkRFUl9SRVNVTFRfXyA9IF9fVFlQRV9FWFBBTkRFUl9FWFBBTkRfXzxfX1RZUEVfRVhQQU5ERVJfRVhQUkVTU0lPTl9fPjtcIixcbiAgICAgICAgICBgdHlwZSBfX1RZUEVfRVhQQU5ERVJfRVhQUkVTU0lPTl9fID0gJHt0eXBlRXhwcmVzc2lvbn07YCxcbiAgICAgICAgICBcInR5cGUgX19UWVBFX0VYUEFOREVSX0VYUEFORF9fPFQ+ID0ge1wiLFxuICAgICAgICAgIFwiICBbSyBpbiBrZXlvZiBUXTogX19UWVBFX0VYUEFOREVSX0VYUEFORF9fPFRbS10+O1wiLFxuICAgICAgICAgIFwifSAmIHt9O1wiLFxuICAgICAgICBdLFxuICAgICAgICBzb3VyY2VGaWxlLmdldEZ1bGxUZXh0KCksXG4gICAgICBdLmpvaW4oXCJcXG5cIik7XG5cbiAgICAgIHJldHVybiB0cy5jcmVhdGVTb3VyY2VGaWxlKFxuICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgc291cmNlVGV4dCxcbiAgICAgICAgc291cmNlRmlsZS5sYW5ndWFnZVZlcnNpb24sXG4gICAgICAgIHRydWUsXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBvcmlnaW5hbEdldFNvdXJjZUZpbGUoZmlsZU5hbWUsIC4uLmFyZ3MpO1xuICB9O1xuXG4gIHJldHVybiBjdXN0b21Db21waWxlckhvc3Q7XG59O1xuIiwgImltcG9ydCB7IGNyZWF0ZUV4cGFuZGVyQ29tcGlsZXJIb3N0IH0gZnJvbSBcIi4vY3JlYXRlLWV4cGFuZGVyLWNvbXBpbGVyLWhvc3QudHNcIjtcbmltcG9ydCB7IGZvcm1hdCwgdHlwZSBPcHRpb25zIGFzIFByZXR0aWVyT3B0aW9ucyB9IGZyb20gXCJwcmV0dGllclwiO1xuaW1wb3J0IHRzIGZyb20gXCJ0eXBlc2NyaXB0XCI7XG5cbi8qKlxuICogRmluZHMgdGhlIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSBUWVBFX0VYUEFOREVSX1JFU1VMVCB0eXBlLlxuICpcbiAqIEBwYXJhbSBub2RlIE5vZGUgaW4gd2hpY2ggdGhlIFRZUEVfRVhQQU5ERVJfUkVTVUxUIHR5cGUgc2hvdWxkIGJlIHNlYXJjaGVkLlxuICogQHJldHVybnMgVGhlIG5vZGUgdGhhdCByZXByZXNlbnRzIHRoZSBUWVBFX0VYUEFOREVSX1JFU1VMVCB0eXBlLlxuICovXG5jb25zdCBmaW5kVHlwZUV4cGFuZGVyUmVzdWx0Tm9kZSA9IChub2RlOiB0cy5Ob2RlKTogdHMuTm9kZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChub2RlLmdldENoaWxkQ291bnQoKSA9PSAwKSB7XG4gICAgaWYgKCF0cy5pc0lkZW50aWZpZXIobm9kZSkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLy8gU2luY2Ugd2UgcHV0IHRoZSBfX1RZUEVfRVhQQU5ERVJfUkVTVUxUX18gdHlwZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZVxuICAgIC8vIGZpbGUsIHdlIGNhbiByZXR1cm4gdGhlIGZpcnN0IGlkZW50aWZpZXIgd2UgZmluZC5cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHJldHVybiB0cy5mb3JFYWNoQ2hpbGQobm9kZSwgZmluZFR5cGVFeHBhbmRlclJlc3VsdE5vZGUpO1xufTtcblxuZXhwb3J0IHR5cGUgRXhwYW5kVHlwZU9wdGlvbnNCYXNlID0ge1xuICAvKipcbiAgICogVGhlIHR5cGUgZXhwcmVzc2lvbiB0byBleHBhbmQuXG4gICAqIEBleGFtcGxlIFwiUmV0dXJuVHlwZTx0eXBlb2YgbXlGdW5jdGlvbj5cIlxuICAgKi9cbiAgdHlwZUV4cHJlc3Npb246IHN0cmluZztcblxuICAvKipcbiAgICogVHlwZVNjcmlwdCBjb21waWxlciBvcHRpb25zLlxuICAgKi9cbiAgdHNDb21waWxlck9wdGlvbnM/OiB0cy5Db21waWxlck9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIFByZXR0aWVyIG9wdGlvbnMuXG4gICAqL1xuICBwcmV0dGlmeT86IHtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIHByZXR0aWZ5IHRoZSBvdXRwdXQuXG4gICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAqL1xuICAgIGVuYWJsZWQ/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFByZXR0aWVyIG9wdGlvbnMuIERvbid0IGZvcmdldCB0byBzZXQgdGhlIHBhcnNlciB0byBcInR5cGVzY3JpcHRcIi5cbiAgICAgKiBAZGVmYXVsdCB7IHBhcnNlcjogXCJ0eXBlc2NyaXB0XCIsIHNlbWk6IGZhbHNlIH1cbiAgICAgKi9cbiAgICBvcHRpb25zPzogUHJldHRpZXJPcHRpb25zO1xuICB9O1xufTtcbmV4cG9ydCB0eXBlIEV4cGFuZFR5cGVGcm9tU291cmNlRmlsZU9wdGlvbnMgPSBFeHBhbmRUeXBlT3B0aW9uc0Jhc2UgJiB7XG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBzb3VyY2UgZmlsZSB0byBldmFsdWF0ZSB0aGUgdHlwZSBleHByZXNzaW9uIGluLlxuICAgKi9cbiAgc291cmNlRmlsZU5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgc291cmNlIGZpbGUuIFdoZW4gbm90IHNwZWNpZmllZCwgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBkZWZhdWx0IFR5cGVTY3JpcHQgY29tcGlsZXIgaG9zdCBpcyB1c2VkLlxuICAgKi9cbiAgZ2V0U291cmNlRmlsZUZ1bmN0aW9uPzogdHMuQ29tcGlsZXJIb3N0W1wiZ2V0U291cmNlRmlsZVwiXTtcbn07XG5leHBvcnQgdHlwZSBFeHBhbmRUeXBlRnJvbVNvdXJjZVRleHRPcHRpb25zID0gRXhwYW5kVHlwZU9wdGlvbnNCYXNlICYge1xuICAvKipcbiAgICogVHlwZVNjcmlwdCBzb3VyY2UgdGV4dCB0byBldmFsdWF0ZSB0aGUgdHlwZSBleHByZXNzaW9uIGluLlxuICAgKi9cbiAgc291cmNlVGV4dDogc3RyaW5nO1xufTtcbmV4cG9ydCB0eXBlIEV4cGFuZE15VHlwZU9wdGlvbnMgPVxuICB8IEV4cGFuZFR5cGVGcm9tU291cmNlRmlsZU9wdGlvbnNcbiAgfCBFeHBhbmRUeXBlRnJvbVNvdXJjZVRleHRPcHRpb25zO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhwYW5kTXlUeXBlKFxuICBvcHRpb25zOiBFeHBhbmRUeXBlRnJvbVNvdXJjZVRleHRPcHRpb25zLFxuKTogUHJvbWlzZTxzdHJpbmc+O1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4cGFuZE15VHlwZShcbiAgb3B0aW9uczogRXhwYW5kVHlwZUZyb21Tb3VyY2VGaWxlT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nPjtcblxuLyoqXG4gKiBFeHBhbmRzIGEgVHlwZVNjcmlwdCB0eXBlIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIG9wdGlvbnNcbiAqIEByZXR1cm5zIFRoZSBleHBhbmRlZCB0eXBlIGV4cHJlc3Npb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHBhbmRNeVR5cGUob3B0aW9uczogRXhwYW5kTXlUeXBlT3B0aW9ucykge1xuICBpZiAob3B0aW9ucy50eXBlRXhwcmVzc2lvbi50cmltKCkgPT09IFwiXCIpIHtcbiAgICByZXR1cm4gXCJuZXZlclwiO1xuICB9XG5cbiAgaWYgKFwic291cmNlVGV4dFwiIGluIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VyY2VGaWxlID0gdHMuY3JlYXRlU291cmNlRmlsZShcbiAgICAgIFwidGVzdC50c1wiLFxuICAgICAgb3B0aW9ucy5zb3VyY2VUZXh0LFxuICAgICAgdHMuU2NyaXB0VGFyZ2V0LkxhdGVzdCxcbiAgICAgIHRydWUsXG4gICAgKTtcblxuICAgIHJldHVybiBleHBhbmRNeVR5cGUoe1xuICAgICAgc291cmNlRmlsZU5hbWU6IFwidGVzdC50c1wiLFxuICAgICAgdHlwZUV4cHJlc3Npb246IG9wdGlvbnMudHlwZUV4cHJlc3Npb24sXG4gICAgICBnZXRTb3VyY2VGaWxlRnVuY3Rpb246ICgpID0+IHNvdXJjZUZpbGUsXG4gICAgICB0c0NvbXBpbGVyT3B0aW9uczogb3B0aW9ucy50c0NvbXBpbGVyT3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHRzQ29tcGlsZXJPcHRpb25zID0gb3B0aW9ucy50c0NvbXBpbGVyT3B0aW9ucyA/PyB7XG4gICAgbm9FbWl0OiB0cnVlLFxuXG4gICAgYWxsb3dTeW50aGV0aWNEZWZhdWx0SW1wb3J0czogdHJ1ZSxcbiAgICBhbGxvd0FyYml0cmFyeUV4dGVuc2lvbnM6IHRydWUsXG4gICAgYWxsb3dJbXBvcnRpbmdUc0V4dGVuc2lvbnM6IHRydWUsXG4gICAgYWxsb3dKczogdHJ1ZSxcbiAgfTtcblxuICBjb25zdCBjb21waWxlckhvc3QgPSBjcmVhdGVFeHBhbmRlckNvbXBpbGVySG9zdChcbiAgICBvcHRpb25zLnNvdXJjZUZpbGVOYW1lLFxuICAgIG9wdGlvbnMudHlwZUV4cHJlc3Npb24sXG4gICAgdHNDb21waWxlck9wdGlvbnMsXG4gICAgb3B0aW9ucy5nZXRTb3VyY2VGaWxlRnVuY3Rpb24sXG4gICk7XG5cbiAgY29uc3QgcHJvZ3JhbSA9IHRzLmNyZWF0ZVByb2dyYW0oXG4gICAgW29wdGlvbnMuc291cmNlRmlsZU5hbWVdLFxuICAgIHRzQ29tcGlsZXJPcHRpb25zLFxuICAgIGNvbXBpbGVySG9zdCxcbiAgKTtcblxuICBjb25zdCBzb3VyY2VGaWxlID0gcHJvZ3JhbS5nZXRTb3VyY2VGaWxlKG9wdGlvbnMuc291cmNlRmlsZU5hbWUpO1xuICBpZiAoIXNvdXJjZUZpbGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb3VyY2UgZmlsZSBub3QgZm91bmQhXCIpO1xuICB9XG5cbiAgY29uc3QgZmlyc3RJZGVudGlmaWVyID0gZmluZFR5cGVFeHBhbmRlclJlc3VsdE5vZGUoc291cmNlRmlsZSk7XG4gIGlmICghZmlyc3RJZGVudGlmaWVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbm9kZSBmb3VuZCFcIik7XG4gIH1cblxuICBjb25zdCB0eXBlQ2hlY2tlciA9IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKTtcbiAgY29uc3QgZXhwYW5kZWRUeXBlID0gdHlwZUNoZWNrZXIudHlwZVRvU3RyaW5nKFxuICAgIHR5cGVDaGVja2VyLmdldFR5cGVBdExvY2F0aW9uKGZpcnN0SWRlbnRpZmllciksXG4gICAgdW5kZWZpbmVkLFxuICAgIHRzLlR5cGVGb3JtYXRGbGFncy5Ob2RlQnVpbGRlckZsYWdzTWFzayxcbiAgKTtcblxuICBpZiAob3B0aW9ucy5wcmV0dGlmeSAmJiBvcHRpb25zLnByZXR0aWZ5LmVuYWJsZWQgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIGV4cGFuZGVkVHlwZTtcbiAgfVxuXG4gIGNvbnN0IGR1bW15VHlwZU5hbWUgPSBcIl9fVFlQRV9FWFBBTkRFUl9SRVNVTFRfX1wiO1xuXG4gIHJldHVybiAoXG4gICAgYXdhaXQgZm9ybWF0KFxuICAgICAgYHR5cGUgJHtkdW1teVR5cGVOYW1lfSA9ICR7ZXhwYW5kZWRUeXBlfWAsXG4gICAgICBvcHRpb25zLnByZXR0aWZ5Py5vcHRpb25zID8/IHtcbiAgICAgICAgcGFyc2VyOiBcInR5cGVzY3JpcHRcIixcbiAgICAgICAgc2VtaTogZmFsc2UsXG4gICAgICB9LFxuICAgIClcbiAgKVxuICAgIC50cmltKClcbiAgICAuc3Vic3RyaW5nKGB0eXBlICR7ZHVtbXlUeXBlTmFtZX0gPSBgLmxlbmd0aCk7XG59XG4iLCAiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuaW1wb3J0IHsgZXhwYW5kTXlUeXBlIH0gZnJvbSBcIi4vaW5kZXgudHNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IHBhcnNlQXJncywgdHlwZSBQYXJzZUFyZ3NDb25maWcgfSBmcm9tIFwibm9kZTp1dGlsXCI7XG5pbXBvcnQgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxudHlwZSBWYWx1ZXMgPSB7XG4gIGhlbHA/OiBib29sZWFuO1xuICBwcmV0dGlmeTogYm9vbGVhbjtcbiAgdHNjb25maWc/OiBzdHJpbmc7XG59O1xuXG5jb25zdCB0cnlQYXJzZSA9IDxcbiAgVmFsdWVzIGV4dGVuZHMgUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBzdHJpbmcgfCBib29sZWFuIHwgQXJyYXk8c3RyaW5nIHwgYm9vbGVhbj4gfCB1bmRlZmluZWRcbiAgPixcbiAgT3B0aW9ucyBleHRlbmRzIFBhcnNlQXJnc0NvbmZpZ1tcIm9wdGlvbnNcIl0gPSBQYXJzZUFyZ3NDb25maWdbXCJvcHRpb25zXCJdLFxuPihcbiAgb3B0aW9uczogT3B0aW9ucyxcbik6IHsgZXJyb3I/OiBFcnJvcjsgdmFsdWVzOiBWYWx1ZXM7IHBvc2l0aW9uYWxzOiBzdHJpbmdbXSB9ID0+IHtcbiAgbGV0IHJlc3VsdDogUmV0dXJuVHlwZTx0eXBlb2YgcGFyc2VBcmdzPjtcbiAgdHJ5IHtcbiAgICByZXN1bHQgPSBwYXJzZUFyZ3Moe1xuICAgICAgb3B0aW9ucyxcbiAgICAgIHRva2VuczogdHJ1ZSxcbiAgICAgIGFsbG93UG9zaXRpb25hbHM6IHRydWUsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVycm9yLFxuICAgICAgdmFsdWVzOiB7fSBhcyBWYWx1ZXMsXG4gICAgICBwb3NpdGlvbmFsczogW10sXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHsgdG9rZW5zLCB2YWx1ZXMsIHBvc2l0aW9uYWxzIH0gPSByZXN1bHQ7XG5cbiAgLy8gUmVwcm9jZXNzIHRoZSBvcHRpb24gdG9rZW5zIGFuZCBvdmVyd3JpdGUgdGhlIHJldHVybmVkIHZhbHVlcy5cbiAgZm9yIChjb25zdCB0b2tlbiBvZiB0b2tlbnMgPz8gW10pIHtcbiAgICBpZiAodG9rZW4ua2luZCA9PT0gXCJvcHRpb24tdGVybWluYXRvclwiIHx8IHRva2VuLmtpbmQgPT09IFwicG9zaXRpb25hbFwiKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAodG9rZW4ubmFtZS5zdGFydHNXaXRoKFwibm8tXCIpKSB7XG4gICAgICAvLyBTdG9yZSBmb286ZmFsc2UgZm9yIC0tbm8tZm9vXG4gICAgICBjb25zdCBwb3NpdGl2ZU5hbWUgPSB0b2tlbi5uYW1lLnNsaWNlKFwibm8tXCIubGVuZ3RoKTtcbiAgICAgIHZhbHVlc1twb3NpdGl2ZU5hbWVdID0gZmFsc2U7XG4gICAgICBkZWxldGUgdmFsdWVzW3Rva2VuLm5hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXNhdmUgdmFsdWUgc28gbGFzdCBvbmUgd2lucyBpZiBib3RoIC0tZm9vIGFuZCAtLW5vLWZvby5cbiAgICAgIHZhbHVlc1t0b2tlbi5uYW1lXSA9IHRva2VuLnZhbHVlID8/IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvcjogdW5kZWZpbmVkLFxuICAgIHZhbHVlczogdmFsdWVzIGFzIFZhbHVlcyxcbiAgICBwb3NpdGlvbmFscyxcbiAgfTtcbn07XG5cbmNvbnN0IHsgZXJyb3IsIHZhbHVlcywgcG9zaXRpb25hbHMgfSA9IHRyeVBhcnNlPFZhbHVlcz4oe1xuICBoZWxwOiB7XG4gICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgc2hvcnQ6IFwiaFwiLFxuICB9LFxuICBwcmV0dGlmeToge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIHNob3J0OiBcInBcIixcbiAgICBkZWZhdWx0OiB0cnVlLFxuICB9LFxuICBcIm5vLXByZXR0aWZ5XCI6IHtcbiAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICBzaG9ydDogXCJQXCIsXG4gIH0sXG4gIHRzY29uZmlnOiB7XG4gICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICBzaG9ydDogXCJjXCIsXG4gIH0sXG59KTtcblxuaWYgKGVycm9yKSB7XG4gIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gIHByb2Nlc3MuZXhpdCgxKTtcbn1cblxuY29uc3QgdXNhZ2VQcm9tcHQgPSBbXG4gIFwiVXNhZ2U6XCIsXG4gIFwiICBleHBhbmQtbXktdHlwZSBbb3B0aW9uc10gPHNvdXJjZS1maWxlPiA8ZXhwcmVzc2lvbj5cIixcbiAgXCJcIixcbiAgXCJPcHRpb25zOlwiLFxuICBcIiAgLWgsIC0taGVscFxcdFxcdFxcdFNob3cgdGhpcyBoZWxwIG1lc3NhZ2VcIixcbiAgXCIgIC1wLCAtLXByZXR0aWZ5XFx0XFx0UHJldHRpZnkgdGhlIG91dHB1dFwiLFxuICBcIiAgLVAsIC0tbm8tcHJldHRpZnlcXHRcXHREbyBub3QgcHJldHRpZnkgdGhlIG91dHB1dFwiLFxuICBcIiAgLWMsIC0tdHNjb25maWcgPGZpbGU+XFx0XFx0VXNlIHRoZSBzcGVjaWZpZWQgdHNjb25maWcuanNvbiBmaWxlXCIsXG5dLmpvaW4oXCJcXG5cIik7XG5cbmlmIChwb3NpdGlvbmFscy5sZW5ndGggIT09IDIpIHtcbiAgY29uc29sZS5lcnJvcih1c2FnZVByb21wdCk7XG4gIHByb2Nlc3MuZXhpdCgxKTtcbn1cblxuaWYgKHZhbHVlcy5oZWxwKSB7XG4gIGNvbnNvbGUuZXJyb3IodXNhZ2VQcm9tcHQpO1xuICBwcm9jZXNzLmV4aXQoMCk7XG59XG5cbmNvbnN0IFtzb3VyY2VGaWxlTmFtZSwgdHlwZUV4cHJlc3Npb25dID0gcG9zaXRpb25hbHM7XG5jb25zdCB7IHByZXR0aWZ5LCB0c2NvbmZpZzogdHNDb25maWdGaWxlTmFtZSB9ID0gdmFsdWVzO1xuXG5sZXQgdHNQYXJzZWRDb21tYW5kTGluZTogdHMuUGFyc2VkQ29tbWFuZExpbmUgfCB1bmRlZmluZWQ7XG5cbmlmICh0c0NvbmZpZ0ZpbGVOYW1lKSB7XG4gIGNvbnN0IGNvbmZpZ0ZpbGUgPSB0cy5yZWFkQ29uZmlnRmlsZSh0c0NvbmZpZ0ZpbGVOYW1lLCB0cy5zeXMucmVhZEZpbGUpO1xuICBjb25zdCBjb21waWxlck9wdGlvbnMgPSB0cy5wYXJzZUpzb25Db25maWdGaWxlQ29udGVudChcbiAgICBjb25maWdGaWxlLmNvbmZpZyxcbiAgICB0cy5zeXMsXG4gICAgXCIuL1wiLFxuICApO1xuXG4gIHRzUGFyc2VkQ29tbWFuZExpbmUgPSBjb21waWxlck9wdGlvbnM7XG59XG5cbmNvbnN0IHJlc3VsdCA9IGF3YWl0IGV4cGFuZE15VHlwZSh7XG4gIHNvdXJjZUZpbGVOYW1lOiBwYXRoLnJlc29sdmUoc291cmNlRmlsZU5hbWUpLFxuICB0eXBlRXhwcmVzc2lvbixcbiAgcHJldHRpZnk6IHtcbiAgICBlbmFibGVkOiBwcmV0dGlmeSxcbiAgfSxcbiAgdHNDb21waWxlck9wdGlvbnM6IHRzUGFyc2VkQ29tbWFuZExpbmU/Lm9wdGlvbnMsXG59KTtcblxuY29uc29sZS5sb2cocmVzdWx0KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7OztBQUFBLE9BQU8sUUFBUTtBQVdSLElBQU0sNkJBQTZCLENBQ3hDQSxpQkFDQUMsaUJBQ0EsaUJBQ0EsMEJBQ0c7QUFDSCxRQUFNLHFCQUFxQixHQUFHLG1CQUFtQixtQkFBbUIsQ0FBQyxDQUFDO0FBQ3RFLFFBQU0sd0JBQXdCLG1CQUFtQjtBQUVqRCxxQkFBbUIsZ0JBQWdCLENBQUMsYUFBYSxTQUFTO0FBQ3hELFFB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VDtBQUFBLEVBQ0EsVUFBVTtBQUFBLElBQ1IsTUFBTTtBQUFBLElBQ04sT0FBTztBQUFBLEVBQ1Q7QUFDRixDQUFDO0FBRUQsSUFBSSxPQUFPO0FBQ1QsVUFBUSxNQUFNLE1BQU0sT0FBTztBQUMzQixVQUFRLEtBQUssQ0FBQztBQUNoQjtBQUVBLElBQU0sY0FBYztBQUFBLEVBQ2xCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUNGLEVBQUUsS0FBSyxJQUFJO0FBRVgsSUFBSSxZQUFZLFdBQVcsR0FBRztBQUM1QixVQUFRLE1BQU0sV0FBVztBQUN6QixVQUFRLEtBQUssQ0FBQztBQUNoQjtBQUVBLElBQUksT0FBTyxNQUFNO0FBQ2YsVUFBUSxNQUFNLFdBQVc7QUFDekIsVUFBUSxLQUFLLENBQUM7QUFDaEI7QUFFQSxJQUFNLENBQUMsZ0JBQWdCLGNBQWMsSUFBSTtBQUN6QyxJQUFNLEVBQUUsVUFBVSxVQUFVLGlCQUFpQixJQUFJO0FBRWpELElBQUk7QUFFSixJQUFJLGtCQUFrQjtBQUNwQixRQUFNLGFBQWFKLElBQUcsZUFBZSxrQkFBa0JBLElBQUcsSUFBSSxRQUFRO0FBQ3RFLFFBQU0sa0JBQWtCQSxJQUFHO0FBQUEsSUFDekIsV0FBVztBQUFBLElBQ1hBLElBQUc7QUFBQSxJQUNIO0FBQUEsRUFDRjtBQUVBLHdCQUFzQjtBQUN4QjtBQUVBLElBQU0sU0FBUyxNQUFNLGFBQWE7QUFBQSxFQUNoQyxnQkFBZ0IsS0FBSyxRQUFRLGNBQWM7QUFBQSxFQUMzQztBQUFBLEVBQ0EsVUFBVTtBQUFBLElBQ1IsU0FBUztBQUFBLEVBQ1g7QUFBQSxFQUNBLG1CQUFtQixxQkFBcUI7QUFDMUMsQ0FBQztBQUVELFFBQVEsSUFBSSxNQUFNOyIsCiAgIm5hbWVzIjogWyJzb3VyY2VGaWxlTmFtZSIsICJ0eXBlRXhwcmVzc2lvbiIsICJ0cyIsICJzb3VyY2VGaWxlIiwgInRzIiwgInJlc3VsdCIsICJlcnJvciIsICJ2YWx1ZXMiLCAicG9zaXRpb25hbHMiXQp9Cg==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expand-my-type",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Expand TypeScript type expressions programmatically",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"expand",
|
|
@@ -32,15 +32,21 @@
|
|
|
32
32
|
},
|
|
33
33
|
"main": "dist/index.cjs",
|
|
34
34
|
"types": "dist/index.d.ts",
|
|
35
|
+
"bin": {
|
|
36
|
+
"expand-my-type": "./dist/cli.js"
|
|
37
|
+
},
|
|
35
38
|
"files": [
|
|
36
39
|
"dist/index.cjs",
|
|
37
40
|
"dist/index.d.cts",
|
|
38
41
|
"dist/index.d.ts",
|
|
39
|
-
"dist/index.js"
|
|
42
|
+
"dist/index.js",
|
|
43
|
+
"dist/cli.js"
|
|
40
44
|
],
|
|
41
45
|
"scripts": {
|
|
46
|
+
"bundle-cli": "tsup ./src/cli.ts --format esm --sourcemap inline --silent",
|
|
47
|
+
"bundle-lib": "tsup ./src/index.ts --format cjs,esm --dts --clean --sourcemap inline --silent",
|
|
42
48
|
"format": "prettier --write .",
|
|
43
|
-
"prepare": "
|
|
49
|
+
"prepare": "npm run bundle-lib && npm run bundle-cli",
|
|
44
50
|
"pretest": "tsc",
|
|
45
51
|
"test": "tsx --test --test-reporter spec ./src/index.test.ts"
|
|
46
52
|
},
|