@veryfront/ext-parser-babel 0.1.1238 → 0.1.1240

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 CHANGED
@@ -18,10 +18,12 @@ export default defineConfig({
18
18
 
19
19
  ## Provided contract
20
20
 
21
- `CodeParser` exposes:
21
+ `CodeParser` exposes:
22
22
 
23
- - `parse(source, options)` / `traverse(ast, visitor)` / `generate(ast, options)` generic AST pipeline for callers that want to build custom transforms.
24
- - `injectJsxNodePositions(source, options)` — the Studio Navigator helper that stamps `data-node-*` attributes onto JSX elements at compile time.
23
+ - `parse(options)` / `traverse(ast, visitor)` / `generate(ast, options)`: generic AST pipeline for callers that want to build custom transforms.
24
+ - `hasFunctionDirective(options)`: parser-owned function directive detection with Babel's syntax semantics.
25
+ - `findStaticCommonJsImports(options)`: parser-owned static CommonJS discovery that respects lexical and TypeScript bindings.
26
+ - `injectJsxNodePositions(source, options)`: the Studio Navigator helper that stamps `data-node-*` attributes onto JSX elements at compile time.
25
27
 
26
28
  Core's `src/transforms/plugins/babel-node-positions.ts` is a thin shim that resolves this contract at call time. When the extension is not installed and the shim is invoked, Veryfront throws an install-suggestion error directing the user to add `@veryfront/ext-parser-babel`.
27
29
 
@@ -0,0 +1,11 @@
1
+ import { Deno } from "@deno/shim-deno";
2
+ export { Deno } from "@deno/shim-deno";
3
+ export { crypto, type Crypto, type SubtleCrypto, type AlgorithmIdentifier, type Algorithm, type RsaOaepParams, type BufferSource, type AesCtrParams, type AesCbcParams, type AesGcmParams, type CryptoKey, type KeyAlgorithm, type KeyType, type KeyUsage, type EcdhKeyDeriveParams, type HkdfParams, type HashAlgorithmIdentifier, type Pbkdf2Params, type AesDerivedKeyParams, type HmacImportParams, type JsonWebKey, type RsaOtherPrimesInfo, type KeyFormat, type RsaHashedKeyGenParams, type RsaKeyGenParams, type BigInteger, type EcKeyGenParams, type NamedCurve, type CryptoKeyPair, type AesKeyGenParams, type HmacKeyGenParams, type RsaHashedImportParams, type EcKeyImportParams, type AesKeyAlgorithm, type RsaPssParams, type EcdsaParams } from "@deno/shim-crypto";
4
+ export { setInterval, setTimeout } from "@deno/shim-timers";
5
+ export declare const dntGlobalThis: Omit<typeof globalThis, "Deno" | "crypto" | "setInterval" | "setTimeout"> & {
6
+ Deno: typeof Deno;
7
+ crypto: import("@deno/shim-crypto").Crypto;
8
+ setInterval: any;
9
+ setTimeout: any;
10
+ };
11
+ //# sourceMappingURL=_dnt.shims.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dnt.shims.d.ts","sourceRoot":"","sources":["../src/_dnt.shims.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,mBAAmB,EAAE,KAAK,UAAU,EAAE,KAAK,uBAAuB,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErvB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQ5D,eAAO,MAAM,aAAa;;;;;CAA2C,CAAC"}
@@ -0,0 +1,90 @@
1
+ const dntNativeDeno = globalThis.Deno;
2
+ // Prefer the host runtime's own Deno. The `@deno/shim-deno` fallback exists
3
+ // for Node and Bun; under Deno it shadows working native APIs with node:net
4
+ // reimplementations that throw (e.g. Deno.listen reads `server._handle.fd`,
5
+ // which is null on Deno's node compatibility layer).
6
+ //
7
+ // It loads lazily so Deno never resolves it at all. The esm transform
8
+ // rewrites the bare specifier to an absolute file:// bundle, and Deno
9
+ // refuses to prepare that graph node when node_modules is unmanaged, which
10
+ // is what `deno install -g` produces (`nodeModulesDir: "manual"`). A static
11
+ // import therefore failed every request with "Loading unprepared module"
12
+ // naming a bundle that was present on disk, on the one runtime that never
13
+ // reads the value.
14
+ export const Deno = typeof dntNativeDeno?.version?.deno === "string"
15
+ ? dntNativeDeno
16
+ : (await import("@deno/shim-deno")).Deno;
17
+ const dntNativeCrypto = globalThis.crypto;
18
+ // Web Crypto is a global on every runtime the framework supports (Deno,
19
+ // Node 19+, Bun), so `@deno/shim-crypto` is a fallback for runtimes that no
20
+ // longer exist in practice. It loads lazily for the same reason the Deno
21
+ // shim does: the esm transform rewrites the bare specifier to an absolute
22
+ // file:// bundle, and Deno cannot prepare that graph node when node_modules
23
+ // is unmanaged.
24
+ export const crypto = dntNativeCrypto !== undefined
25
+ ? dntNativeCrypto
26
+ : (await import("@deno/shim-crypto")).crypto;
27
+ import { setInterval, setTimeout } from "@deno/shim-timers";
28
+ export { setInterval, setTimeout } from "@deno/shim-timers";
29
+ const dntGlobals = {
30
+ Deno,
31
+ crypto,
32
+ setInterval,
33
+ setTimeout,
34
+ };
35
+ export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
36
+ function createMergeProxy(baseObj, extObj) {
37
+ return new Proxy(baseObj, {
38
+ get(_target, prop, _receiver) {
39
+ if (prop in extObj) {
40
+ return extObj[prop];
41
+ }
42
+ else {
43
+ return baseObj[prop];
44
+ }
45
+ },
46
+ set(_target, prop, value) {
47
+ if (prop in extObj) {
48
+ delete extObj[prop];
49
+ }
50
+ baseObj[prop] = value;
51
+ return true;
52
+ },
53
+ deleteProperty(_target, prop) {
54
+ let success = false;
55
+ if (prop in extObj) {
56
+ delete extObj[prop];
57
+ success = true;
58
+ }
59
+ if (prop in baseObj) {
60
+ delete baseObj[prop];
61
+ success = true;
62
+ }
63
+ return success;
64
+ },
65
+ ownKeys(_target) {
66
+ const baseKeys = Reflect.ownKeys(baseObj);
67
+ const extKeys = Reflect.ownKeys(extObj);
68
+ const extKeysSet = new Set(extKeys);
69
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
70
+ },
71
+ defineProperty(_target, prop, desc) {
72
+ if (prop in extObj) {
73
+ delete extObj[prop];
74
+ }
75
+ Reflect.defineProperty(baseObj, prop, desc);
76
+ return true;
77
+ },
78
+ getOwnPropertyDescriptor(_target, prop) {
79
+ if (prop in extObj) {
80
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
81
+ }
82
+ else {
83
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
84
+ }
85
+ },
86
+ has(_target, prop) {
87
+ return prop in extObj || prop in baseObj;
88
+ },
89
+ });
90
+ }
package/esm/index.d.ts CHANGED
@@ -1,25 +1,11 @@
1
- /**
2
- * ext-parser-babel — CodeParser implementation backed by @babel/parser,
3
- * @babel/traverse, @babel/generator, @babel/types.
4
- *
5
- * Provides the `CodeParser` contract:
6
- * - `parse/traverse/generate` — generic AST pipeline for callers that
7
- * want to build custom transforms.
8
- * - `injectJsxNodePositions(source, options)` — the Studio Navigator
9
- * helper that stamps `data-node-*` attributes onto JSX elements.
10
- *
11
- * Core's `src/transforms/plugins/babel-node-positions.ts` is a shim that
12
- * resolves this contract at call time.
13
- *
14
- * @module extensions/ext-parser-babel
15
- */
16
1
  import type { ExtensionFactory } from "veryfront/extensions";
17
- import type { ASTNode, CodeParser, FunctionDirectiveOptions, GenerateOptions, GenerateResult, InjectJsxNodePositionsOptions, TraverseVisitor } from "veryfront/extensions/parser";
2
+ import type { ASTNode, CodeParser, FunctionDirectiveOptions, GenerateOptions, GenerateResult, InjectJsxNodePositionsOptions, ParseOptions, TraverseVisitor } from "veryfront/extensions/parser";
18
3
  import { BabelParseOnlyParser } from "./parser-only.js";
19
4
  declare class BabelCodeParser extends BabelParseOnlyParser implements CodeParser {
20
5
  traverse(ast: ASTNode, visitor: TraverseVisitor): void;
21
6
  generate(ast: ASTNode, options?: GenerateOptions): Promise<GenerateResult>;
22
7
  hasFunctionDirective(options: FunctionDirectiveOptions): Promise<boolean>;
8
+ findStaticCommonJsImports(options: ParseOptions): Promise<readonly string[]>;
23
9
  injectJsxNodePositions(source: string, options: InjectJsxNodePositionsOptions): string;
24
10
  }
25
11
  declare const extBabel: ExtensionFactory;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,6BAA6B,EAC7B,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAwDxD,cAAM,eAAgB,SAAQ,oBAAqB,YAAW,UAAU;IACtE,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAItD,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAWpE,oBAAoB,CACxB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC;IAcnB,sBAAsB,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,6BAA6B,GACrC,MAAM;CAGV;AAED,QAAA,MAAM,QAAQ,EAAE,gBAiBf,CAAC;AAEF,eAAe,QAAQ,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,6BAA6B,EAC7B,YAAY,EACZ,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AA4axD,cAAM,eAAgB,SAAQ,oBAAqB,YAAW,UAAU;IACtE,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAItD,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAWpE,oBAAoB,CACxB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC;IAcb,yBAAyB,CAC7B,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;IAuB7B,sBAAsB,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,6BAA6B,GACrC,MAAM;CAGV;AAED,QAAA,MAAM,QAAQ,EAAE,gBAiBf,CAAC;AAEF,eAAe,QAAQ,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,CAAC"}
package/esm/index.js CHANGED
@@ -1,11 +1,14 @@
1
1
  /**
2
- * ext-parser-babel CodeParser implementation backed by @babel/parser,
2
+ * ext-parser-babel: CodeParser implementation backed by @babel/parser,
3
3
  * @babel/traverse, @babel/generator, @babel/types.
4
4
  *
5
5
  * Provides the `CodeParser` contract:
6
- * - `parse/traverse/generate` generic AST pipeline for callers that
6
+ * - `parse/traverse/generate`: generic AST pipeline for callers that
7
7
  * want to build custom transforms.
8
- * - `injectJsxNodePositions(source, options)` the Studio Navigator
8
+ * - `hasFunctionDirective(options)`: parser-owned directive detection.
9
+ * - `findStaticCommonJsImports(options)`: static CommonJS discovery with
10
+ * Babel lexical and TypeScript binding semantics.
11
+ * - `injectJsxNodePositions(source, options)`: the Studio Navigator
9
12
  * helper that stamps `data-node-*` attributes onto JSX elements.
10
13
  *
11
14
  * Core's `src/transforms/plugins/babel-node-positions.ts` is a shim that
@@ -13,8 +16,10 @@
13
16
  *
14
17
  * @module extensions/ext-parser-babel
15
18
  */
19
+ import * as dntShim from "./_dnt.shims.js";
16
20
  import * as traverseModule from "@babel/traverse";
17
21
  import * as generateModule from "@babel/generator";
22
+ import { BUNDLE_ERROR } from "veryfront/errors";
18
23
  import { injectNodePositions } from "./inject-node-positions.js";
19
24
  import { BabelParseOnlyParser } from "./parser-only.js";
20
25
  function resolveDefaultExport(mod) {
@@ -28,6 +33,88 @@ function resolveDefaultExport(mod) {
28
33
  }
29
34
  const traverse = resolveDefaultExport(traverseModule);
30
35
  const generate = resolveDefaultExport(generateModule);
36
+ const ReflectApply = Reflect.apply;
37
+ const ReflectOwnKeys = Reflect.ownKeys;
38
+ const ArrayIsArray = Array.isArray;
39
+ const ArrayPush = Array.prototype.push;
40
+ const ArraySome = Array.prototype.some;
41
+ const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
42
+ const MAX_STATIC_STRING_DEPTH = 16;
43
+ const MAX_STATIC_STRING_PARTS = 32;
44
+ const MAX_STATIC_STRING_LENGTH = 2_048;
45
+ function arrayPush(array, value) {
46
+ return ReflectApply(ArrayPush, array, [value]);
47
+ }
48
+ function arraySome(array, predicate) {
49
+ return ReflectApply(ArraySome, array, [predicate]);
50
+ }
51
+ function getOwnPropertyDescriptor(owner, key) {
52
+ return ReflectApply(ObjectGetOwnPropertyDescriptor, Object, [owner, key]);
53
+ }
54
+ function capturePrimitiveMethods(owner) {
55
+ const keys = ReflectApply(ReflectOwnKeys, Reflect, [owner]);
56
+ const entries = [];
57
+ for (let index = 0; index < keys.length; index++) {
58
+ const key = keys[index];
59
+ const descriptor = getOwnPropertyDescriptor(owner, key);
60
+ if (typeof descriptor?.value !== "function")
61
+ continue;
62
+ arrayPush(entries, { key, value: descriptor.value });
63
+ }
64
+ return { owner, entries };
65
+ }
66
+ const COMMON_JS_ANALYSIS_PRIMITIVES = [
67
+ capturePrimitiveMethods(Array),
68
+ capturePrimitiveMethods(Array.prototype),
69
+ capturePrimitiveMethods(Function.prototype),
70
+ capturePrimitiveMethods(Map.prototype),
71
+ capturePrimitiveMethods(Object),
72
+ capturePrimitiveMethods(Object.prototype),
73
+ capturePrimitiveMethods(RegExp.prototype),
74
+ capturePrimitiveMethods(Set.prototype),
75
+ capturePrimitiveMethods(String.prototype),
76
+ capturePrimitiveMethods(WeakMap.prototype),
77
+ capturePrimitiveMethods(WeakSet.prototype),
78
+ ];
79
+ const COMMON_JS_ANALYSIS_GLOBALS = [
80
+ { key: "Array", value: Array },
81
+ { key: "Function", value: Function },
82
+ { key: "Map", value: Map },
83
+ { key: "Object", value: Object },
84
+ { key: "Promise", value: Promise },
85
+ { key: "RegExp", value: RegExp },
86
+ { key: "Set", value: Set },
87
+ { key: "String", value: String },
88
+ { key: "WeakMap", value: WeakMap },
89
+ { key: "WeakSet", value: WeakSet },
90
+ ];
91
+ function assertCommonJsAnalysisPrimitives() {
92
+ let changed = false;
93
+ for (let index = 0; index < COMMON_JS_ANALYSIS_GLOBALS.length; index++) {
94
+ const snapshot = COMMON_JS_ANALYSIS_GLOBALS[index];
95
+ if (getOwnPropertyDescriptor(dntShim.dntGlobalThis, snapshot.key)?.value !== snapshot.value) {
96
+ changed = true;
97
+ break;
98
+ }
99
+ }
100
+ for (let ownerIndex = 0; !changed && ownerIndex < COMMON_JS_ANALYSIS_PRIMITIVES.length; ownerIndex++) {
101
+ const snapshot = COMMON_JS_ANALYSIS_PRIMITIVES[ownerIndex];
102
+ for (let entryIndex = 0; entryIndex < snapshot.entries.length; entryIndex++) {
103
+ const entry = snapshot.entries[entryIndex];
104
+ if (getOwnPropertyDescriptor(snapshot.owner, entry.key)?.value !== entry.value) {
105
+ changed = true;
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ if (changed) {
111
+ throw BUNDLE_ERROR.create({
112
+ message: "CommonJS analysis integrity check failed",
113
+ detail: "Required runtime primitives changed after parser initialization",
114
+ context: { capability: "findStaticCommonJsImports" },
115
+ });
116
+ }
117
+ }
31
118
  const FUNCTION_NODE_TYPES = [
32
119
  "ArrowFunctionExpression",
33
120
  "ClassMethod",
@@ -37,15 +124,238 @@ const FUNCTION_NODE_TYPES = [
37
124
  "ObjectMethod",
38
125
  ];
39
126
  function isRecord(value) {
40
- return typeof value === "object" && value !== null && !Array.isArray(value);
127
+ return typeof value === "object" && value !== null && !ArrayIsArray(value);
41
128
  }
42
129
  function functionHasDirective(node, directive) {
43
130
  const body = node.body;
44
131
  if (!isRecord(body) || body.type !== "BlockStatement" ||
45
- !Array.isArray(body.directives)) {
132
+ !ArrayIsArray(body.directives)) {
133
+ return false;
134
+ }
135
+ return arraySome(body.directives, (entry) => isRecord(entry) && isRecord(entry.value) && entry.value.value === directive);
136
+ }
137
+ function astNode(value) {
138
+ return isRecord(value) && typeof value.type === "string" ? value : undefined;
139
+ }
140
+ function unwrapErasedExpression(node) {
141
+ while (node?.type === "ParenthesizedExpression" || node?.type === "TSAsExpression" ||
142
+ node?.type === "TSInstantiationExpression" || node?.type === "TSNonNullExpression" ||
143
+ node?.type === "TSSatisfiesExpression" || node?.type === "TSTypeAssertion") {
144
+ node = astNode(node.expression);
145
+ }
146
+ return node;
147
+ }
148
+ function staticStringValue(node, depth = 0) {
149
+ if (depth > MAX_STATIC_STRING_DEPTH)
150
+ return undefined;
151
+ node = unwrapErasedExpression(node);
152
+ if (node?.type === "StringLiteral" && typeof node.value === "string") {
153
+ return node.value.length <= MAX_STATIC_STRING_LENGTH ? node.value : undefined;
154
+ }
155
+ if (node?.type === "BinaryExpression" && node.operator === "+") {
156
+ const left = staticStringValue(astNode(node.left), depth + 1);
157
+ const right = staticStringValue(astNode(node.right), depth + 1);
158
+ if (left === undefined || right === undefined)
159
+ return undefined;
160
+ return left.length + right.length <= MAX_STATIC_STRING_LENGTH ? left + right : undefined;
161
+ }
162
+ if (node?.type !== "TemplateLiteral" || !ArrayIsArray(node.expressions) ||
163
+ !ArrayIsArray(node.quasis) || node.quasis.length !== node.expressions.length + 1 ||
164
+ node.quasis.length > MAX_STATIC_STRING_PARTS) {
165
+ return undefined;
166
+ }
167
+ let value = "";
168
+ for (let index = 0; index < node.quasis.length; index++) {
169
+ const quasi = astNode(node.quasis[index]);
170
+ if (!isRecord(quasi?.value) || typeof quasi.value.cooked !== "string")
171
+ return undefined;
172
+ value += quasi.value.cooked;
173
+ if (value.length > MAX_STATIC_STRING_LENGTH)
174
+ return undefined;
175
+ if (index >= node.expressions.length)
176
+ continue;
177
+ const expression = staticStringValue(astNode(node.expressions[index]), depth + 1);
178
+ if (expression === undefined || value.length + expression.length > MAX_STATIC_STRING_LENGTH) {
179
+ return undefined;
180
+ }
181
+ value += expression;
182
+ }
183
+ return value;
184
+ }
185
+ function memberPropertyName(member) {
186
+ const property = unwrapErasedExpression(astNode(member.property));
187
+ return member.computed === true
188
+ ? staticStringValue(property)
189
+ : property?.type === "Identifier" && typeof property.name === "string"
190
+ ? property.name
191
+ : undefined;
192
+ }
193
+ function commonJsRequireBinding(callee) {
194
+ callee = unwrapErasedExpression(callee);
195
+ if (callee?.type === "Identifier" && callee.name === "require")
196
+ return "require";
197
+ if (callee?.type === "SequenceExpression") {
198
+ if (!ArrayIsArray(callee.expressions) || callee.expressions.length === 0)
199
+ return undefined;
200
+ return commonJsRequireBinding(astNode(callee.expressions[callee.expressions.length - 1]));
201
+ }
202
+ return undefined;
203
+ }
204
+ function commonJsModuleObjectBinding(value) {
205
+ value = unwrapErasedExpression(value);
206
+ if (value?.type === "Identifier" && value.name === "module")
207
+ return "module";
208
+ if (value?.type === "SequenceExpression") {
209
+ if (!ArrayIsArray(value.expressions) || value.expressions.length === 0)
210
+ return undefined;
211
+ return commonJsModuleObjectBinding(astNode(value.expressions[value.expressions.length - 1]));
212
+ }
213
+ if (value?.type !== "MemberExpression" && value?.type !== "OptionalMemberExpression") {
214
+ return undefined;
215
+ }
216
+ return memberPropertyName(value) === "parent"
217
+ ? commonJsModuleObjectBinding(astNode(value.object))
218
+ : undefined;
219
+ }
220
+ function commonJsRequireMainBinding(value) {
221
+ value = unwrapErasedExpression(value);
222
+ if (value?.type !== "MemberExpression" && value?.type !== "OptionalMemberExpression") {
223
+ return undefined;
224
+ }
225
+ return memberPropertyName(value) === "main"
226
+ ? commonJsRequireBinding(astNode(value.object))
227
+ : undefined;
228
+ }
229
+ function commonJsCallableBinding(callee) {
230
+ callee = unwrapErasedExpression(callee);
231
+ const requireBinding = commonJsRequireBinding(callee);
232
+ if (requireBinding !== undefined)
233
+ return requireBinding;
234
+ if (callee?.type === "SequenceExpression") {
235
+ if (!ArrayIsArray(callee.expressions) || callee.expressions.length === 0)
236
+ return undefined;
237
+ return commonJsCallableBinding(astNode(callee.expressions[callee.expressions.length - 1]));
238
+ }
239
+ if (callee?.type !== "MemberExpression" && callee?.type !== "OptionalMemberExpression") {
240
+ return undefined;
241
+ }
242
+ const object = unwrapErasedExpression(astNode(callee.object));
243
+ const propertyName = memberPropertyName(callee);
244
+ if (propertyName === "resolve") {
245
+ return commonJsRequireBinding(object);
246
+ }
247
+ if (propertyName !== "require")
248
+ return undefined;
249
+ return commonJsModuleObjectBinding(object) ?? commonJsRequireMainBinding(object);
250
+ }
251
+ function callArguments(call) {
252
+ return ArrayIsArray(call.arguments) ? call.arguments : undefined;
253
+ }
254
+ function commonJsCallTarget(call) {
255
+ const args = callArguments(call);
256
+ const callee = unwrapErasedExpression(astNode(call.callee));
257
+ if (callee?.type === "CallExpression" || callee?.type === "OptionalCallExpression") {
258
+ const boundCallee = unwrapErasedExpression(astNode(callee.callee));
259
+ if (boundCallee?.type === "MemberExpression" ||
260
+ boundCallee?.type === "OptionalMemberExpression") {
261
+ if (memberPropertyName(boundCallee) === "bind") {
262
+ const binding = commonJsCallableBinding(astNode(boundCallee.object));
263
+ const boundArgs = callArguments(callee);
264
+ const specifier = boundArgs !== undefined && boundArgs.length >= 2
265
+ ? astNode(boundArgs[1])
266
+ : astNode(args?.[0]);
267
+ return binding === undefined ? undefined : { binding, specifier };
268
+ }
269
+ }
270
+ }
271
+ if (callee?.type === "MemberExpression" || callee?.type === "OptionalMemberExpression") {
272
+ const method = memberPropertyName(callee);
273
+ if (method === "call") {
274
+ const binding = commonJsCallableBinding(astNode(callee.object));
275
+ return binding === undefined ? undefined : { binding, specifier: astNode(args?.[1]) };
276
+ }
277
+ if (method === "apply") {
278
+ const binding = commonJsCallableBinding(astNode(callee.object));
279
+ const applied = unwrapErasedExpression(astNode(args?.[1]));
280
+ const elements = applied?.type === "ArrayExpression" && ArrayIsArray(applied.elements)
281
+ ? applied.elements
282
+ : undefined;
283
+ return binding === undefined ? undefined : { binding, specifier: astNode(elements?.[0]) };
284
+ }
285
+ }
286
+ const binding = commonJsCallableBinding(callee);
287
+ return binding === undefined ? undefined : { binding, specifier: astNode(args?.[0]) };
288
+ }
289
+ function isErasedTypeScriptBinding(path) {
290
+ for (let current = path; current; current = current.parentPath) {
291
+ if (current.node.declare === true)
292
+ return true;
293
+ if ((current.node.type === "ImportDeclaration" || current.node.type === "ImportSpecifier" ||
294
+ current.node.type === "TSImportEqualsDeclaration") &&
295
+ current.node.importKind === "type") {
296
+ return true;
297
+ }
298
+ }
299
+ return false;
300
+ }
301
+ function namespaceMemberEmitsRuntime(value) {
302
+ const node = astNode(value);
303
+ if (!node)
46
304
  return false;
305
+ if (node.type === "ExportNamedDeclaration") {
306
+ const declaration = astNode(node.declaration);
307
+ if (declaration !== undefined)
308
+ return namespaceMemberEmitsRuntime(declaration);
309
+ if (node.exportKind === "type")
310
+ return false;
311
+ return ArrayIsArray(node.specifiers) &&
312
+ arraySome(node.specifiers, (specifier) => astNode(specifier)?.exportKind !== "type");
313
+ }
314
+ if (node.type === "TSModuleDeclaration") {
315
+ if (node.declare === true)
316
+ return false;
317
+ const body = astNode(node.body);
318
+ return body?.type === "TSModuleBlock" && ArrayIsArray(body.body) &&
319
+ arraySome(body.body, namespaceMemberEmitsRuntime);
47
320
  }
48
- return body.directives.some((entry) => isRecord(entry) && isRecord(entry.value) && entry.value.value === directive);
321
+ if (node.type === "TSInterfaceDeclaration" || node.type === "TSTypeAliasDeclaration" ||
322
+ node.type === "TSNamespaceExportDeclaration" || node.type === "EmptyStatement") {
323
+ return false;
324
+ }
325
+ if ((node.type === "ImportDeclaration" || node.type === "TSImportEqualsDeclaration") &&
326
+ node.importKind === "type") {
327
+ return false;
328
+ }
329
+ return true;
330
+ }
331
+ function bodyHasRuntimeNamespaceBinding(body, name) {
332
+ if (!ArrayIsArray(body))
333
+ return false;
334
+ return arraySome(body, (entry) => {
335
+ let declaration = astNode(entry);
336
+ if (declaration?.type === "ExportNamedDeclaration") {
337
+ declaration = astNode(declaration.declaration);
338
+ }
339
+ if (declaration?.type !== "TSModuleDeclaration" || declaration.declare === true)
340
+ return false;
341
+ const identifier = astNode(declaration.id);
342
+ return identifier?.type === "Identifier" && identifier.name === name &&
343
+ namespaceMemberEmitsRuntime(declaration);
344
+ });
345
+ }
346
+ function hasRuntimeNamespaceBinding(path, name) {
347
+ for (let current = path; current; current = current.parentPath) {
348
+ if ((current.node.type === "Program" || current.node.type === "TSModuleBlock") &&
349
+ bodyHasRuntimeNamespaceBinding(current.node.body, name)) {
350
+ return true;
351
+ }
352
+ }
353
+ return false;
354
+ }
355
+ function hasRuntimeBinding(path, name) {
356
+ const binding = path.scope?.getBinding(name);
357
+ return (binding !== undefined && !isErasedTypeScriptBinding(binding.path)) ||
358
+ hasRuntimeNamespaceBinding(path, name);
49
359
  }
50
360
  class BabelCodeParser extends BabelParseOnlyParser {
51
361
  traverse(ast, visitor) {
@@ -75,6 +385,30 @@ class BabelCodeParser extends BabelParseOnlyParser {
75
385
  this.traverse(ast, visitor);
76
386
  return found;
77
387
  }
388
+ async findStaticCommonJsImports(options) {
389
+ assertCommonJsAnalysisPrimitives();
390
+ const ast = await this.parse({
391
+ ...options,
392
+ allowReturnOutsideFunction: true,
393
+ });
394
+ assertCommonJsAnalysisPrimitives();
395
+ const imports = [];
396
+ const visit = (path) => {
397
+ const target = commonJsCallTarget(path.node);
398
+ if (!target || hasRuntimeBinding(path, target.binding))
399
+ return;
400
+ const specifier = staticStringValue(target.specifier);
401
+ if (specifier !== undefined)
402
+ arrayPush(imports, specifier);
403
+ };
404
+ traverse(ast, {
405
+ CallExpression: visit,
406
+ NewExpression: visit,
407
+ OptionalCallExpression: visit,
408
+ });
409
+ assertCommonJsAnalysisPrimitives();
410
+ return imports;
411
+ }
78
412
  injectJsxNodePositions(source, options) {
79
413
  return injectNodePositions(source, options);
80
414
  }
@@ -1 +1 @@
1
- {"version":3,"file":"parser-only.d.ts","sourceRoot":"","sources":["../src/parser-only.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEzE,wEAAwE;AACxE,MAAM,WAAW,4BAA4B;IAC3C,sEAAsE;IACtE,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AA0BD;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,4BAA4B;IACvE,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;CAQ/C"}
1
+ {"version":3,"file":"parser-only.d.ts","sourceRoot":"","sources":["../src/parser-only.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEzE,wEAAwE;AACxE,MAAM,WAAW,4BAA4B;IAC3C,sEAAsE;IACtE,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AA0BD;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,4BAA4B;IACvE,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;CAW/C"}
@@ -39,11 +39,14 @@ function pickPlugins(filePath) {
39
39
  */
40
40
  export class BabelParseOnlyParser {
41
41
  parse(options) {
42
+ const filePath = options.filePath?.toLowerCase() ?? "";
42
43
  const ast = parser.parse(options.code, {
43
44
  sourceType: "unambiguous",
44
- allowReturnOutsideFunction: options.filePath?.toLowerCase().endsWith(".cjs") === true,
45
+ allowReturnOutsideFunction: options.allowReturnOutsideFunction === true ||
46
+ /\.(?:cjs|js)$/.test(filePath),
45
47
  plugins: pickPlugins(options.filePath),
46
48
  });
47
- return Promise.resolve(ast);
49
+ const node = ast;
50
+ return Promise.resolve(node);
48
51
  }
49
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veryfront/ext-parser-babel",
3
- "version": "0.1.1238",
3
+ "version": "0.1.1240",
4
4
  "description": "Veryfront first-party extension package for ext-parser-babel",
5
5
  "keywords": [
6
6
  "veryfront",
@@ -46,13 +46,16 @@
46
46
  "capabilities": []
47
47
  },
48
48
  "dependencies": {
49
+ "@deno/shim-deno": "~0.18.0",
50
+ "@deno/shim-crypto": "~0.3.1",
51
+ "@deno/shim-timers": "~0.1.0",
49
52
  "@babel/generator": "7.29.1",
50
53
  "@babel/parser": "7.29.2",
51
54
  "@babel/traverse": "7.29.0",
52
55
  "@babel/types": "7.29.0"
53
56
  },
54
57
  "peerDependencies": {
55
- "veryfront": "^0.1.1238"
58
+ "veryfront": "^0.1.1240"
56
59
  },
57
60
  "type": "module",
58
61
  "types": "./esm/index.d.ts",