@gtkx/cli 2.0.0-beta.1 → 2.0.0-beta.2
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/builder.d.ts +1 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +17 -5
- package/dist/builder.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +4 -2
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +13 -8
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +1 -1
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js +2 -2
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +83 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.d.ts +1 -0
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +6 -5
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +4 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +8 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +19 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
- package/dist/deploy/freedesktop/metainfo.js +41 -2
- package/dist/deploy/freedesktop/metainfo.js.map +1 -1
- package/dist/deploy/nfpm/config.d.ts.map +1 -1
- package/dist/deploy/nfpm/config.js +5 -2
- package/dist/deploy/nfpm/config.js.map +1 -1
- package/dist/deploy/nfpm/contents.d.ts.map +1 -1
- package/dist/deploy/nfpm/contents.js +8 -0
- package/dist/deploy/nfpm/contents.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +2 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +32 -5
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts +2 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +73 -4
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/notices/node-runtime.js +2 -2
- package/dist/deploy/notices/node-runtime.js.map +1 -1
- package/dist/deploy/payload/launcher.d.ts.map +1 -1
- package/dist/deploy/payload/launcher.js +14 -1
- package/dist/deploy/payload/launcher.js.map +1 -1
- package/dist/deploy/payload/stage.js +1 -1
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts +1 -0
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +100 -14
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/build-manifest.d.ts +6 -1
- package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
- package/dist/deploy/settings/build-manifest.js +15 -4
- package/dist/deploy/settings/build-manifest.js.map +1 -1
- package/dist/deploy/settings/extra-files.d.ts +1 -1
- package/dist/deploy/settings/extra-files.d.ts.map +1 -1
- package/dist/deploy/settings/extra-files.js +22 -1
- package/dist/deploy/settings/extra-files.js.map +1 -1
- package/dist/deploy/settings/index.d.ts +1 -0
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +2 -1
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/paths.d.ts +2 -1
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +113 -5
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +11 -2
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/types.d.ts +1 -0
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/dev/headless.d.ts +3 -0
- package/dist/dev/headless.d.ts.map +1 -0
- package/dist/dev/headless.js +35 -0
- package/dist/dev/headless.js.map +1 -0
- package/dist/dev/runner-deps.js +1 -1
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/i18n/source-messages.d.ts.map +1 -1
- package/dist/i18n/source-messages.js +835 -1
- package/dist/i18n/source-messages.js.map +1 -1
- package/dist/internal/build-manifest.d.ts +5 -2
- package/dist/internal/build-manifest.d.ts.map +1 -1
- package/dist/internal/build-manifest.js +15 -2
- package/dist/internal/build-manifest.js.map +1 -1
- package/dist/internal/build-output.d.ts +8 -0
- package/dist/internal/build-output.d.ts.map +1 -0
- package/dist/internal/build-output.js +69 -0
- package/dist/internal/build-output.js.map +1 -0
- package/dist/internal/entry-arg.d.ts +4 -1
- package/dist/internal/entry-arg.d.ts.map +1 -1
- package/dist/internal/entry-arg.js +7 -1
- package/dist/internal/entry-arg.js.map +1 -1
- package/dist/internal/output-directory.d.ts +15 -0
- package/dist/internal/output-directory.d.ts.map +1 -0
- package/dist/internal/output-directory.js +490 -0
- package/dist/internal/output-directory.js.map +1 -0
- package/dist/internal/prepare-project.d.ts +2 -0
- package/dist/internal/prepare-project.d.ts.map +1 -1
- package/dist/internal/prepare-project.js +3 -3
- package/dist/internal/prepare-project.js.map +1 -1
- package/dist/internal/source-imports.js +1 -1
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/client.js.map +1 -1
- package/dist/vite-plugins/build-manifest.d.ts +5 -1
- package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
- package/dist/vite-plugins/build-manifest.js +2 -1
- package/dist/vite-plugins/build-manifest.js.map +1 -1
- package/dist/vite-plugins/i18n.d.ts.map +1 -1
- package/dist/vite-plugins/i18n.js +58 -6
- package/dist/vite-plugins/i18n.js.map +1 -1
- package/dist/vite-plugins/index.d.ts +8 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +6 -2
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/self-contained.d.ts.map +1 -1
- package/dist/vite-plugins/self-contained.js +159 -158
- package/dist/vite-plugins/self-contained.js.map +1 -1
- package/package.json +9 -9
- package/src/builder.ts +18 -5
- package/src/cli.ts +3 -0
- package/src/codegen/run-codegen.ts +15 -7
- package/src/codegen/store-resolver.ts +2 -2
- package/src/commands/build.ts +13 -2
- package/src/commands/codegen.ts +6 -5
- package/src/commands/deploy.ts +4 -2
- package/src/commands/dev.ts +20 -1
- package/src/deploy/freedesktop/metainfo.ts +73 -21
- package/src/deploy/nfpm/config.ts +5 -2
- package/src/deploy/nfpm/contents.ts +8 -0
- package/src/deploy/node-runtime/elf.ts +43 -5
- package/src/deploy/node-runtime/index.ts +105 -5
- package/src/deploy/notices/node-runtime.ts +2 -2
- package/src/deploy/payload/launcher.ts +20 -1
- package/src/deploy/payload/stage.ts +1 -1
- package/src/deploy/run-deploy.ts +56 -16
- package/src/deploy/settings/build-manifest.ts +28 -3
- package/src/deploy/settings/extra-files.ts +26 -2
- package/src/deploy/settings/index.ts +3 -1
- package/src/deploy/settings/paths.ts +70 -5
- package/src/deploy/targets/flatpak-source.ts +13 -2
- package/src/deploy/types.ts +1 -0
- package/src/dev/headless.ts +40 -0
- package/src/dev/runner-deps.ts +1 -1
- package/src/i18n/source-messages.ts +1220 -2
- package/src/internal/build-manifest.ts +25 -1
- package/src/internal/build-output.ts +99 -0
- package/src/internal/entry-arg.ts +8 -1
- package/src/internal/output-directory.ts +699 -0
- package/src/internal/prepare-project.ts +5 -5
- package/src/internal/source-imports.ts +1 -1
- package/src/mcp/client.ts +2 -2
- package/src/vite-plugins/build-manifest.ts +7 -1
- package/src/vite-plugins/i18n.ts +86 -5
- package/src/vite-plugins/index.ts +14 -7
- package/src/vite-plugins/self-contained.ts +184 -185
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import { type NodePath, parseSync, type Scope, traverse } from "@babel/core";
|
|
2
3
|
import { isBuiltin } from "node:module";
|
|
3
4
|
import { posix } from "node:path";
|
|
4
|
-
import { parseSync, Visitor } from "vite";
|
|
5
5
|
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
requires: Set<string>;
|
|
10
|
-
urls: Set<string>;
|
|
11
|
-
};
|
|
6
|
+
type BindingKind = "factory" | "module" | "require" | "url";
|
|
7
|
+
|
|
8
|
+
type ResolvedBinding = NonNullable<ReturnType<Scope["getBinding"]>>;
|
|
12
9
|
|
|
13
10
|
type Scan = {
|
|
14
|
-
bindings: Bindings;
|
|
15
|
-
calls: ESTree.CallExpression[];
|
|
16
11
|
sources: string[];
|
|
17
12
|
};
|
|
18
13
|
|
|
@@ -21,199 +16,208 @@ type Chunk = {
|
|
|
21
16
|
code: string;
|
|
22
17
|
};
|
|
23
18
|
|
|
24
|
-
type PatternItem =
|
|
25
|
-
| ESTree.BindingPattern |
|
|
26
|
-
ESTree.BindingProperty |
|
|
27
|
-
ESTree.BindingRestElement |
|
|
28
|
-
ESTree.FormalParameterRest |
|
|
29
|
-
ESTree.TSParameterProperty |
|
|
30
|
-
null;
|
|
31
|
-
|
|
32
19
|
const REQUIRE_FACTORY = "createRequire";
|
|
33
20
|
const REQUIRE_BINDING = "require";
|
|
34
21
|
const RESOLVE_PROPERTY = "resolve";
|
|
35
|
-
const
|
|
22
|
+
const URL_PROPERTY = "url";
|
|
23
|
+
const MODULE_BUILTINS = new Set(["module", "node:module"]);
|
|
36
24
|
const OUTPUT_DIRECTORY = ".";
|
|
37
25
|
const RELATIVE_SPECIFIER = /^\.\.?(?:\/|$)/;
|
|
38
26
|
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const countName = (declarations: Map<string, number>, name: string | null): void => {
|
|
43
|
-
if (name !== null) {
|
|
44
|
-
declarations.set(name, (declarations.get(name) ?? 0) + 1);
|
|
27
|
+
const importedName = (path: NodePath): string | null => {
|
|
28
|
+
if (!path.isImportSpecifier()) {
|
|
29
|
+
return null;
|
|
45
30
|
}
|
|
31
|
+
|
|
32
|
+
const { imported } = path.node;
|
|
33
|
+
|
|
34
|
+
return imported.type === "Identifier" ? imported.name : imported.value;
|
|
46
35
|
};
|
|
47
36
|
|
|
48
|
-
const
|
|
49
|
-
|
|
37
|
+
const importKind = (path: NodePath): BindingKind | null => {
|
|
38
|
+
const declaration = path.parentPath;
|
|
39
|
+
|
|
40
|
+
if (!declaration.isImportDeclaration() || !MODULE_BUILTINS.has(declaration.node.source.value)) {
|
|
50
41
|
return null;
|
|
51
42
|
}
|
|
52
43
|
|
|
53
|
-
if (
|
|
54
|
-
return
|
|
44
|
+
if (importedName(path) === REQUIRE_FACTORY) {
|
|
45
|
+
return "factory";
|
|
55
46
|
}
|
|
56
47
|
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
return path.isImportNamespaceSpecifier() || path.isImportDefaultSpecifier() ? "module" : null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const memberName = (path: NodePath): string | null => {
|
|
52
|
+
if (!path.isMemberExpression()) {
|
|
53
|
+
return null;
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
};
|
|
56
|
+
const property = path.get("property");
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
countPattern(declarations, boundPattern(item));
|
|
58
|
+
if (path.node.computed) {
|
|
59
|
+
return property.isStringLiteral() ? property.node.value : null;
|
|
67
60
|
}
|
|
61
|
+
|
|
62
|
+
return property.isIdentifier() ? property.node.name : null;
|
|
68
63
|
};
|
|
69
64
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
const isImportMeta = (path: NodePath): boolean =>
|
|
66
|
+
path.isMetaProperty() && path.node.meta.name === "import" && path.node.property.name === "meta";
|
|
67
|
+
|
|
68
|
+
const isDirectMetaUrl = (path: NodePath): boolean => {
|
|
69
|
+
if (!path.isMemberExpression() || memberName(path) !== URL_PROPERTY) {
|
|
70
|
+
return false;
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
countName(declarations, pattern.name);
|
|
73
|
+
const object = path.get("object");
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
return isImportMeta(object);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const bindingKind = (binding: ResolvedBinding, seen: Set<ResolvedBinding>): BindingKind | null => {
|
|
79
|
+
if (seen.has(binding)) {
|
|
80
|
+
return null;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
const next = new Set(seen).add(binding);
|
|
84
|
+
const imported = importKind(binding.path);
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
if (imported !== null) {
|
|
87
|
+
return imported;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!binding.path.isVariableDeclarator()) {
|
|
91
|
+
return null;
|
|
85
92
|
}
|
|
86
93
|
|
|
87
|
-
|
|
94
|
+
const initializer = binding.path.get("init");
|
|
95
|
+
|
|
96
|
+
return initializer.node === null ? null : expressionKind(initializer, next);
|
|
88
97
|
};
|
|
89
98
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
const nameKind = (scope: Scope, name: string, seen: Set<ResolvedBinding>): BindingKind | null => {
|
|
100
|
+
const binding = scope.getBinding(name);
|
|
101
|
+
|
|
102
|
+
if (binding !== undefined) {
|
|
103
|
+
return bindingKind(binding, seen);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (name === REQUIRE_FACTORY) {
|
|
107
|
+
return "factory";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return name === REQUIRE_BINDING ? "require" : null;
|
|
96
111
|
};
|
|
97
112
|
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
},
|
|
117
|
-
FunctionExpression: (node) => {
|
|
118
|
-
countFunction(declarations, node);
|
|
119
|
-
},
|
|
120
|
-
ImportDefaultSpecifier: (node) => {
|
|
121
|
-
countPattern(declarations, node.local);
|
|
122
|
-
},
|
|
123
|
-
ImportNamespaceSpecifier: (node) => {
|
|
124
|
-
countPattern(declarations, node.local);
|
|
125
|
-
},
|
|
126
|
-
ImportSpecifier: (node) => {
|
|
127
|
-
countPattern(declarations, node.local);
|
|
128
|
-
},
|
|
129
|
-
VariableDeclarator: (node) => {
|
|
130
|
-
countPattern(declarations, node.id);
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
const isUnshadowed = (name: string, bindings: Bindings): boolean => (bindings.declarations.get(name) ?? 0) <= 1;
|
|
135
|
-
|
|
136
|
-
const templateString = (node: ESTree.TemplateLiteral): string | null => {
|
|
137
|
-
const [quasi] = node.quasis;
|
|
138
|
-
|
|
139
|
-
return quasi === undefined || node.expressions.length > 0 ? null : quasi.value.cooked;
|
|
113
|
+
const isModuleExpression = (path: NodePath, seen: Set<ResolvedBinding>): boolean => {
|
|
114
|
+
if (path.isIdentifier()) {
|
|
115
|
+
return nameKind(path.scope, path.node.name, seen) === "module";
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!path.isCallExpression()) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const [source] = path.get("arguments");
|
|
123
|
+
const callee = path.get("callee");
|
|
124
|
+
const sourceName = source === undefined ? null : literalString(source);
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
sourceName !== null &&
|
|
128
|
+
MODULE_BUILTINS.has(sourceName) &&
|
|
129
|
+
isRequireExpression(callee, seen)
|
|
130
|
+
);
|
|
140
131
|
};
|
|
141
132
|
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
144
|
-
return
|
|
133
|
+
const isFactoryExpression = (path: NodePath, seen: Set<ResolvedBinding>): boolean => {
|
|
134
|
+
if (path.isIdentifier()) {
|
|
135
|
+
return nameKind(path.scope, path.node.name, seen) === "factory";
|
|
145
136
|
}
|
|
146
137
|
|
|
147
|
-
|
|
138
|
+
if (!path.isMemberExpression() || memberName(path) !== REQUIRE_FACTORY) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return isModuleExpression(path.get("object"), seen);
|
|
148
143
|
};
|
|
149
144
|
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
-
return
|
|
145
|
+
const isRequireFactoryCall = (path: NodePath, seen: Set<ResolvedBinding>): boolean => {
|
|
146
|
+
if (!path.isCallExpression()) {
|
|
147
|
+
return false;
|
|
153
148
|
}
|
|
154
149
|
|
|
155
|
-
const
|
|
150
|
+
const callee = path.get("callee");
|
|
156
151
|
|
|
157
|
-
return
|
|
152
|
+
return isFactoryExpression(callee, seen);
|
|
158
153
|
};
|
|
159
154
|
|
|
160
|
-
const
|
|
161
|
-
|
|
155
|
+
const expressionKind = (path: NodePath, seen: Set<ResolvedBinding>): BindingKind | null => {
|
|
156
|
+
if (isDirectMetaUrl(path)) {
|
|
157
|
+
return "url";
|
|
158
|
+
}
|
|
162
159
|
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
if (path.isIdentifier()) {
|
|
161
|
+
return nameKind(path.scope, path.node.name, seen);
|
|
162
|
+
}
|
|
165
163
|
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
if (isFactoryExpression(path, seen)) {
|
|
165
|
+
return "factory";
|
|
166
|
+
}
|
|
168
167
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
if (isModuleExpression(path, seen)) {
|
|
169
|
+
return "module";
|
|
170
|
+
}
|
|
172
171
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
isRequireName(referenceName(object), bindings) ||
|
|
176
|
-
isRequireFactory(object, bindings);
|
|
172
|
+
return isRequireFactoryCall(path, seen) ? "require" : null;
|
|
173
|
+
};
|
|
177
174
|
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
callee.property.type === "Identifier" &&
|
|
182
|
-
callee.property.name === RESOLVE_PROPERTY &&
|
|
183
|
-
isResolveTarget(callee.object, bindings);
|
|
175
|
+
const isMetaUrl = (path: NodePath): boolean =>
|
|
176
|
+
isDirectMetaUrl(path) ||
|
|
177
|
+
(path.isIdentifier() && nameKind(path.scope, path.node.name, new Set()) === "url");
|
|
184
178
|
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
isRequireFactory(call.callee, bindings) ||
|
|
189
|
-
isResolveMember(call.callee, bindings);
|
|
179
|
+
const isRequireExpression = (path: NodePath, seen: Set<ResolvedBinding> = new Set()): boolean =>
|
|
180
|
+
isRequireFactoryCall(path, seen) ||
|
|
181
|
+
(path.isIdentifier() && nameKind(path.scope, path.node.name, seen) === "require");
|
|
190
182
|
|
|
191
|
-
const
|
|
192
|
-
if (
|
|
193
|
-
return;
|
|
183
|
+
const hasMetaUrlArgument = (path: NodePath): boolean => {
|
|
184
|
+
if (!path.isCallExpression()) {
|
|
185
|
+
return false;
|
|
194
186
|
}
|
|
195
187
|
|
|
196
|
-
|
|
197
|
-
if (specifier.type === "ImportSpecifier" && exportName(specifier.imported) === REQUIRE_FACTORY) {
|
|
198
|
-
bindings.factories.add(specifier.local.name);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
188
|
+
return path.get("arguments").some((argument) => isMetaUrl(argument));
|
|
201
189
|
};
|
|
202
190
|
|
|
203
|
-
const
|
|
204
|
-
|
|
191
|
+
const isResolveMember = (path: NodePath): boolean => {
|
|
192
|
+
if (!path.isMemberExpression() || memberName(path) !== RESOLVE_PROPERTY) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
205
195
|
|
|
206
|
-
|
|
207
|
-
|
|
196
|
+
const object = path.get("object");
|
|
197
|
+
|
|
198
|
+
return isImportMeta(object) || isRequireExpression(object);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const isResolvingCall = (path: NodePath): boolean => {
|
|
202
|
+
if (!path.isCallExpression()) {
|
|
203
|
+
return false;
|
|
208
204
|
}
|
|
209
205
|
|
|
210
|
-
|
|
211
|
-
|
|
206
|
+
const callee = path.get("callee");
|
|
207
|
+
|
|
208
|
+
return hasMetaUrlArgument(path) || isRequireExpression(callee) || isResolveMember(callee);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const literalString = (path: NodePath): string | null => {
|
|
212
|
+
if (path.isStringLiteral()) {
|
|
213
|
+
return path.node.value;
|
|
212
214
|
}
|
|
213
215
|
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
+
if (!path.isTemplateLiteral() || path.node.expressions.length > 0) {
|
|
217
|
+
return null;
|
|
216
218
|
}
|
|
219
|
+
|
|
220
|
+
return path.node.quasis[0]?.value.cooked ?? null;
|
|
217
221
|
};
|
|
218
222
|
|
|
219
223
|
const collectSource = (scan: Scan, source: string | null): void => {
|
|
@@ -222,55 +226,51 @@ const collectSource = (scan: Scan, source: string | null): void => {
|
|
|
222
226
|
}
|
|
223
227
|
};
|
|
224
228
|
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
|
|
229
|
+
const collectCallSources = (scan: Scan, path: NodePath): void => {
|
|
230
|
+
if (!isResolvingCall(path) || !path.isCallExpression()) {
|
|
231
|
+
return;
|
|
228
232
|
}
|
|
229
|
-
};
|
|
230
233
|
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
ExportAllDeclaration: (node) => {
|
|
236
|
-
collectSource(scan, node.source.value);
|
|
237
|
-
},
|
|
238
|
-
ExportNamedDeclaration: (node) => {
|
|
239
|
-
collectSource(scan, node.source?.value ?? null);
|
|
240
|
-
},
|
|
241
|
-
ImportDeclaration: (node) => {
|
|
242
|
-
collectFactories(node, scan.bindings);
|
|
243
|
-
collectSource(scan, node.source.value);
|
|
244
|
-
},
|
|
245
|
-
ImportExpression: (node) => {
|
|
246
|
-
collectSource(scan, literalString(node.source));
|
|
247
|
-
},
|
|
248
|
-
VariableDeclarator: (node) => {
|
|
249
|
-
collectBinding(node, scan.bindings);
|
|
250
|
-
},
|
|
251
|
-
});
|
|
234
|
+
for (const argument of path.get("arguments")) {
|
|
235
|
+
collectSource(scan, literalString(argument));
|
|
236
|
+
}
|
|
237
|
+
};
|
|
252
238
|
|
|
253
239
|
const scanChunk = (chunk: Chunk): Scan => {
|
|
254
|
-
const scan: Scan = {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
240
|
+
const scan: Scan = { sources: [] };
|
|
241
|
+
const ast = parseSync(chunk.code, {
|
|
242
|
+
ast: true,
|
|
243
|
+
babelrc: false,
|
|
244
|
+
configFile: false,
|
|
245
|
+
filename: chunk.fileName,
|
|
246
|
+
sourceType: "module",
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
if (ast === null) {
|
|
250
|
+
throw new Error(`Cannot inspect ${chunk.fileName}`);
|
|
251
|
+
}
|
|
259
252
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
253
|
+
traverse(ast, {
|
|
254
|
+
CallExpression: (path) => {
|
|
255
|
+
collectCallSources(scan, path);
|
|
256
|
+
},
|
|
257
|
+
ExportAllDeclaration: (path) => {
|
|
258
|
+
collectSource(scan, path.node.source.value);
|
|
259
|
+
},
|
|
260
|
+
ExportNamedDeclaration: (path) => {
|
|
261
|
+
collectSource(scan, path.node.source?.value ?? null);
|
|
262
|
+
},
|
|
263
|
+
ImportDeclaration: (path) => {
|
|
264
|
+
collectSource(scan, path.node.source.value);
|
|
265
|
+
},
|
|
266
|
+
ImportExpression: (path) => {
|
|
267
|
+
collectSource(scan, literalString(path.get("source")));
|
|
268
|
+
},
|
|
269
|
+
});
|
|
263
270
|
|
|
264
271
|
return scan;
|
|
265
272
|
};
|
|
266
273
|
|
|
267
|
-
const callSpecifiers = (scan: Scan): string[] =>
|
|
268
|
-
scan.calls
|
|
269
|
-
.filter((call) => isResolvingCall(call, scan.bindings))
|
|
270
|
-
.flatMap((call) => call.arguments)
|
|
271
|
-
.map((argument) => literalString(argument))
|
|
272
|
-
.filter((specifier) => specifier !== null);
|
|
273
|
-
|
|
274
274
|
const isReachable = (specifier: string, directory: string, emitted: Set<string>): boolean => {
|
|
275
275
|
if (isBuiltin(specifier)) {
|
|
276
276
|
return true;
|
|
@@ -286,10 +286,9 @@ const isReachable = (specifier: string, directory: string, emitted: Set<string>)
|
|
|
286
286
|
};
|
|
287
287
|
|
|
288
288
|
const unreachableSpecifiers = (chunk: Chunk, emitted: Set<string>): string[] => {
|
|
289
|
-
const scan = scanChunk(chunk);
|
|
290
289
|
const directory = posix.dirname(chunk.fileName);
|
|
291
290
|
|
|
292
|
-
return new Set(
|
|
291
|
+
return new Set(scanChunk(chunk).sources)
|
|
293
292
|
.values()
|
|
294
293
|
.filter((specifier) => !isReachable(specifier, directory, emitted))
|
|
295
294
|
.toArray()
|