-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatically annotate file paths if dynamicPaths include JS modules …
…or is a function
- Loading branch information
Showing
7 changed files
with
61 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,25 @@ | ||
import {readConfig} from "../config.js"; | ||
import {isPathImport} from "../path.js"; | ||
|
||
const annotate = process.env["OBSERVABLE_ANNOTATE_FILES"]; | ||
if (annotate && annotate !== "true") throw new Error(`unsupported OBSERVABLE_ANNOTATE_FILES: ${annotate}`); | ||
const unnormalizedConfig = await readConfig(undefined, undefined, false); | ||
const configShouldAnnotate = Array.isArray(unnormalizedConfig.dynamicPaths) | ||
? unnormalizedConfig.dynamicPaths.some((path) => path.endsWith(".js")) | ||
: typeof unnormalizedConfig.dynamicPaths === "function"; | ||
|
||
/** Annotate a path to a local import or file so it can be reworked server-side. */ | ||
export const annotatePath = annotate | ||
? (uri: string) => `${JSON.stringify(uri)}${isPathImport(uri) ? "/* observablehq-file */" : ""}` | ||
: JSON.stringify; | ||
export function annotatePath(uri: string) { | ||
const envShouldAnnotate = | ||
process.env["OBSERVABLE_ANNOTATE_FILES"] === "true" | ||
? true | ||
: process.env["OBSERVABLE_ANNOTATE_FILES"] === "false" | ||
? false | ||
: process.env["OBSERVABLE_ANNOTATE_FILES"]; | ||
if (envShouldAnnotate !== true && envShouldAnnotate !== false && envShouldAnnotate !== undefined) { | ||
throw new Error(`unsupported OBSERVABLE_ANNOTATE_FILES: ${envShouldAnnotate}`); | ||
} | ||
|
||
const shouldAnnotate = envShouldAnnotate ?? configShouldAnnotate; | ||
return shouldAnnotate | ||
? `${JSON.stringify(uri)}${isPathImport(uri) ? "/* observablehq-file */" : ""}` | ||
: JSON.stringify(uri); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 12 additions & 1 deletion
13
test/javascript/annotate.ts → test/javascript/annotate-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,10 +4,12 @@ import {join} from "node:path/posix"; | |
import {extractNpmSpecifier, initializeNpmVersionCache, parseNpmSpecifier} from "../src/npm.js"; | ||
import {fromJsDelivrPath, getDependencyResolver, resolveNpmImport, rewriteNpmImports} from "../src/npm.js"; | ||
import {relativePath} from "../src/path.js"; | ||
import {mockAnnotateFileEnv} from "./javascript/annotate-test.js"; | ||
import {mockJsDelivr} from "./mocks/jsdelivr.js"; | ||
|
||
describe("getDependencyResolver(root, path, input)", () => { | ||
mockJsDelivr(); | ||
mockAnnotateFileEnv(false); | ||
it("finds /npm/ imports and re-resolves their versions", async () => { | ||
const root = "test/input/build/simple-public"; | ||
const specifier = "/npm/[email protected]/dist/d3-array.js"; | ||
|
@@ -23,6 +25,7 @@ describe("getDependencyResolver(root, path, input)", () => { | |
}); | ||
|
||
describe("parseNpmSpecifier(specifier)", () => { | ||
mockAnnotateFileEnv(false); | ||
it("parses the name", () => { | ||
assert.deepStrictEqual(parseNpmSpecifier("d3-array"), {name: "d3-array", range: undefined, path: undefined}); | ||
}); | ||
|
@@ -50,6 +53,7 @@ describe("parseNpmSpecifier(specifier)", () => { | |
|
||
describe("resolveNpmImport(root, specifier)", () => { | ||
mockJsDelivr(); | ||
mockAnnotateFileEnv(false); | ||
const root = "test/input/build/simple"; | ||
it("implicitly adds ._esm.js for specifiers without an extension", async () => { | ||
assert.strictEqual(await resolveNpmImport(root, "d3-array"), "/_npm/[email protected]/_esm.js"); | ||
|
@@ -75,6 +79,7 @@ describe("resolveNpmImport(root, specifier)", () => { | |
}); | ||
|
||
describe("extractNpmSpecifier(path)", () => { | ||
mockAnnotateFileEnv(false); | ||
it("returns the npm specifier for the given local npm path", () => { | ||
assert.strictEqual(extractNpmSpecifier("/_npm/[email protected]/_esm.js"), "[email protected]/+esm"); | ||
assert.strictEqual(extractNpmSpecifier("/_npm/[email protected]/dist/d3.js"), "[email protected]/dist/d3.js"); | ||
|
@@ -89,6 +94,7 @@ describe("extractNpmSpecifier(path)", () => { | |
}); | ||
|
||
describe("fromJsDelivrPath(path)", () => { | ||
mockAnnotateFileEnv(false); | ||
it("returns the local npm path for the given jsDelivr path", () => { | ||
assert.strictEqual(fromJsDelivrPath("/npm/[email protected]/+esm"), "/_npm/[email protected]/_esm.js"); | ||
assert.strictEqual(fromJsDelivrPath("/npm/[email protected]/dist/d3.js"), "/_npm/[email protected]/dist/d3.js"); | ||
|
@@ -102,6 +108,7 @@ describe("fromJsDelivrPath(path)", () => { | |
|
||
// prettier-ignore | ||
describe("rewriteNpmImports(input, resolve)", () => { | ||
mockAnnotateFileEnv(false); | ||
it("rewrites /npm/ imports to /_npm/", () => { | ||
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/dist/d3.js", v)), 'export * from "../../[email protected]/dist/d3-array.js";\n'); | ||
}); | ||
|
@@ -148,6 +155,7 @@ describe("rewriteNpmImports(input, resolve)", () => { | |
}); | ||
|
||
describe("initializeNpmVersionCache(root, dir)", () => { | ||
mockAnnotateFileEnv(false); | ||
const root = join("test", "input", "npm"); | ||
const dir = join(root, ".observablehq", "cache", "_npm"); | ||
before(async () => { | ||
|