@atlaspack/transformer-typescript-types 2.12.1-canary.3354

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/src/shake.js ADDED
@@ -0,0 +1,318 @@
1
+ // @flow
2
+ import {TSModule} from './TSModule';
3
+ import type {TSModuleGraph} from './TSModuleGraph';
4
+
5
+ import ts from 'typescript';
6
+ import nullthrows from 'nullthrows';
7
+ import {getExportedName, isDeclaration} from './utils';
8
+ import {
9
+ createImportClause,
10
+ createImportDeclaration,
11
+ createImportSpecifier,
12
+ updateExportDeclaration,
13
+ } from './wrappers';
14
+
15
+ export function shake(
16
+ moduleGraph: TSModuleGraph,
17
+ context: any,
18
+ sourceFile: any,
19
+ ): any {
20
+ // Factory only exists on TS >= 4.0
21
+ const {factory = ts} = context;
22
+
23
+ // We traverse things out of order which messes with typescript's internal state.
24
+ // We don't rely on the lexical environment, so just overwrite with noops to avoid errors.
25
+ context.suspendLexicalEnvironment = () => {};
26
+ context.resumeLexicalEnvironment = () => {};
27
+
28
+ // Propagate exports from the main module to determine what types should be included
29
+ let exportedNames = moduleGraph.propagate(context);
30
+
31
+ // When module definitions are nested inside each other (e.g with module augmentation),
32
+ // we want to keep track of the hierarchy so we can associated nodes with the right module.
33
+ const moduleStack: Array<?TSModule> = [];
34
+
35
+ let addedGeneratedImports = false;
36
+
37
+ let _currentModule: ?TSModule;
38
+ let visit = (node: any): any => {
39
+ if (ts.isBundle(node)) {
40
+ return factory.updateBundle(node, ts.visitNodes(node.sourceFiles, visit));
41
+ }
42
+
43
+ // Flatten all module declarations into the top-level scope
44
+ if (ts.isModuleDeclaration(node)) {
45
+ // Deeply nested module declarations are assumed to be module augmentations and left alone.
46
+ if (moduleStack.length >= 1) {
47
+ // Since we are hoisting them to the top-level scope, we need to add a "declare" keyword to make them ambient.
48
+ // we also want the declare keyword to come after the export keyword to guarantee a valid typings file.
49
+ node.modifiers ??= [];
50
+ const index =
51
+ node.modifiers[0]?.kind === ts.SyntaxKind.ExportKeyword ? 1 : 0;
52
+ node.modifiers.splice(
53
+ index,
54
+ 0,
55
+ factory.createModifier(ts.SyntaxKind.DeclareKeyword),
56
+ );
57
+ return node;
58
+ }
59
+
60
+ moduleStack.push(_currentModule);
61
+ let isFirstModule = !_currentModule;
62
+ _currentModule = moduleGraph.getModule(node.name.text);
63
+ let statements = ts.visitEachChild(node, visit, context).body.statements;
64
+ _currentModule = moduleStack.pop();
65
+
66
+ if (isFirstModule && !addedGeneratedImports) {
67
+ statements.unshift(...generateImports(factory, moduleGraph));
68
+ addedGeneratedImports = true;
69
+ }
70
+
71
+ return statements;
72
+ }
73
+
74
+ if (!_currentModule) {
75
+ return ts.visitEachChild(node, visit, context);
76
+ }
77
+
78
+ // Remove inline imports. They are hoisted to the top of the output.
79
+ if (ts.isImportDeclaration(node)) {
80
+ return null;
81
+ }
82
+
83
+ let currentModule = nullthrows(_currentModule);
84
+ // Remove exports from flattened modules
85
+ if (ts.isExportDeclaration(node)) {
86
+ if (
87
+ !node.moduleSpecifier ||
88
+ moduleGraph.getModule(node.moduleSpecifier.text)
89
+ ) {
90
+ if (!node.moduleSpecifier && node.exportClause) {
91
+ // Filter exported elements to only external re-exports
92
+ let exported = [];
93
+ for (let element of node.exportClause.elements) {
94
+ let name = (element.propertyName ?? element.name).text;
95
+ if (
96
+ exportedNames.get(name) === currentModule &&
97
+ !currentModule.hasBinding(name)
98
+ ) {
99
+ exported.push(element);
100
+ }
101
+ }
102
+
103
+ if (exported.length > 0) {
104
+ return updateExportDeclaration(
105
+ factory,
106
+ node,
107
+ undefined, // modifiers
108
+ false, // isTypeOnly
109
+ factory.updateNamedExports(node.exportClause, exported),
110
+ undefined, // moduleSpecifier
111
+ undefined, // assertClause
112
+ );
113
+ }
114
+ }
115
+
116
+ return null;
117
+ }
118
+ }
119
+
120
+ // Remove export assignment if unused.
121
+ if (ts.isExportAssignment(node)) {
122
+ let name = currentModule.getName('default');
123
+ if (exportedNames.get(name) !== currentModule) {
124
+ return null;
125
+ }
126
+ }
127
+
128
+ if (isDeclaration(node)) {
129
+ let name = getExportedName(node) || node.name.text;
130
+
131
+ // Remove unused declarations
132
+ if (!currentModule.used.has(name)) {
133
+ return null;
134
+ }
135
+
136
+ // Remove original export modifiers
137
+ node.modifiers = (node.modifiers || []).filter(
138
+ m =>
139
+ m.kind !== ts.SyntaxKind.ExportKeyword &&
140
+ m.kind !== ts.SyntaxKind.DefaultKeyword,
141
+ );
142
+
143
+ // Rename declarations
144
+ let newName = currentModule.getName(name);
145
+ if (newName !== name && newName !== 'default') {
146
+ node.name = factory.createIdentifier(newName);
147
+ }
148
+
149
+ // Export declarations that should be exported
150
+ if (exportedNames.get(newName) === currentModule) {
151
+ if (newName === 'default') {
152
+ node.modifiers.unshift(
153
+ factory.createModifier(ts.SyntaxKind.DefaultKeyword),
154
+ );
155
+ }
156
+
157
+ node.modifiers.unshift(
158
+ factory.createModifier(ts.SyntaxKind.ExportKeyword),
159
+ );
160
+ } else if (
161
+ ts.isFunctionDeclaration(node) ||
162
+ ts.isClassDeclaration(node)
163
+ ) {
164
+ node.modifiers.unshift(
165
+ factory.createModifier(ts.SyntaxKind.DeclareKeyword),
166
+ );
167
+ }
168
+ }
169
+
170
+ if (ts.isVariableStatement(node)) {
171
+ node = ts.visitEachChild(node, visit, context);
172
+
173
+ // Remove empty variable statements
174
+ if (node.declarationList.declarations.length === 0) {
175
+ return null;
176
+ }
177
+
178
+ // Remove original export modifiers
179
+ node.modifiers = (node.modifiers || []).filter(
180
+ m =>
181
+ m.kind !== ts.SyntaxKind.ExportKeyword &&
182
+ m.kind !== ts.SyntaxKind.DeclareKeyword,
183
+ );
184
+
185
+ // Add export modifier if all declarations are exported.
186
+ let isExported = node.declarationList.declarations.every(
187
+ d => exportedNames.get(d.name.text) === currentModule,
188
+ );
189
+ if (isExported) {
190
+ node.modifiers.unshift(
191
+ factory.createModifier(ts.SyntaxKind.ExportKeyword),
192
+ );
193
+ } else {
194
+ // Otherwise, add `declare` modifier (required for top-level declarations in d.ts files).
195
+ node.modifiers.unshift(
196
+ factory.createModifier(ts.SyntaxKind.DeclareKeyword),
197
+ );
198
+ }
199
+
200
+ return node;
201
+ }
202
+
203
+ if (ts.isVariableDeclaration(node)) {
204
+ // Remove unused variables
205
+ if (!currentModule.used.has(node.name.text)) {
206
+ return null;
207
+ }
208
+ }
209
+
210
+ // Rename references
211
+ if (ts.isIdentifier(node) && currentModule.names.has(node.text)) {
212
+ let newName = nullthrows(currentModule.getName(node.text));
213
+ if (newName !== 'default') {
214
+ return factory.createIdentifier(newName);
215
+ }
216
+ }
217
+
218
+ // Replace namespace references with final names
219
+ if (ts.isQualifiedName(node) && ts.isIdentifier(node.left)) {
220
+ let resolved = moduleGraph.resolveImport(
221
+ currentModule,
222
+ node.left.text,
223
+ node.right.text,
224
+ );
225
+ if (resolved && resolved.module.hasBinding(resolved.name)) {
226
+ return factory.createIdentifier(resolved.name);
227
+ } else {
228
+ return factory.updateQualifiedName(
229
+ node,
230
+ factory.createIdentifier(currentModule.getName(node.left.text)),
231
+ node.right,
232
+ );
233
+ }
234
+ }
235
+
236
+ // Remove private properties
237
+ if (ts.isPropertyDeclaration(node)) {
238
+ let isPrivate =
239
+ node.modifiers &&
240
+ node.modifiers.some(m => m.kind === ts.SyntaxKind.PrivateKeyword);
241
+ if (isPrivate) {
242
+ return null;
243
+ }
244
+ }
245
+
246
+ return ts.visitEachChild(node, visit, context);
247
+ };
248
+
249
+ return ts.visitNode(sourceFile, visit);
250
+ }
251
+
252
+ function generateImports(factory: any, moduleGraph: TSModuleGraph) {
253
+ let importStatements = [];
254
+ for (let [specifier, names] of moduleGraph.getAllImports()) {
255
+ let defaultSpecifier;
256
+ let namespaceSpecifier;
257
+ let namedSpecifiers = [];
258
+ for (let [name, imported] of names) {
259
+ if (imported === 'default') {
260
+ defaultSpecifier = factory.createIdentifier(name);
261
+ } else if (imported === '*') {
262
+ namespaceSpecifier = factory.createNamespaceImport(
263
+ factory.createIdentifier(name),
264
+ );
265
+ } else {
266
+ namedSpecifiers.push(
267
+ createImportSpecifier(
268
+ factory,
269
+ false,
270
+ name === imported ? undefined : factory.createIdentifier(imported),
271
+ factory.createIdentifier(name),
272
+ ),
273
+ );
274
+ }
275
+ }
276
+
277
+ if (namespaceSpecifier) {
278
+ let importClause = createImportClause(
279
+ factory,
280
+ false,
281
+ defaultSpecifier,
282
+ namespaceSpecifier,
283
+ );
284
+ importStatements.push(
285
+ createImportDeclaration(
286
+ factory,
287
+ undefined,
288
+ importClause,
289
+ factory.createStringLiteral(specifier),
290
+ undefined,
291
+ ),
292
+ );
293
+ defaultSpecifier = undefined;
294
+ }
295
+
296
+ if (defaultSpecifier || namedSpecifiers.length > 0) {
297
+ let importClause = createImportClause(
298
+ factory,
299
+ false,
300
+ defaultSpecifier,
301
+ namedSpecifiers.length > 0
302
+ ? factory.createNamedImports(namedSpecifiers)
303
+ : undefined,
304
+ );
305
+ importStatements.push(
306
+ createImportDeclaration(
307
+ factory,
308
+ undefined,
309
+ importClause,
310
+ factory.createStringLiteral(specifier),
311
+ undefined,
312
+ ),
313
+ );
314
+ }
315
+ }
316
+
317
+ return importStatements;
318
+ }
package/src/utils.js ADDED
@@ -0,0 +1,28 @@
1
+ // @flow
2
+ import ts from 'typescript';
3
+
4
+ export function getExportedName(node: any): ?string {
5
+ if (!node.modifiers) {
6
+ return null;
7
+ }
8
+
9
+ if (!node.modifiers.some(m => m.kind === ts.SyntaxKind.ExportKeyword)) {
10
+ return null;
11
+ }
12
+
13
+ if (node.modifiers.some(m => m.kind === ts.SyntaxKind.DefaultKeyword)) {
14
+ return 'default';
15
+ }
16
+
17
+ return node.name.text;
18
+ }
19
+
20
+ export function isDeclaration(node: any): boolean {
21
+ return (
22
+ ts.isFunctionDeclaration(node) ||
23
+ ts.isClassDeclaration(node) ||
24
+ ts.isInterfaceDeclaration(node) ||
25
+ ts.isEnumDeclaration(node) ||
26
+ ts.isTypeAliasDeclaration(node)
27
+ );
28
+ }
@@ -0,0 +1,202 @@
1
+ // @flow
2
+ /* eslint-disable no-unused-vars */
3
+ import type {
4
+ ExportDeclaration,
5
+ Expression,
6
+ Identifier,
7
+ ImportClause,
8
+ ImportDeclaration,
9
+ ImportSpecifier,
10
+ Modifier,
11
+ NamedImportBindings,
12
+ } from 'typescript';
13
+
14
+ import ts from 'typescript';
15
+ import invariant from 'assert';
16
+
17
+ type AssertClause = any;
18
+ type NamedExportBindings = any;
19
+
20
+ const [majorVersion, minorVersion] = ts.versionMajorMinor
21
+ .split('.')
22
+ .map(num => parseInt(num, 10));
23
+
24
+ // Everything below was generated using https://github.com/mischnic/tsc-version-wrapper
25
+
26
+ export const createImportClause: (
27
+ factory: any,
28
+ isTypeOnly: boolean,
29
+ name: Identifier | void,
30
+ namedBindings: NamedImportBindings | void,
31
+ ) => ImportClause = (() => {
32
+ if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 0)) {
33
+ return (factory, isTypeOnly, name, namedBindings) =>
34
+ factory.createImportClause(isTypeOnly, name, namedBindings);
35
+ } else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 8)) {
36
+ return (factory, isTypeOnly, name, namedBindings) =>
37
+ factory.createImportClause(name, namedBindings, isTypeOnly);
38
+ } else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
39
+ return (factory, isTypeOnly, name, namedBindings) =>
40
+ factory.createImportClause(name, namedBindings);
41
+ } else {
42
+ invariant(false);
43
+ }
44
+ })();
45
+
46
+ export const createImportDeclaration: (
47
+ factory: any,
48
+ modifiers: Modifier[] | void,
49
+ importClause: ImportClause | void,
50
+ moduleSpecifier: Expression,
51
+ assertClause: AssertClause,
52
+ ) => ImportDeclaration = (() => {
53
+ if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 8)) {
54
+ return (factory, modifiers, importClause, moduleSpecifier, assertClause) =>
55
+ factory.createImportDeclaration(
56
+ modifiers,
57
+ importClause,
58
+ moduleSpecifier,
59
+ assertClause,
60
+ );
61
+ } else if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
62
+ return (factory, modifiers, importClause, moduleSpecifier, assertClause) =>
63
+ factory.createImportDeclaration(
64
+ undefined /* decorators */,
65
+ modifiers,
66
+ importClause,
67
+ moduleSpecifier,
68
+ assertClause,
69
+ );
70
+ } else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
71
+ return (factory, modifiers, importClause, moduleSpecifier, assertClause) =>
72
+ factory.createImportDeclaration(
73
+ undefined /* decorators */,
74
+ modifiers,
75
+ importClause,
76
+ moduleSpecifier,
77
+ );
78
+ } else {
79
+ invariant(false);
80
+ }
81
+ })();
82
+
83
+ export const createImportSpecifier: (
84
+ factory: any,
85
+ isTypeOnly: boolean,
86
+ propertyName: Identifier | void,
87
+ name: Identifier,
88
+ ) => ImportSpecifier = (() => {
89
+ if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
90
+ return (factory, isTypeOnly, propertyName, name) =>
91
+ factory.createImportSpecifier(isTypeOnly, propertyName, name);
92
+ } else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
93
+ return (factory, isTypeOnly, propertyName, name) =>
94
+ factory.createImportSpecifier(propertyName, name);
95
+ } else {
96
+ invariant(false);
97
+ }
98
+ })();
99
+
100
+ export const updateExportDeclaration: (
101
+ factory: any,
102
+ node: ExportDeclaration,
103
+ modifiers: Modifier[] | void,
104
+ isTypeOnly: boolean,
105
+ exportClause: NamedExportBindings | void,
106
+ moduleSpecifier: Expression | void,
107
+ assertClause: AssertClause | void,
108
+ ) => ExportDeclaration = (() => {
109
+ if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 8)) {
110
+ return (
111
+ factory,
112
+ node,
113
+ modifiers,
114
+ isTypeOnly,
115
+ exportClause,
116
+ moduleSpecifier,
117
+ assertClause,
118
+ ) =>
119
+ factory.updateExportDeclaration(
120
+ node,
121
+ modifiers,
122
+ isTypeOnly,
123
+ exportClause,
124
+ moduleSpecifier,
125
+ assertClause,
126
+ );
127
+ } else if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
128
+ return (
129
+ factory,
130
+ node,
131
+ modifiers,
132
+ isTypeOnly,
133
+ exportClause,
134
+ moduleSpecifier,
135
+ assertClause,
136
+ ) =>
137
+ factory.updateExportDeclaration(
138
+ node,
139
+ undefined /* decorators */,
140
+ modifiers,
141
+ isTypeOnly,
142
+ exportClause,
143
+ moduleSpecifier,
144
+ assertClause,
145
+ );
146
+ } else if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 0)) {
147
+ return (
148
+ factory,
149
+ node,
150
+ modifiers,
151
+ isTypeOnly,
152
+ exportClause,
153
+ moduleSpecifier,
154
+ assertClause,
155
+ ) =>
156
+ factory.updateExportDeclaration(
157
+ node,
158
+ undefined /* decorators */,
159
+ modifiers,
160
+ isTypeOnly,
161
+ exportClause,
162
+ moduleSpecifier,
163
+ );
164
+ } else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 8)) {
165
+ return (
166
+ factory,
167
+ node,
168
+ modifiers,
169
+ isTypeOnly,
170
+ exportClause,
171
+ moduleSpecifier,
172
+ assertClause,
173
+ ) =>
174
+ factory.updateExportDeclaration(
175
+ node,
176
+ undefined /* decorators */,
177
+ modifiers,
178
+ exportClause,
179
+ moduleSpecifier,
180
+ isTypeOnly,
181
+ );
182
+ } else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
183
+ return (
184
+ factory,
185
+ node,
186
+ modifiers,
187
+ isTypeOnly,
188
+ exportClause,
189
+ moduleSpecifier,
190
+ assertClause,
191
+ ) =>
192
+ factory.updateExportDeclaration(
193
+ node,
194
+ undefined /* decorators */,
195
+ modifiers,
196
+ exportClause,
197
+ moduleSpecifier,
198
+ );
199
+ } else {
200
+ invariant(false);
201
+ }
202
+ })();