Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/mod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ Deno.test("should resolve, load and get graph", async () => {
nodeConditions: undefined, // ensure doesn't error
});
const modFileUrl = import.meta.resolve("./mod.ts");
const loader = await workspace.createLoader({
const { loader, diagnostics } = await workspace.createLoader({
entrypoints: [modFileUrl],
});
assertEquals(diagnostics.length, 0);
const graph = loader.getGraphUnstable();
assertEquals((graph as any).roots[0], modFileUrl);
const resolvedUrl = loader.resolve(
Expand Down Expand Up @@ -51,9 +52,10 @@ Deno.test("should resolve, load and get graph", async () => {
Deno.test("resolving a jsr specifier should fail with explanatory message", async () => {
const workspace = new Workspace({});
const modFileUrl = import.meta.resolve("./mod.ts");
const loader = await workspace.createLoader({
const { loader, diagnostics } = await workspace.createLoader({
entrypoints: [modFileUrl],
});
assertEquals(diagnostics.length, 0);
assertRejects(
async () => {
await loader.load(
Expand Down
24 changes: 18 additions & 6 deletions src/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
* const workspace = new Workspace({
* // optional options
* });
* const loader = await workspace.createLoader({
* const { loader, diagnostics } = await workspace.createLoader({
* entrypoints: ["./mod.ts"]
* });
* if (diagnostics.length > 0) {
* throw new Error(diagnostics[0].message);
* }
* const resolvedUrl = loader.resolve(
* "./mod.test.ts",
* "https://deno.land/mod.ts", // referrer
Expand Down Expand Up @@ -146,7 +149,9 @@ export class Workspace implements Disposable {
}

/** Creates a loader that uses this this workspace. */
async createLoader(options: LoaderOptions): Promise<Loader> {
async createLoader(
options: LoaderOptions,
): Promise<{ loader: Loader; diagnostics: EntrypointDiagnostic[] }> {
if (this.#debug) {
console.error(
`Creating loader for entrypoints:\n ${
Expand All @@ -156,8 +161,8 @@ export class Workspace implements Disposable {
}
const wasmLoader = await this.#inner.create_loader();
const loader = new Loader(wasmLoader, this.#debug);
await loader.addEntrypoints(options.entrypoints);
return loader;
const diagnostics = await loader.addEntrypoints(options.entrypoints);
return { loader, diagnostics };
}
}

Expand All @@ -168,6 +173,10 @@ export enum RequestedModuleType {
Bytes = 3,
}

export interface EntrypointDiagnostic {
message: string;
}

/** A loader for resolving and loading urls. */
export class Loader implements Disposable {
#inner: WasmLoader;
Expand All @@ -192,8 +201,11 @@ export class Loader implements Disposable {
* stored in the internal module graph on the fly, which will allow
* it to be synchronously resolved.
*/
addEntrypoints(entrypoints: string[]): Promise<void> {
return this.#inner.add_entrypoints(entrypoints);
async addEntrypoints(
entrypoints: string[],
): Promise<EntrypointDiagnostic[]> {
const messages = await this.#inner.add_entrypoints(entrypoints);
return messages.map((message) => ({ message }));
}

/** Resolves a specifier using the given referrer and resolution mode. */
Expand Down
26 changes: 21 additions & 5 deletions src/rs_lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ use deno_ast::ModuleKind;
use deno_cache_dir::file_fetcher::CacheSetting;
use deno_cache_dir::file_fetcher::NullBlobStore;
use deno_error::JsErrorBox;
use deno_graph::CheckJsOption;
use deno_graph::GraphKind;
use deno_graph::MediaType;
use deno_graph::ModuleGraph;
use deno_graph::Position;
use deno_graph::WalkOptions;
use deno_graph::analysis::ModuleAnalyzer;
use deno_graph::ast::CapturingEsParser;
use deno_graph::ast::DefaultEsParser;
Expand Down Expand Up @@ -336,7 +339,7 @@ impl DenoLoader {
pub async fn add_entrypoints(
&mut self,
entrypoints: Vec<String>,
) -> Result<(), JsValue> {
) -> Result<Vec<String>, JsValue> {
// only allow one async task to modify the graph at a time
let task_queue = self.task_queue.clone();
task_queue
Expand All @@ -352,7 +355,7 @@ impl DenoLoader {
async fn add_entrypoints_internal(
&mut self,
entrypoints: Vec<String>,
) -> Result<(), anyhow::Error> {
) -> Result<Vec<String>, anyhow::Error> {
let roots = entrypoints
.into_iter()
.map(|e| self.resolve_entrypoint(e))
Expand Down Expand Up @@ -393,7 +396,7 @@ impl DenoLoader {
self
.graph
.build(
roots,
roots.clone(),
Vec::new(),
&loader,
deno_graph::BuildOptions {
Expand All @@ -414,8 +417,21 @@ impl DenoLoader {
},
)
.await;
self.graph.valid()?;
Ok(())
let errors = self
.graph
.walk(
roots.iter(),
WalkOptions {
check_js: CheckJsOption::True,
kind: GraphKind::CodeOnly,
follow_dynamic: false,
prefer_fast_check_graph: false,
},
)
.errors()
.map(|e| e.to_string_with_range())
.collect();
Ok(errors)
}

pub fn resolve(
Expand Down
18 changes: 17 additions & 1 deletion tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,28 @@ export * from "@deno/loader";
export async function createLoader(
workspaceOptions: WorkspaceOptions,
loaderOptions: LoaderOptions,
) {
const { loader, workspace, diagnostics } = await createLoaderWithDiagnostics(
workspaceOptions,
loaderOptions,
);
assertEquals(diagnostics, []);
return {
loader,
workspace,
};
}

export async function createLoaderWithDiagnostics(
workspaceOptions: WorkspaceOptions,
loaderOptions: LoaderOptions,
) {
const workspace = new Workspace(workspaceOptions);
const loader = await workspace.createLoader(loaderOptions);
const { loader, diagnostics } = await workspace.createLoader(loaderOptions);
return {
loader,
workspace,
diagnostics,
};
}

Expand Down
19 changes: 19 additions & 0 deletions tests/invalid_graph/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { assertEquals } from "@std/assert";
import { createLoaderWithDiagnostics } from "../helpers.ts";

Deno.test("loads linked entrypoint", async () => {
const mainFile = import.meta.dirname + "/testdata/main.ts";
const { diagnostics } = await createLoaderWithDiagnostics({
configPath: import.meta.dirname + "/testdata/deno.json",
}, {
entrypoints: [mainFile],
});

assertEquals(diagnostics.length, 1);
const expectedMessage =
'Relative import path "unknown" not prefixed with / or ./ or ../';
assertEquals(
diagnostics[0].message.substring(0, expectedMessage.length),
expectedMessage,
);
});
2 changes: 2 additions & 0 deletions tests/invalid_graph/testdata/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 1 addition & 0 deletions tests/invalid_graph/testdata/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "unknown";
8 changes: 5 additions & 3 deletions tests/jsx/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ResolutionMode,
type WorkspaceOptions,
} from "../helpers.ts";
import { assert } from "@std/assert";
import { assert, assertEquals } from "@std/assert";

Deno.test("loads jsx transpiled", async () => {
const mainJsx = import.meta.dirname + "/testdata/main.jsx";
Expand Down Expand Up @@ -47,9 +47,10 @@ ${mainJsxSourceMappingURL}`,

{
const { workspace } = await createWorkspace({ preserveJsx: true });
const newLoader = await workspace.createLoader({
const { loader: newLoader, diagnostics } = await workspace.createLoader({
entrypoints: [mainJsx, mainTsxUrl],
});
assertEquals(diagnostics, []);
assertResponseText(
await newLoader.load(mainJsxUrl, RequestedModuleType.Default),
"console.log(<div />);\n",
Expand All @@ -61,9 +62,10 @@ ${mainJsxSourceMappingURL}`,
}
{
const { workspace } = await createWorkspace({ noTranspile: true });
const newLoader = await workspace.createLoader({
const { loader: newLoader, diagnostics } = await workspace.createLoader({
entrypoints: [mainJsx, mainTsx],
});
assertEquals(diagnostics, []);
assertResponseText(
await newLoader.load(mainJsxUrl, RequestedModuleType.Default),
`console.log(<div />);\n`,
Expand Down