Skip to content

Commit 02911fb

Browse files
committed
fix #126; disallow top-level export
1 parent e0ac8d0 commit 02911fb

File tree

4 files changed

+23
-5
lines changed

4 files changed

+23
-5
lines changed

src/javascript.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import {findDeclarations} from "./javascript/declarations.js";
55
import {findFeatures} from "./javascript/features.js";
66
import {rewriteFetches} from "./javascript/fetches.js";
77
import {defaultGlobals} from "./javascript/globals.js";
8-
import {findImports, rewriteImports} from "./javascript/imports.js";
8+
import {findExports, findImports, rewriteImports} from "./javascript/imports.js";
99
import {findReferences} from "./javascript/references.js";
10+
import {syntaxError} from "./javascript/syntaxError.js";
1011
import {Sourcemap} from "./sourcemap.js";
1112

1213
export interface DatabaseReference {
@@ -131,6 +132,8 @@ function parseJavaScript(input: string, options: ParseOptions): JavaScriptNode {
131132
if (expression?.type === "FunctionExpression" && expression.id) expression = null; // treat named function as program
132133
if (!expression && inline) throw new SyntaxError("invalid expression");
133134
const body = expression ?? (Parser.parse(input, parseOptions) as any);
135+
const exports = findExports(body);
136+
if (exports.length) throw syntaxError("Unexpected token 'export'", exports[0], input); // disallow exports
134137
const references = findReferences(body, globals, input);
135138
const declarations = expression ? null : findDeclarations(body, globals, input);
136139
const imports = findImports(body, root, sourcePath);

src/javascript/imports.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
import {readFileSync} from "node:fs";
22
import {dirname, join, normalize} from "node:path";
3-
import {type Node, Parser} from "acorn";
3+
import {type ExportAllDeclaration, type ExportNamedDeclaration, type Node, Parser} from "acorn";
44
import {simple} from "acorn-walk";
55
import {type ImportReference, type JavaScriptNode, parseOptions} from "../javascript.js";
66
import {getStringLiteralValue, isStringLiteral} from "./features.js";
77

8+
export function findExports(body: Node) {
9+
const exports: (ExportAllDeclaration | ExportNamedDeclaration)[] = [];
10+
11+
simple(body, {
12+
ExportAllDeclaration: findExport,
13+
ExportNamedDeclaration: findExport
14+
});
15+
16+
function findExport(node: ExportAllDeclaration | ExportNamedDeclaration) {
17+
exports.push(node);
18+
}
19+
20+
return exports;
21+
}
22+
823
export function findImports(body: Node, root: string, sourcePath: string) {
924
const imports: ImportReference[] = [];
1025
const paths = new Set<string>();
1126

1227
simple(body, {
1328
ImportDeclaration: findImport,
14-
ImportExpression: findImport,
15-
ExportAllDeclaration: findImport,
16-
ExportNamedDeclaration: findImport
29+
ImportExpression: findImport
1730
});
1831

1932
function findImport(node) {

test/input/export.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const foo = 42;

test/output/export.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
define({id: "0", body: () => { throw new SyntaxError("Unexpected token 'export' (1:0)"); }});

0 commit comments

Comments
 (0)