@tanstack/router-cli 0.0.1-beta.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,598 @@
1
+ /**
2
+ * router-cli
3
+ *
4
+ * Copyright (c) TanStack
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ 'use strict';
12
+
13
+ Object.defineProperty(exports, '__esModule', { value: true });
14
+
15
+ var babel = require('@babel/core');
16
+ var t = require('@babel/types');
17
+ var syntaxTS = require('@babel/plugin-syntax-typescript');
18
+ var generator = require('./generator.js');
19
+ var path = require('path');
20
+
21
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
22
+
23
+ function _interopNamespace(e) {
24
+ if (e && e.__esModule) return e;
25
+ var n = Object.create(null);
26
+ if (e) {
27
+ Object.keys(e).forEach(function (k) {
28
+ if (k !== 'default') {
29
+ var d = Object.getOwnPropertyDescriptor(e, k);
30
+ Object.defineProperty(n, k, d.get ? d : {
31
+ enumerable: true,
32
+ get: function () { return e[k]; }
33
+ });
34
+ }
35
+ });
36
+ }
37
+ n["default"] = e;
38
+ return Object.freeze(n);
39
+ }
40
+
41
+ var babel__namespace = /*#__PURE__*/_interopNamespace(babel);
42
+ var t__namespace = /*#__PURE__*/_interopNamespace(t);
43
+ var syntaxTS__default = /*#__PURE__*/_interopDefaultLegacy(syntaxTS);
44
+ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
45
+
46
+ const isolatedProperties = ['loader', 'action', 'component', 'errorComponent', 'pendingComponent'];
47
+ const getBasePlugins = () => [[syntaxTS__default["default"], {
48
+ isTSX: true
49
+ // disallowAmbiguousJSXLike: true,
50
+ }]];
51
+
52
+ async function ensureBoilerplate(node, code) {
53
+ var _originalFile$code, _originalFile$code2, _file$code, _file$code2;
54
+ const relativeImportPath = path__default["default"].relative(node.fullDir, node.genPathNoExt);
55
+ const originalFile = await babel__namespace.transformAsync(code, {
56
+ configFile: false,
57
+ babelrc: false,
58
+ plugins: [...getBasePlugins()]
59
+ });
60
+ const file = await babel__namespace.transformAsync(code, {
61
+ configFile: false,
62
+ babelrc: false,
63
+ plugins: [...getBasePlugins(), {
64
+ visitor: {
65
+ Program: {
66
+ enter(programPath) {
67
+ // Remove all properties except for our isolated one
68
+
69
+ if (node.isRoot) {
70
+ let foundImport = false;
71
+ programPath.traverse({
72
+ ImportSpecifier(importPath) {
73
+ if (t__namespace.isIdentifier(importPath.node.imported) && importPath.node.imported.name === 'createRouteConfig') {
74
+ foundImport = true;
75
+ }
76
+ }
77
+ });
78
+ if (!foundImport) {
79
+ programPath.node.body.unshift(babel__namespace.template.statement("import { createRouteConfig } from '@tanstack/react-router'")());
80
+ }
81
+ } else {
82
+ let foundImport = false;
83
+ programPath.traverse({
84
+ ImportSpecifier(importPath) {
85
+ if (t__namespace.isIdentifier(importPath.node.imported) && importPath.node.imported.name === 'routeConfig') {
86
+ foundImport = true;
87
+ if (t__namespace.isImportDeclaration(importPath.parentPath.node)) {
88
+ if (importPath.parentPath.node.source.value !== relativeImportPath) {
89
+ importPath.parentPath.node.source.value = relativeImportPath;
90
+ }
91
+ }
92
+ }
93
+ }
94
+ });
95
+ if (!foundImport) {
96
+ programPath.node.body.unshift(babel__namespace.template.statement("import { routeConfig } from '" + relativeImportPath + "'")());
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }]
103
+ });
104
+ const separator = node.isRoot ? 'createRouteConfig(' : 'routeConfig.generate(';
105
+ if (!(originalFile != null && originalFile.code)) {
106
+ return (file == null ? void 0 : file.code) + "\n\n" + separator + "{\n\n})";
107
+ }
108
+ const originalHead = originalFile == null ? void 0 : (_originalFile$code = originalFile.code) == null ? void 0 : _originalFile$code.substring(0, originalFile == null ? void 0 : (_originalFile$code2 = originalFile.code) == null ? void 0 : _originalFile$code2.indexOf(separator));
109
+ const generatedHead = file == null ? void 0 : (_file$code = file.code) == null ? void 0 : _file$code.substring(0, file == null ? void 0 : (_file$code2 = file.code) == null ? void 0 : _file$code2.indexOf(separator));
110
+ if (originalHead !== generatedHead) {
111
+ var _originalFile$code3, _originalFile$code4;
112
+ return generatedHead + "\n\n" + (originalFile == null ? void 0 : (_originalFile$code3 = originalFile.code) == null ? void 0 : _originalFile$code3.substring(originalFile == null ? void 0 : (_originalFile$code4 = originalFile.code) == null ? void 0 : _originalFile$code4.indexOf(separator)));
113
+ }
114
+ return;
115
+ }
116
+ async function isolateOptionToExport(node, code, opts) {
117
+ var _await$babel$transfor;
118
+ return (_await$babel$transfor = await babel__namespace.transformAsync(code, {
119
+ configFile: false,
120
+ babelrc: false,
121
+ plugins: [...getBasePlugins(), plugin()],
122
+ ast: true
123
+ })) == null ? void 0 : _await$babel$transfor.code;
124
+ function plugin() {
125
+ return {
126
+ visitor: {
127
+ Program: {
128
+ enter(programPath, state) {
129
+ // If we're the root, handle things a bit differently
130
+ if (node.isRoot) {
131
+ programPath.traverse({
132
+ Identifier(path) {
133
+ if (path.node.name === 'createRouteConfig' && t__namespace.isCallExpression(path.parentPath.node)) {
134
+ const options = getCreateRouteConfigOptions(path);
135
+ if (options) {
136
+ var _path$findParent;
137
+ const property = options.properties.find(property => {
138
+ return t__namespace.isObjectProperty(property) && t__namespace.isIdentifier(property.key) && property.key.name === opts.isolate;
139
+ });
140
+ if (t__namespace.isObjectProperty(property)) {
141
+ const program = path.findParent(d => d.isProgram());
142
+ if (program != null && program.isProgram()) {
143
+ program.node.body.push(babel__namespace.template.statement("export const " + opts.isolate + " = $LOADER")({
144
+ $LOADER: property.value
145
+ }));
146
+ }
147
+ }
148
+ (_path$findParent = path.findParent(d => d.isExpressionStatement())) == null ? void 0 : _path$findParent.remove();
149
+ }
150
+ }
151
+ }
152
+ });
153
+ }
154
+
155
+ // We're not in the root, handle things normally
156
+ if (!node.isRoot) {
157
+ // Remove all properties except for our isolated one
158
+ programPath.traverse({
159
+ Identifier(path) {
160
+ if (path.node.name === 'generate') {
161
+ const options = getRouteConfigGenerateOptions(path);
162
+ if (options) {
163
+ var _path$findParent2;
164
+ const property = options.properties.find(property => {
165
+ return t__namespace.isObjectProperty(property) && t__namespace.isIdentifier(property.key) && property.key.name === opts.isolate;
166
+ });
167
+ if (t__namespace.isObjectProperty(property) && t__namespace.isIdentifier(property.key)) {
168
+ if (property.key.name === opts.isolate) {
169
+ const program = path.findParent(d => d.isProgram());
170
+ if (program != null && program.isProgram()) {
171
+ program.node.body.push(babel__namespace.template.statement("export const " + opts.isolate + " = $LOADER")({
172
+ $LOADER: property.value
173
+ }));
174
+ }
175
+ }
176
+ }
177
+ (_path$findParent2 = path.findParent(d => d.isExpressionStatement())) == null ? void 0 : _path$findParent2.remove();
178
+ }
179
+ }
180
+ }
181
+ });
182
+ }
183
+ cleanUnusedCode(programPath, state, [opts.isolate]);
184
+ }
185
+ }
186
+ }
187
+ };
188
+ }
189
+ }
190
+ async function detectExports(code) {
191
+ let exported = [];
192
+
193
+ // try {
194
+ await babel__namespace.transformAsync(code, {
195
+ configFile: false,
196
+ babelrc: false,
197
+ plugins: [...getBasePlugins(), {
198
+ visitor: {
199
+ ExportNamedDeclaration(path) {
200
+ if (t__namespace.isVariableDeclaration(path.node.declaration)) {
201
+ var _path$node$declaratio;
202
+ if (t__namespace.isVariableDeclarator((_path$node$declaratio = path.node.declaration.declarations) == null ? void 0 : _path$node$declaratio[0])) {
203
+ if (t__namespace.isIdentifier(path.node.declaration.declarations[0].id)) {
204
+ exported.push(path.node.declaration.declarations[0].id.name);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ }
210
+ }],
211
+ ast: true
212
+ });
213
+ return exported;
214
+ }
215
+ async function generateRouteConfig(node, routeCode, imports, clientOnly) {
216
+ var _node$parent, _node$parent2, _node$parent3, _node$parent4, _await$babel$transfor2;
217
+ const relativeParentRoutePath = clientOnly ? node.parent ? generator.removeExt(path__default["default"].relative(node.genDir, path__default["default"].resolve((_node$parent = node.parent) == null ? void 0 : _node$parent.genDir, (_node$parent2 = node.parent) == null ? void 0 : _node$parent2.clientFilename))) : "./" + generator.rootRouteClientName : node.parent ? generator.removeExt(path__default["default"].relative(node.genDir, path__default["default"].resolve((_node$parent3 = node.parent) == null ? void 0 : _node$parent3.genDir, (_node$parent4 = node.parent) == null ? void 0 : _node$parent4.filename))) : "./" + generator.rootRouteName;
218
+ const pathName = node.isRoot ? undefined : node.fileNameNoExt.startsWith('__') ? undefined : node.fileNameNoExt === 'index' ? '/' : node.fileNameNoExt;
219
+ const routeId = node.isRoot ? undefined : node.fileNameNoExt;
220
+ function plugin() {
221
+ return {
222
+ visitor: {
223
+ Program: {
224
+ enter(programPath, state) {
225
+ // Remove all of the isolated import properties from the config
226
+ programPath.traverse({
227
+ ImportSpecifier(path) {
228
+ if (t__namespace.isIdentifier(path.node.imported)) {
229
+ if (!node.isRoot) {
230
+ if (path.node.imported.name === 'routeConfig') {
231
+ path.parentPath.remove();
232
+ const program = path.findParent(d => d.isProgram());
233
+ if (program != null && program.isProgram()) {
234
+ program.node.body.unshift(babel__namespace.template.statement("import { routeConfig as parentRouteConfig } from '$IMPORT'")({
235
+ $IMPORT: relativeParentRoutePath
236
+ }));
237
+ }
238
+ }
239
+ }
240
+ }
241
+ },
242
+ Identifier(iPath) {
243
+ let options;
244
+ if (node.isRoot) {
245
+ if (iPath.node.name === 'createRouteConfig') {
246
+ if (t__namespace.isCallExpression(iPath.parentPath.node)) {
247
+ var _iPath$parentPath$par;
248
+ if (t__namespace.isExpressionStatement((_iPath$parentPath$par = iPath.parentPath.parentPath) == null ? void 0 : _iPath$parentPath$par.node)) {
249
+ var _iPath$parentPath$par2;
250
+ (_iPath$parentPath$par2 = iPath.parentPath.parentPath) == null ? void 0 : _iPath$parentPath$par2.replaceWith(t__namespace.variableDeclaration('const', [t__namespace.variableDeclarator(t__namespace.identifier('routeConfig'), iPath.parentPath.node)]));
251
+ }
252
+ }
253
+ }
254
+ } else {
255
+ if (iPath.node.name === 'generate') {
256
+ if (t__namespace.isMemberExpression(iPath.parentPath.node)) {
257
+ if (t__namespace.isIdentifier(iPath.parentPath.node.object)) {
258
+ iPath.node.name = 'createRoute';
259
+ iPath.parentPath.node.object.name = 'parentRouteConfig';
260
+ options = getRouteConfigGenerateOptions(iPath);
261
+ }
262
+ }
263
+ }
264
+ }
265
+ if (options) {
266
+ options.properties = [...(pathName ? [t__namespace.objectProperty(t__namespace.identifier('path'), t__namespace.stringLiteral(pathName))] : routeId ? [t__namespace.objectProperty(t__namespace.identifier('id'), t__namespace.stringLiteral(routeId))] : []), ...options.properties.map(property => {
267
+ if (t__namespace.isObjectProperty(property) && t__namespace.isIdentifier(property.key) && isolatedProperties.includes(property.key.name)) {
268
+ const key = property.key.name;
269
+ if (key === 'loader') {
270
+ if (clientOnly) {
271
+ return t__namespace.objectProperty(t__namespace.identifier('loader'), t__namespace.tSAsExpression(t__namespace.booleanLiteral(true), t__namespace.tsAnyKeyword()));
272
+ }
273
+ return t__namespace.objectProperty(t__namespace.identifier(key), babel__namespace.template.expression("(...args) => import('./" + path__default["default"].relative(node.genDir, node.genPathNoExt) + "-" + key + "').then(d => d." + key + ".apply(d." + key + ", (args as any)))", {
274
+ plugins: ['typescript']
275
+ })({}));
276
+ }
277
+ if (key === 'action') {
278
+ if (clientOnly) {
279
+ return t__namespace.objectProperty(t__namespace.identifier('action'), t__namespace.tSAsExpression(t__namespace.booleanLiteral(true), t__namespace.tSAnyKeyword()));
280
+ }
281
+ return t__namespace.objectProperty(t__namespace.identifier(key), babel__namespace.template.expression("(...payload: Parameters<typeof import('./" + path__default["default"].relative(node.genDir, node.genPathNoExt) + "-" + key + "').action>) => import('./" + path__default["default"].relative(node.genDir, node.genPathNoExt) + "-" + key + "').then(d => d." + key + ".apply(d." + key + ", (payload as any)))", {
282
+ plugins: ['typescript']
283
+ })({}));
284
+ }
285
+ return t__namespace.objectProperty(t__namespace.identifier(key), babel__namespace.template.expression("\n lazy(() => import('./" + path__default["default"].relative(node.genDir, node.genPathNoExt) + "-" + key + "').then(d => ({ default: d." + key + " }) ))")());
286
+ }
287
+ return property;
288
+ })];
289
+ const program = iPath.findParent(d => d.isProgram());
290
+ if (program != null && program.isProgram() && options) {
291
+ const index = program.node.body.findIndex(d => {
292
+ var _iPath$parentPath$par3;
293
+ return d.start === ((_iPath$parentPath$par3 = iPath.parentPath.parentPath) == null ? void 0 : _iPath$parentPath$par3.node.start);
294
+ });
295
+ if (node.isRoot) {
296
+ program.node.body[index] = babel__namespace.template.statement("const routeConfig = createRouteConfig(\n $OPTIONS\n )")({
297
+ $OPTIONS: options
298
+ });
299
+ } else {
300
+ program.node.body[index] = babel__namespace.template.statement("const routeConfig = parentRouteConfig.createRoute(\n $OPTIONS\n )")({
301
+ $OPTIONS: options
302
+ });
303
+ }
304
+ }
305
+ }
306
+ }
307
+ });
308
+ programPath.node.body.unshift(babel__namespace.template.statement("import { lazy } from '@tanstack/react-router'")());
309
+
310
+ // Add the routeConfig exports
311
+ programPath.node.body.push(babel__namespace.template.statement(clientOnly ? "export { routeConfig, routeConfig as " + node.variable + "Route }" : "export { routeConfig }")());
312
+ cleanUnusedCode(programPath, state, ['routeConfig', node.variable + "Route"]);
313
+ }
314
+ }
315
+ }
316
+ };
317
+ }
318
+ const code = (_await$babel$transfor2 = await babel__namespace.transformAsync(routeCode, {
319
+ configFile: false,
320
+ babelrc: false,
321
+ plugins: [...getBasePlugins(), plugin()],
322
+ ast: true
323
+ })) == null ? void 0 : _await$babel$transfor2.code;
324
+ if (!code) {
325
+ // console.log(code, node, imports)
326
+ throw new Error('Error while generating a route file!');
327
+ }
328
+ return code;
329
+ }
330
+ function getIdentifier(path) {
331
+ const parentPath = path.parentPath;
332
+ if (parentPath.type === 'VariableDeclarator') {
333
+ const pp = parentPath;
334
+ const name = pp.get('id');
335
+ return name.node.type === 'Identifier' ? name : null;
336
+ }
337
+ if (parentPath.type === 'AssignmentExpression') {
338
+ const pp = parentPath;
339
+ const name = pp.get('left');
340
+ return name.node.type === 'Identifier' ? name : null;
341
+ }
342
+ if (path.node.type === 'ArrowFunctionExpression') {
343
+ return null;
344
+ }
345
+ return path.node.id && path.node.id.type === 'Identifier' ? path.get('id') : null;
346
+ }
347
+ function isIdentifierReferenced(ident) {
348
+ const b = ident.scope.getBinding(ident.node.name);
349
+ if (b && b.referenced) {
350
+ if (b.path.type === 'FunctionDeclaration') {
351
+ return !b.constantViolations.concat(b.referencePaths).every(ref => ref.findParent(p => p === b.path));
352
+ }
353
+ return true;
354
+ }
355
+ return false;
356
+ }
357
+ function markFunction(path, state) {
358
+ const ident = getIdentifier(path);
359
+ if (ident && ident.node && isIdentifierReferenced(ident)) {
360
+ state.refs.add(ident);
361
+ }
362
+ }
363
+ function markImport(path, state) {
364
+ const local = path.get('local');
365
+ if (isIdentifierReferenced(local)) {
366
+ state.refs.add(local);
367
+ }
368
+ }
369
+ function getRouteConfigGenerateOptions(path) {
370
+ var _path$parentPath$pare;
371
+ const tryOptions = node => {
372
+ if (t__namespace.isIdentifier(node)) {
373
+ var _path$scope$getBindin;
374
+ const initNode = (_path$scope$getBindin = path.scope.getBinding(node.name)) == null ? void 0 : _path$scope$getBindin.path.node;
375
+ if (t__namespace.isVariableDeclarator(initNode)) {
376
+ return tryOptions(initNode.init);
377
+ }
378
+ } else if (t__namespace.isObjectExpression(node)) {
379
+ return node;
380
+ }
381
+ return;
382
+ };
383
+ if (t__namespace.isMemberExpression(path.parentPath.node) && t__namespace.isCallExpression((_path$parentPath$pare = path.parentPath.parentPath) == null ? void 0 : _path$parentPath$pare.node)) {
384
+ var _path$parentPath$pare2;
385
+ const options = (_path$parentPath$pare2 = path.parentPath.parentPath) == null ? void 0 : _path$parentPath$pare2.node.arguments[0];
386
+ return tryOptions(options);
387
+ }
388
+ }
389
+ function getCreateRouteConfigOptions(path) {
390
+ var _path$parentPath;
391
+ const tryOptions = node => {
392
+ if (t__namespace.isIdentifier(node)) {
393
+ var _path$scope$getBindin2;
394
+ const initNode = (_path$scope$getBindin2 = path.scope.getBinding(node.name)) == null ? void 0 : _path$scope$getBindin2.path.node;
395
+ if (t__namespace.isVariableDeclarator(initNode)) {
396
+ return tryOptions(initNode.init);
397
+ }
398
+ } else if (t__namespace.isObjectExpression(node)) {
399
+ return node;
400
+ }
401
+ return;
402
+ };
403
+ if (t__namespace.isCallExpression((_path$parentPath = path.parentPath) == null ? void 0 : _path$parentPath.node)) {
404
+ var _path$parentPath2;
405
+ const options = (_path$parentPath2 = path.parentPath) == null ? void 0 : _path$parentPath2.node.arguments[0];
406
+ return tryOptions(options);
407
+ }
408
+ }
409
+
410
+ // All credit for this amazing function goes to the Next.js team
411
+ // (and the Solid.js team for their derivative work).
412
+ // https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform.ts
413
+ // https://github.com/solidjs/solid-start/blob/main/packages/start/server/routeData.js
414
+
415
+ function cleanUnusedCode(programPath, state, keepExports) {
416
+ state.refs = new Set();
417
+ state.done = false;
418
+ function markVariable(variablePath, variableState) {
419
+ if (variablePath.node.id.type === 'Identifier') {
420
+ const local = variablePath.get('id');
421
+ if (isIdentifierReferenced(local)) {
422
+ variableState.refs.add(local);
423
+ }
424
+ } else if (variablePath.node.id.type === 'ObjectPattern') {
425
+ const pattern = variablePath.get('id');
426
+ const properties = pattern.get('properties');
427
+ properties.forEach(p => {
428
+ const local = p.get(p.node.type === 'ObjectProperty' ? 'value' : p.node.type === 'RestElement' ? 'argument' : function () {
429
+ throw new Error('invariant');
430
+ }());
431
+ if (isIdentifierReferenced(local)) {
432
+ variableState.refs.add(local);
433
+ }
434
+ });
435
+ } else if (variablePath.node.id.type === 'ArrayPattern') {
436
+ const pattern = variablePath.get('id');
437
+ const elements = pattern.get('elements');
438
+ elements.forEach(e => {
439
+ let local;
440
+ if (e.node && e.node.type === 'Identifier') {
441
+ local = e;
442
+ } else if (e.node && e.node.type === 'RestElement') {
443
+ local = e.get('argument');
444
+ } else {
445
+ return;
446
+ }
447
+ if (isIdentifierReferenced(local)) {
448
+ variableState.refs.add(local);
449
+ }
450
+ });
451
+ }
452
+ }
453
+
454
+ // Mark all variables and functions if used
455
+ programPath.traverse({
456
+ VariableDeclarator: markVariable,
457
+ FunctionDeclaration: markFunction,
458
+ FunctionExpression: markFunction,
459
+ ArrowFunctionExpression: markFunction,
460
+ ImportSpecifier: markImport,
461
+ ImportDefaultSpecifier: markImport,
462
+ ImportNamespaceSpecifier: markImport,
463
+ ExportDefaultDeclaration: markImport,
464
+ // ExportNamedDeclaration(path, state) {
465
+ // if (t.isVariableDeclaration(path.node.declaration)) {
466
+ // if (t.isVariableDeclarator(path.node.declaration.declarations?.[0])) {
467
+ // if (t.isIdentifier(path.node.declaration.declarations[0].id)) {
468
+ // if (
469
+ // keepExports.includes(
470
+ // path.node.declaration.declarations[0].id.name,
471
+ // )
472
+ // ) {
473
+ // return
474
+ // }
475
+ // }
476
+ // path.replaceWith(path.node.declaration.declarations[0])
477
+ // return
478
+ // }
479
+ // }
480
+ // path.remove()
481
+ // },
482
+ ImportDeclaration: path => {
483
+ if (path.node.source.value.endsWith('.css')) {
484
+ path.remove();
485
+ }
486
+ }
487
+ }, state);
488
+
489
+ // Sweet all of the remaining references and remove unused ones
490
+ const refs = state.refs;
491
+ let count;
492
+ function sweepFunction(sweepPath) {
493
+ const ident = getIdentifier(sweepPath);
494
+ if (ident && ident.node && refs.has(ident) && !isIdentifierReferenced(ident)) {
495
+ ++count;
496
+ if (t__namespace.isAssignmentExpression(sweepPath.parentPath) || t__namespace.isVariableDeclarator(sweepPath.parentPath)) {
497
+ sweepPath.parentPath.remove();
498
+ } else {
499
+ sweepPath.remove();
500
+ }
501
+ }
502
+ }
503
+ function sweepImport(sweepPath) {
504
+ const local = sweepPath.get('local');
505
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
506
+ ++count;
507
+ sweepPath.remove();
508
+ if (sweepPath.parent.specifiers.length === 0) {
509
+ sweepPath.parentPath.remove();
510
+ }
511
+ }
512
+ }
513
+ do {
514
+ programPath.scope.crawl();
515
+ count = 0;
516
+ programPath.traverse({
517
+ VariableDeclarator(variablePath) {
518
+ if (variablePath.node.id.type === 'Identifier') {
519
+ const local = variablePath.get('id');
520
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
521
+ ++count;
522
+ variablePath.remove();
523
+ }
524
+ } else if (variablePath.node.id.type === 'ObjectPattern') {
525
+ const pattern = variablePath.get('id');
526
+ const beforeCount = count;
527
+ const properties = pattern.get('properties');
528
+ properties.forEach(p => {
529
+ const local = p.get(p.node.type === 'ObjectProperty' ? 'value' : p.node.type === 'RestElement' ? 'argument' : function () {
530
+ throw new Error('invariant');
531
+ }());
532
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
533
+ ++count;
534
+ p.remove();
535
+ }
536
+ });
537
+ if (beforeCount !== count && pattern.get('properties').length < 1) {
538
+ variablePath.remove();
539
+ }
540
+ } else if (variablePath.node.id.type === 'ArrayPattern') {
541
+ const pattern = variablePath.get('id');
542
+ const beforeCount = count;
543
+ const elements = pattern.get('elements');
544
+ elements.forEach(e => {
545
+ let local;
546
+ if (e.node && e.node.type === 'Identifier') {
547
+ local = e;
548
+ } else if (e.node && e.node.type === 'RestElement') {
549
+ local = e.get('argument');
550
+ } else {
551
+ return;
552
+ }
553
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
554
+ ++count;
555
+ e.remove();
556
+ }
557
+ });
558
+ if (beforeCount !== count && pattern.get('elements').length < 1) {
559
+ variablePath.remove();
560
+ }
561
+ }
562
+ },
563
+ FunctionDeclaration: sweepFunction,
564
+ FunctionExpression: sweepFunction,
565
+ ArrowFunctionExpression: sweepFunction,
566
+ ImportSpecifier: sweepImport,
567
+ ImportDefaultSpecifier: sweepImport,
568
+ ImportNamespaceSpecifier: sweepImport
569
+ });
570
+ } while (count);
571
+
572
+ // Do we need the * import for react?
573
+ let hasReact = false;
574
+
575
+ // Mark react elements as having react
576
+ programPath.traverse({
577
+ JSXElement(path) {
578
+ hasReact = true;
579
+ }
580
+ });
581
+ if (!hasReact) {
582
+ // Mark all variables and functions if used
583
+ programPath.traverse({
584
+ ImportDeclaration(path) {
585
+ if (t__namespace.isStringLiteral(path.node.source) && path.node.source.value === 'react' && t__namespace.isImportNamespaceSpecifier(path.node.specifiers[0])) {
586
+ path.remove();
587
+ }
588
+ }
589
+ });
590
+ }
591
+ }
592
+
593
+ exports.detectExports = detectExports;
594
+ exports.ensureBoilerplate = ensureBoilerplate;
595
+ exports.generateRouteConfig = generateRouteConfig;
596
+ exports.isolateOptionToExport = isolateOptionToExport;
597
+ exports.isolatedProperties = isolatedProperties;
598
+ //# sourceMappingURL=transformCode.js.map