diff --git a/src/build.ts b/src/build.ts index 88aab3d9c..7e8abaaf2 100644 --- a/src/build.ts +++ b/src/build.ts @@ -72,8 +72,9 @@ export async function build({sourceRoot, outputRoot, verbose = true, addPublic = // Copy over the referenced files. for (const file of files) { + const outputPath = join(outputRoot, file); + if (existsSync(outputPath) || existsSync(outputPath + ".html")) continue; // skip pages let sourcePath = join(sourceRoot, file); - const outputPath = join(outputRoot, "_file", file); if (!existsSync(sourcePath)) { const loader = Loader.find(sourceRoot, file); if (!loader) { diff --git a/src/files.ts b/src/files.ts index 4ffa4f1a2..7462012a8 100644 --- a/src/files.ts +++ b/src/files.ts @@ -19,7 +19,7 @@ export function fileReference(name: string, sourcePath: string): FileReference { return { name, mimeType: mime.getType(name), - path: relativeUrl(sourcePath, resolvePath("_file", sourcePath, name)) + path: relativeUrl(sourcePath, resolvePath(sourcePath, name)) }; } diff --git a/src/javascript.ts b/src/javascript.ts index ce1dd0aba..afc12acac 100644 --- a/src/javascript.ts +++ b/src/javascript.ts @@ -18,7 +18,7 @@ export interface DatabaseReference { export interface FileReference { name: string; mimeType: string | null; - /** The relative path from the document to the file in _file */ + /** The relative path from the document to the file */ path: string; } diff --git a/src/javascript/fetches.ts b/src/javascript/fetches.ts index 0ef90f8b2..57819b285 100644 --- a/src/javascript/fetches.ts +++ b/src/javascript/fetches.ts @@ -10,8 +10,8 @@ export function rewriteFetches(output: Sourcemap, rootNode: JavaScriptNode, sour if (isLocalFetch(node, rootNode.references, sourcePath)) { const arg = node.arguments[0]; const value = getStringLiteralValue(arg); - const path = resolvePath("_file", sourcePath, value); - output.replaceLeft(arg.start, arg.end, JSON.stringify(relativeUrl(sourcePath, path))); + const path = relativeUrl(sourcePath, resolvePath(sourcePath, value)); + output.replaceLeft(arg.start, arg.end, JSON.stringify(path)); } } }); diff --git a/src/markdown.ts b/src/markdown.ts index 49b10f288..028b0c731 100644 --- a/src/markdown.ts +++ b/src/markdown.ts @@ -323,6 +323,7 @@ function renderIntoPieces(renderer: Renderer, root: string, sourcePath: string): } const SUPPORTED_PROPERTIES: readonly {query: string; src: "href" | "src" | "srcset"}[] = Object.freeze([ + {query: "a[href]", src: "href"}, {query: "audio[src]", src: "src"}, {query: "audio source[src]", src: "src"}, {query: "img[src]", src: "src"}, diff --git a/src/preview.ts b/src/preview.ts index 1eac5835b..324abe7e2 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -95,28 +95,6 @@ export class PreviewServer { throw new HttpError("Not found", 404); } end(req, res, rewriteModule(js, file, createImportResolver(this.root)), "text/javascript"); - } else if (pathname.startsWith("/_file/")) { - const path = pathname.slice("/_file".length); - const filepath = join(this.root, path); - try { - await access(filepath, constants.R_OK); - send(req, pathname.slice("/_file".length), {root: this.root}).pipe(res); - return; - } catch (error) { - if (!isEnoent(error)) throw error; - } - - // Look for a data loader for this file. - const loader = Loader.find(this.root, path); - if (loader) { - try { - send(req, await loader.load(), {root: this.root}).pipe(res); - return; - } catch (error) { - if (!isEnoent(error)) throw error; - } - } - throw new HttpError("Not found", 404); } else { if ((pathname = normalize(pathname)).startsWith("..")) throw new Error("Invalid path: " + pathname); let path = join(this.root, pathname); @@ -134,6 +112,11 @@ export class PreviewServer { try { if ((await stat(path)).isDirectory() && (await stat(join(path, "index") + ".md")).isFile()) { await access(join(path, "index") + ".md", constants.R_OK); + if (!path.endsWith("/")) { + res.writeHead(302, {Location: pathname + "/" + url.search}); + res.end(); + return; + } pathname = join(pathname, "index"); path = join(path, "index"); } @@ -141,16 +124,7 @@ export class PreviewServer { if (!isEnoent(error)) throw error; // internal error } - // If this path ends with .html, then redirect to drop the .html. TODO: - // Check for the existence of the .md file first. - if (extname(path) === ".html") { - res.writeHead(302, {Location: join(dirname(pathname), basename(pathname, ".html")) + url.search}); - res.end(); - return; - } - - // Otherwise, serve the corresponding Markdown file, if it exists. - // Anything else should 404; static files should be matched above. + // Serve the corresponding Markdown file, if it exists. try { const config = await readConfig(this.root); const {html} = await renderPreview(await readFile(path + ".md", "utf-8"), { @@ -160,10 +134,47 @@ export class PreviewServer { ...config }); end(req, res, html, "text/html"); + return; } catch (error) { - if (!isEnoent(error)) throw error; // internal error - throw new HttpError("Not found", 404); + if (!isEnoent(error)) throw error; } + + // Handle a static file. + try { + if ((await stat(path)).isFile()) { + send(req, pathname, {root: this.root}).pipe(res); + return; + } + } catch (error) { + if (!isEnoent(error)) throw error; + } + + // If this path ends with .html and a .md file exists, redirect. + if (extname(path) === ".html") { + try { + if ((await stat(path.slice(0, -".html".length) + ".md")).isFile()) { + res.writeHead(302, {Location: join(dirname(pathname), basename(pathname, ".html")) + url.search}); + res.end(); + return; + } + } catch (error) { + if (!isEnoent(error)) throw error; + } + } + + // Look for a data loader for this file. + const loader = Loader.find(this.root, pathname); + if (loader) { + try { + send(req, await loader.load(), {root: this.root}).pipe(res); + return; + } catch (error) { + if (!isEnoent(error)) throw error; + } + } + + // Otherwise, 404. + throw new HttpError("Not found", 404); } } catch (error) { console.error(error); diff --git a/test/files-test.ts b/test/files-test.ts index 0ae3b7831..fe8116f47 100644 --- a/test/files-test.ts +++ b/test/files-test.ts @@ -35,6 +35,7 @@ describe("visitFiles(root)", () => { "custom-styles.css", "file-top.csv", "files.md", + "another/file-another.csv", "subsection/additional-styles.css", "subsection/file-sub.csv", "subsection/subfiles.md" diff --git a/test/input/build/files/another/file-another.csv b/test/input/build/files/another/file-another.csv new file mode 100644 index 000000000..e266c56c6 --- /dev/null +++ b/test/input/build/files/another/file-another.csv @@ -0,0 +1,2 @@ +Hola,mundo +1,2 diff --git a/test/input/build/files/subsection/subfiles.md b/test/input/build/files/subsection/subfiles.md index 6449283ee..f642a98c3 100644 --- a/test/input/build/files/subsection/subfiles.md +++ b/test/input/build/files/subsection/subfiles.md @@ -9,6 +9,10 @@ fetch("../file-top.csv") fetch("./file-sub.csv") ``` +```js +fetch("../another/file-another.csv") +``` + ```js FileAttachment("../file-top.csv") ``` diff --git a/test/output/build/archives/_file/dynamic-tar-gz/file.txt b/test/output/build/archives/dynamic-tar-gz/file.txt similarity index 100% rename from test/output/build/archives/_file/dynamic-tar-gz/file.txt rename to test/output/build/archives/dynamic-tar-gz/file.txt diff --git a/test/output/build/archives/_file/dynamic-tar/file.txt b/test/output/build/archives/dynamic-tar/file.txt similarity index 100% rename from test/output/build/archives/_file/dynamic-tar/file.txt rename to test/output/build/archives/dynamic-tar/file.txt diff --git a/test/output/build/archives/_file/dynamic/file.txt b/test/output/build/archives/dynamic/file.txt similarity index 100% rename from test/output/build/archives/_file/dynamic/file.txt rename to test/output/build/archives/dynamic/file.txt diff --git a/test/output/build/archives/_file/static-tar/file.txt b/test/output/build/archives/static-tar/file.txt similarity index 100% rename from test/output/build/archives/_file/static-tar/file.txt rename to test/output/build/archives/static-tar/file.txt diff --git a/test/output/build/archives/_file/static-tgz/file.txt b/test/output/build/archives/static-tgz/file.txt similarity index 100% rename from test/output/build/archives/_file/static-tgz/file.txt rename to test/output/build/archives/static-tgz/file.txt diff --git a/test/output/build/archives/_file/static/file.txt b/test/output/build/archives/static/file.txt similarity index 100% rename from test/output/build/archives/_file/static/file.txt rename to test/output/build/archives/static/file.txt diff --git a/test/output/build/archives/tar.html b/test/output/build/archives/tar.html index 161745cb9..24469e8ce 100644 --- a/test/output/build/archives/tar.html +++ b/test/output/build/archives/tar.html @@ -10,37 +10,37 @@ import {define} from "./_observablehq/client.js"; -define({id: "d5134368", inputs: ["FileAttachment","display"], files: [{"name":"static-tar/file.txt","mimeType":"text/plain","path":"./_file/static-tar/file.txt"}], body: async (FileAttachment,display) => { +define({id: "d5134368", inputs: ["FileAttachment","display"], files: [{"name":"static-tar/file.txt","mimeType":"text/plain","path":"./static-tar/file.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("static-tar/file.txt").text() )) }}); -define({id: "a0c06958", inputs: ["FileAttachment","display"], files: [{"name":"static-tgz/file.txt","mimeType":"text/plain","path":"./_file/static-tgz/file.txt"}], body: async (FileAttachment,display) => { +define({id: "a0c06958", inputs: ["FileAttachment","display"], files: [{"name":"static-tgz/file.txt","mimeType":"text/plain","path":"./static-tgz/file.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("static-tgz/file.txt").text() )) }}); -define({id: "d84cd7fb", inputs: ["FileAttachment","display"], files: [{"name":"static-tar/does-not-exist.txt","mimeType":"text/plain","path":"./_file/static-tar/does-not-exist.txt"}], body: async (FileAttachment,display) => { +define({id: "d84cd7fb", inputs: ["FileAttachment","display"], files: [{"name":"static-tar/does-not-exist.txt","mimeType":"text/plain","path":"./static-tar/does-not-exist.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("static-tar/does-not-exist.txt").text() )) }}); -define({id: "86bd51aa", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar/file.txt","mimeType":"text/plain","path":"./_file/dynamic-tar/file.txt"}], body: async (FileAttachment,display) => { +define({id: "86bd51aa", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar/file.txt","mimeType":"text/plain","path":"./dynamic-tar/file.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("dynamic-tar/file.txt").text() )) }}); -define({id: "95938c22", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar/does-not-exist.txt","mimeType":"text/plain","path":"./_file/dynamic-tar/does-not-exist.txt"}], body: async (FileAttachment,display) => { +define({id: "95938c22", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar/does-not-exist.txt","mimeType":"text/plain","path":"./dynamic-tar/does-not-exist.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("dynamic-tar/does-not-exist.txt").text() )) }}); -define({id: "7e5740fd", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar-gz/file.txt","mimeType":"text/plain","path":"./_file/dynamic-tar-gz/file.txt"}], body: async (FileAttachment,display) => { +define({id: "7e5740fd", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar-gz/file.txt","mimeType":"text/plain","path":"./dynamic-tar-gz/file.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("dynamic-tar-gz/file.txt").text() )) }}); -define({id: "d0a58efd", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar-gz/does-not-exist.txt","mimeType":"text/plain","path":"./_file/dynamic-tar-gz/does-not-exist.txt"}], body: async (FileAttachment,display) => { +define({id: "d0a58efd", inputs: ["FileAttachment","display"], files: [{"name":"dynamic-tar-gz/does-not-exist.txt","mimeType":"text/plain","path":"./dynamic-tar-gz/does-not-exist.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("dynamic-tar-gz/does-not-exist.txt").text() )) diff --git a/test/output/build/archives/zip.html b/test/output/build/archives/zip.html index e74a82b65..e2c7cceeb 100644 --- a/test/output/build/archives/zip.html +++ b/test/output/build/archives/zip.html @@ -10,22 +10,22 @@ import {define} from "./_observablehq/client.js"; -define({id: "d3b9d0ee", inputs: ["FileAttachment","display"], files: [{"name":"static/file.txt","mimeType":"text/plain","path":"./_file/static/file.txt"}], body: async (FileAttachment,display) => { +define({id: "d3b9d0ee", inputs: ["FileAttachment","display"], files: [{"name":"static/file.txt","mimeType":"text/plain","path":"./static/file.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("static/file.txt").text() )) }}); -define({id: "bab54217", inputs: ["FileAttachment","display"], files: [{"name":"static/not-found.txt","mimeType":"text/plain","path":"./_file/static/not-found.txt"}], body: async (FileAttachment,display) => { +define({id: "bab54217", inputs: ["FileAttachment","display"], files: [{"name":"static/not-found.txt","mimeType":"text/plain","path":"./static/not-found.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("static/not-found.txt").text() )) }}); -define({id: "11eec300", inputs: ["FileAttachment","display"], files: [{"name":"dynamic/file.txt","mimeType":"text/plain","path":"./_file/dynamic/file.txt"}], body: async (FileAttachment,display) => { +define({id: "11eec300", inputs: ["FileAttachment","display"], files: [{"name":"dynamic/file.txt","mimeType":"text/plain","path":"./dynamic/file.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("dynamic/file.txt").text() )) }}); -define({id: "ee2310f3", inputs: ["FileAttachment","display"], files: [{"name":"dynamic/not-found.txt","mimeType":"text/plain","path":"./_file/dynamic/not-found.txt"}], body: async (FileAttachment,display) => { +define({id: "ee2310f3", inputs: ["FileAttachment","display"], files: [{"name":"dynamic/not-found.txt","mimeType":"text/plain","path":"./dynamic/not-found.txt"}], body: async (FileAttachment,display) => { display(( await FileAttachment("dynamic/not-found.txt").text() )) diff --git a/test/output/build/files/another/file-another.csv b/test/output/build/files/another/file-another.csv new file mode 100644 index 000000000..e266c56c6 --- /dev/null +++ b/test/output/build/files/another/file-another.csv @@ -0,0 +1,2 @@ +Hola,mundo +1,2 diff --git a/test/output/build/files/_file/custom-styles.css b/test/output/build/files/custom-styles.css similarity index 100% rename from test/output/build/files/_file/custom-styles.css rename to test/output/build/files/custom-styles.css diff --git a/test/output/build/files/_file/file-top.csv b/test/output/build/files/file-top.csv similarity index 100% rename from test/output/build/files/_file/file-top.csv rename to test/output/build/files/file-top.csv diff --git a/test/output/build/files/files.html b/test/output/build/files/files.html index dff62d57b..98e3527ba 100644 --- a/test/output/build/files/files.html +++ b/test/output/build/files/files.html @@ -9,22 +9,22 @@ import {define} from "./_observablehq/client.js"; -define({id: "a7808707", inputs: ["display"], files: [{"name":"./file-top.csv","mimeType":"text/csv","path":"./_file/file-top.csv"}], body: (display) => { +define({id: "a7808707", inputs: ["display"], files: [{"name":"./file-top.csv","mimeType":"text/csv","path":"./file-top.csv"}], body: (display) => { display(( -fetch("./_file/file-top.csv") +fetch("./file-top.csv") )) }}); -define({id: "03b99abc", inputs: ["display"], files: [{"name":"./subsection/file-sub.csv","mimeType":"text/csv","path":"./_file/subsection/file-sub.csv"}], body: (display) => { +define({id: "03b99abc", inputs: ["display"], files: [{"name":"./subsection/file-sub.csv","mimeType":"text/csv","path":"./subsection/file-sub.csv"}], body: (display) => { display(( -fetch("./_file/subsection/file-sub.csv") +fetch("./subsection/file-sub.csv") )) }}); -define({id: "10037545", inputs: ["FileAttachment","display"], files: [{"name":"file-top.csv","mimeType":"text/csv","path":"./_file/file-top.csv"}], body: (FileAttachment,display) => { +define({id: "10037545", inputs: ["FileAttachment","display"], files: [{"name":"file-top.csv","mimeType":"text/csv","path":"./file-top.csv"}], body: (FileAttachment,display) => { display(( FileAttachment("file-top.csv") )) }}); -define({id: "453a8147", inputs: ["FileAttachment","display"], files: [{"name":"subsection/file-sub.csv","mimeType":"text/csv","path":"./_file/subsection/file-sub.csv"}], body: (FileAttachment,display) => { +define({id: "453a8147", inputs: ["FileAttachment","display"], files: [{"name":"subsection/file-sub.csv","mimeType":"text/csv","path":"./subsection/file-sub.csv"}], body: (FileAttachment,display) => { display(( FileAttachment("subsection/file-sub.csv") )) @@ -50,8 +50,8 @@ }
- - + +
diff --git a/test/output/build/files/_file/subsection/additional-styles.css b/test/output/build/files/subsection/additional-styles.css similarity index 100% rename from test/output/build/files/_file/subsection/additional-styles.css rename to test/output/build/files/subsection/additional-styles.css diff --git a/test/output/build/files/_file/subsection/file-sub.csv b/test/output/build/files/subsection/file-sub.csv similarity index 100% rename from test/output/build/files/_file/subsection/file-sub.csv rename to test/output/build/files/subsection/file-sub.csv diff --git a/test/output/build/files/subsection/subfiles.html b/test/output/build/files/subsection/subfiles.html index 67aeebf80..92aa44e57 100644 --- a/test/output/build/files/subsection/subfiles.html +++ b/test/output/build/files/subsection/subfiles.html @@ -9,22 +9,27 @@ import {define} from "../_observablehq/client.js"; -define({id: "62f1fd0c", inputs: ["display"], files: [{"name":"../file-top.csv","mimeType":"text/csv","path":"../_file/file-top.csv"}], body: (display) => { +define({id: "62f1fd0c", inputs: ["display"], files: [{"name":"../file-top.csv","mimeType":"text/csv","path":"../file-top.csv"}], body: (display) => { display(( -fetch("../_file/file-top.csv") +fetch("../file-top.csv") )) }}); -define({id: "94d347ec", inputs: ["display"], files: [{"name":"./file-sub.csv","mimeType":"text/csv","path":"../_file/subsection/file-sub.csv"}], body: (display) => { +define({id: "94d347ec", inputs: ["display"], files: [{"name":"./file-sub.csv","mimeType":"text/csv","path":"./file-sub.csv"}], body: (display) => { display(( -fetch("../_file/subsection/file-sub.csv") +fetch("./file-sub.csv") )) }}); -define({id: "ef9a31ef", inputs: ["FileAttachment","display"], files: [{"name":"../file-top.csv","mimeType":"text/csv","path":"../_file/file-top.csv"}], body: (FileAttachment,display) => { +define({id: "41cecaf7", inputs: ["display"], files: [{"name":"../another/file-another.csv","mimeType":"text/csv","path":"../another/file-another.csv"}], body: (display) => { +display(( +fetch("../another/file-another.csv") +)) +}}); +define({id: "ef9a31ef", inputs: ["FileAttachment","display"], files: [{"name":"../file-top.csv","mimeType":"text/csv","path":"../file-top.csv"}], body: (FileAttachment,display) => { display(( FileAttachment("../file-top.csv") )) }}); -define({id: "834ecf9f", inputs: ["FileAttachment","display"], files: [{"name":"file-sub.csv","mimeType":"text/csv","path":"../_file/subsection/file-sub.csv"}], body: (FileAttachment,display) => { +define({id: "834ecf9f", inputs: ["FileAttachment","display"], files: [{"name":"file-sub.csv","mimeType":"text/csv","path":"./file-sub.csv"}], body: (FileAttachment,display) => { display(( FileAttachment("file-sub.csv") )) @@ -50,10 +55,11 @@ }
- - + +
+
diff --git a/test/output/build/imports/foo/foo.html b/test/output/build/imports/foo/foo.html index 7cd4a8713..9bd864cbb 100644 --- a/test/output/build/imports/foo/foo.html +++ b/test/output/build/imports/foo/foo.html @@ -15,14 +15,14 @@ import {define} from "../_observablehq/client.js"; -define({id: "9c60abc0", inputs: ["display"], outputs: ["d3","bar","top"], files: [{"name":"/top.js","mimeType":"application/javascript","path":"../_file/top.js"}], body: async (display) => { +define({id: "9c60abc0", inputs: ["display"], outputs: ["d3","bar","top"], files: [{"name":"/top.js","mimeType":"application/javascript","path":"../top.js"}], body: async (display) => { const d3 = await import("https://cdn.jsdelivr.net/npm/d3/+esm"); const {bar} = await import("../_import/bar/bar.js?sha=2e71da6918681d51fd9e7ed79b03aed514771c2e1583af42783665aff3f5ef5e"); const {top} = await import("../_import/top.js?sha=43e37c2a4fe9ca94e62d0d8acd5dbd8bdd5f0ec845503964f465979c4c82c2a3"); display(bar); display(top); -fetch("../_file/top.js"); +fetch("../top.js"); return {d3,bar,top}; }}); diff --git a/test/output/build/imports/_file/top.js b/test/output/build/imports/top.js similarity index 100% rename from test/output/build/imports/_file/top.js rename to test/output/build/imports/top.js diff --git a/test/output/build/missing-file/index.html b/test/output/build/missing-file/index.html index fa69daaae..716fe834e 100644 --- a/test/output/build/missing-file/index.html +++ b/test/output/build/missing-file/index.html @@ -10,7 +10,7 @@ import {define} from "./_observablehq/client.js"; -define({id: "5760fd93", inputs: ["FileAttachment","display"], files: [{"name":"does-not-exist.txt","mimeType":"text/plain","path":"./_file/does-not-exist.txt"}], body: (FileAttachment,display) => { +define({id: "5760fd93", inputs: ["FileAttachment","display"], files: [{"name":"does-not-exist.txt","mimeType":"text/plain","path":"./does-not-exist.txt"}], body: (FileAttachment,display) => { display(( FileAttachment("does-not-exist.txt") )) diff --git a/test/output/build/multi/_file/file1.csv b/test/output/build/multi/file1.csv similarity index 100% rename from test/output/build/multi/_file/file1.csv rename to test/output/build/multi/file1.csv diff --git a/test/output/build/multi/_file/file2.csv b/test/output/build/multi/file2.csv similarity index 100% rename from test/output/build/multi/_file/file2.csv rename to test/output/build/multi/file2.csv diff --git a/test/output/build/multi/index.html b/test/output/build/multi/index.html index b668f6c43..7043a97ca 100644 --- a/test/output/build/multi/index.html +++ b/test/output/build/multi/index.html @@ -10,7 +10,7 @@ import {define} from "./_observablehq/client.js"; -define({id: "1bcb5df5", inputs: ["FileAttachment"], outputs: ["f1"], files: [{"name":"file1.csv","mimeType":"text/csv","path":"./_file/file1.csv"}], body: (FileAttachment) => { +define({id: "1bcb5df5", inputs: ["FileAttachment"], outputs: ["f1"], files: [{"name":"file1.csv","mimeType":"text/csv","path":"./file1.csv"}], body: (FileAttachment) => { const f1 = FileAttachment("file1.csv").csv(); return {f1}; }}); @@ -19,8 +19,8 @@ Input.table(f1) )) }}); -define({id: "aaa5c01d", outputs: ["f2"], files: [{"name":"./file2.csv","mimeType":"text/csv","path":"./_file/file2.csv"}], body: () => { -const f2 = fetch("./_file/file2.csv"); +define({id: "aaa5c01d", outputs: ["f2"], files: [{"name":"./file2.csv","mimeType":"text/csv","path":"./file2.csv"}], body: () => { +const f2 = fetch("./file2.csv"); return {f2}; }}); diff --git a/test/output/build/simple/_file/data.txt b/test/output/build/simple/data.txt similarity index 100% rename from test/output/build/simple/_file/data.txt rename to test/output/build/simple/data.txt diff --git a/test/output/build/simple/simple.html b/test/output/build/simple/simple.html index f3baaf5c1..7f2b38fe8 100644 --- a/test/output/build/simple/simple.html +++ b/test/output/build/simple/simple.html @@ -10,7 +10,7 @@ import {define} from "./_observablehq/client.js"; -define({id: "115586ff", inputs: ["FileAttachment"], outputs: ["result"], files: [{"name":"data.txt","mimeType":"text/plain","path":"./_file/data.txt"}], body: (FileAttachment) => { +define({id: "115586ff", inputs: ["FileAttachment"], outputs: ["result"], files: [{"name":"data.txt","mimeType":"text/plain","path":"./data.txt"}], body: (FileAttachment) => { let result = FileAttachment("data.txt").text(); return {result}; }}); diff --git a/test/output/fetch-parent-dir.json b/test/output/fetch-parent-dir.json index a631568da..a86fa1132 100644 --- a/test/output/fetch-parent-dir.json +++ b/test/output/fetch-parent-dir.json @@ -5,22 +5,22 @@ { "name": "./NOENT.md", "mimeType": "text/markdown", - "path": "./_file/NOENT.md" + "path": "./NOENT.md" }, { "name": "./NOENT.md", "mimeType": "text/markdown", - "path": "./_file/NOENT.md" + "path": "./NOENT.md" }, { "name": "./tex-expression.md", "mimeType": "text/markdown", - "path": "./_file/tex-expression.md" + "path": "./tex-expression.md" }, { "name": "./tex-expression.md", "mimeType": "text/markdown", - "path": "./_file/tex-expression.md" + "path": "./tex-expression.md" } ], "imports": [], @@ -139,10 +139,10 @@ { "name": "./NOENT.md", "mimeType": "text/markdown", - "path": "./_file/NOENT.md" + "path": "./NOENT.md" } ], - "body": "() => {\nconst fail5 = fetch(\"./_file/NOENT.md\").then(d => d.text())\nreturn {fail5};\n}" + "body": "() => {\nconst fail5 = fetch(\"./NOENT.md\").then(d => d.text())\nreturn {fail5};\n}" }, { "type": "cell", @@ -157,7 +157,7 @@ { "name": "./NOENT.md", "mimeType": "text/markdown", - "path": "./_file/NOENT.md" + "path": "./NOENT.md" } ], "body": "(FileAttachment) => {\nconst fail6 = FileAttachment(\"./NOENT.md\").text()\nreturn {fail6};\n}" @@ -172,10 +172,10 @@ { "name": "./tex-expression.md", "mimeType": "text/markdown", - "path": "./_file/tex-expression.md" + "path": "./tex-expression.md" } ], - "body": "() => {\nconst ok1 = fetch(\"./_file/tex-expression.md\").then(d => d.text())\nreturn {ok1};\n}" + "body": "() => {\nconst ok1 = fetch(\"./tex-expression.md\").then(d => d.text())\nreturn {ok1};\n}" }, { "type": "cell", @@ -190,7 +190,7 @@ { "name": "./tex-expression.md", "mimeType": "text/markdown", - "path": "./_file/tex-expression.md" + "path": "./tex-expression.md" } ], "body": "(FileAttachment) => {\nconst ok2 = FileAttachment(\"./tex-expression.md\").text()\nreturn {ok2};\n}" diff --git a/test/output/local-fetch.json b/test/output/local-fetch.json index df9870060..093ce698c 100644 --- a/test/output/local-fetch.json +++ b/test/output/local-fetch.json @@ -5,7 +5,7 @@ { "name": "./local-fetch.md", "mimeType": "text/markdown", - "path": "./_file/local-fetch.md" + "path": "./local-fetch.md" } ], "imports": [], @@ -36,10 +36,10 @@ { "name": "./local-fetch.md", "mimeType": "text/markdown", - "path": "./_file/local-fetch.md" + "path": "./local-fetch.md" } ], - "body": "(display) => {\ndisplay((\nfetch(\"./_file/local-fetch.md\")\n))\n}" + "body": "(display) => {\ndisplay((\nfetch(\"./local-fetch.md\")\n))\n}" } ], "hash": "286e04e0631c0f114d8c371c9aeda8bfd7eadacd31a72b9134ceabb1588c8371" diff --git a/test/output/template-file-attachment.js b/test/output/template-file-attachment.js index b5e0c61bb..f53f37286 100644 --- a/test/output/template-file-attachment.js +++ b/test/output/template-file-attachment.js @@ -1,3 +1,3 @@ -define({id: "0", inputs: ["FileAttachment"], files: [{"name":"test.js","mimeType":"application/javascript","path":"./_file/test.js"}], body: (FileAttachment) => { +define({id: "0", inputs: ["FileAttachment"], files: [{"name":"test.js","mimeType":"application/javascript","path":"./test.js"}], body: (FileAttachment) => { FileAttachment(`test.js`); }}); diff --git a/test/promote-file-attachment-test.ts b/test/promote-file-attachment-test.ts index 7f3efaf7b..272b449ed 100644 --- a/test/promote-file-attachment-test.ts +++ b/test/promote-file-attachment-test.ts @@ -9,8 +9,8 @@ describe("file attachments", () => { const sourcePath = "/attachments.md"; it("img[src]", () => { - const htmlStr = html``; - const expected = html``; + const htmlStr = html``; + const expected = html``; const context = mockContext(); const actual = normalizePieceHtml(htmlStr, sourcePath, context); @@ -19,7 +19,7 @@ describe("file attachments", () => { { mimeType: "image/png", name: "./test.png", - path: "./_file/test.png" + path: "./test.png" } ]); }); @@ -35,8 +35,8 @@ describe("file attachments", () => { /> `; const expected = html` - Image for testing + Image for testing `; const context = mockContext(); const actual = normalizePieceHtml(htmlStr, sourcePath, context); @@ -46,12 +46,12 @@ describe("file attachments", () => { { mimeType: "image/jpeg", name: "large.jpg", - path: "./_file/large.jpg" + path: "./large.jpg" }, { mimeType: "image/jpeg", name: "small.jpg", - path: "./_file/small.jpg" + path: "./small.jpg" } ]); }); @@ -60,7 +60,7 @@ describe("file attachments", () => { const htmlStr = html``; - const expected = html``; const expected = html``; @@ -97,12 +97,12 @@ describe("file attachments", () => { { mimeType: "video/mp4", name: "observable.mp4", - path: "./_file/observable.mp4" + path: "./observable.mp4" }, { mimeType: "video/quicktime", name: "observable.mov", - path: "./_file/observable.mov" + path: "./observable.mov" } ]); }); @@ -114,8 +114,8 @@ describe("file attachments", () => { `; const expected = html` - - + + `; const context = mockContext(); @@ -126,12 +126,12 @@ describe("file attachments", () => { { mimeType: "image/png", name: "observable-logo-narrow.png", - path: "./_file/observable-logo-narrow.png" + path: "./observable-logo-narrow.png" }, { mimeType: "image/png", name: "observable-logo-wide.png", - path: "./_file/observable-logo-wide.png" + path: "./observable-logo-wide.png" } ]); }); @@ -160,7 +160,7 @@ describe("file attachments", () => { /> `; const expected = html` - Cat image for testing + Cat image for testing `; const context = mockContext(); const actual = normalizePieceHtml(htmlStr, sourcePath, context); @@ -170,7 +170,7 @@ describe("file attachments", () => { { mimeType: "image/jpeg", name: "small.jpg", - path: "./_file/small.jpg" + path: "./small.jpg" } ]); }); @@ -184,7 +184,7 @@ describe("file attachments", () => { const expected = html``; @@ -196,7 +196,7 @@ describe("file attachments", () => { { mimeType: "video/quicktime", name: "observable.mov", - path: "./_file/observable.mov" + path: "./observable.mov" } ]); });