Skip to content
Closed
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
3 changes: 2 additions & 1 deletion src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we error if the file already exists? (Which shouldn’t have been possible before, but should now be possible if you have e.g. an index.html and an index.md.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not error, but we must definitely skip the file in that case.

Here are examples (admittedly fringe) where a file points to a generated page:

javascript.md:
<a href=javascript.html download>download this page</a>

or
<a href=javascript download>download this page</a>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now skipping both of these

if (existsSync(outputPath) || existsSync(outputPath + ".html")) continue; // skip pages
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think we always want to add .html to the path here? Shouldn’t that only apply in extension-less cases? I feel like we are doing too much work to support this extreme edge case of linking to the page itself to download source code. Can we just remove the .html check entirely please?

let sourcePath = join(sourceRoot, file);
const outputPath = join(outputRoot, "_file", file);
if (!existsSync(sourcePath)) {
const loader = Loader.find(sourceRoot, file);
if (!loader) {
Expand Down
2 changes: 1 addition & 1 deletion src/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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))
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions src/javascript/fetches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
});
Expand Down
1 change: 1 addition & 0 deletions src/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{query: "a[href]", src: "href"},
{query: "a[download][href]", src: "href"},

Seems to me that we shouldn’t promote links to file attachments unless they are explicitly marked as downloads.

Philosophically, I don’t expect this functionality to work transparently. Meaning: we have to document which elements get this special treatment, and users will have to read the documentation to know which elements are handled automatically and which aren’t — we can’t guarantee that this will work. The only way to guarantee that it will work is for the user to declare the file attachment statically using FileAttachment in JavaScript. For example, we’re not including object[data] in this list, which looks like this

<object
  type="video/mp4"
  data="path/flower.webm"
  width="600"
  height="140">
  <img src="path/image.jpg" alt="useful image description">
</object>

I don’t think we should try to get everything here, and I don’t think we should feel “forced” to removing /_file to support promotion of linked files via a[href] — though I’m not really sure I follow why that solves a problem. And I do want to add content hashing of file attachments #260, so I’m not sure it is solving something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And come to think of it, a more practical and reliable solution would to be have a public folder where everything gets copied #169, which we can offer in addition to promoting source files (and generated files) through static analysis. So then if you want to ensure that something is including in dist even if it’s not detectable through static analysis, you just drop it into public.

Copy link
Copy Markdown
Contributor Author

@Fil Fil Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about limiting to a[download]; I mean, it's fine to add a[download] to the list, but my main motivation was more on the side of the [view source](page.md) pattern, which is otherwise a bit difficult to create with file attachments. I'll probably come back to it in some other way—on its own it doesn't warrant such a big change in any case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I think the most useful incarnation of [view source](page.md) will be to link to the editable version on the Observable platform or GitHub etc, where people will not only be able to view the source but contribute changes.

{query: "audio[src]", src: "src"},
{query: "audio source[src]", src: "src"},
{query: "img[src]", src: "src"},
Expand Down
79 changes: 45 additions & 34 deletions src/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -134,23 +112,19 @@ 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");
}
} catch (error) {
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"), {
Expand All @@ -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()) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is new… otherwise javascript was detected as the javascript/ directory

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);
Expand Down
1 change: 1 addition & 0 deletions test/files-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 2 additions & 0 deletions test/input/build/files/another/file-another.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Hola,mundo
1,2
4 changes: 4 additions & 0 deletions test/input/build/files/subsection/subfiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ fetch("../file-top.csv")
fetch("./file-sub.csv")
```

```js
fetch("../another/file-another.csv")
```

```js
FileAttachment("../file-top.csv")
```
Expand Down
14 changes: 7 additions & 7 deletions test/output/build/archives/tar.html
Original file line number Diff line number Diff line change
Expand Up @@ -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()
))
Expand Down
8 changes: 4 additions & 4 deletions test/output/build/archives/zip.html
Original file line number Diff line number Diff line change
Expand Up @@ -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()
))
Expand Down
2 changes: 2 additions & 0 deletions test/output/build/files/another/file-another.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Hola,mundo
1,2
16 changes: 8 additions & 8 deletions test/output/build/files/files.html
Original file line number Diff line number Diff line change
Expand Up @@ -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")
))
Expand All @@ -50,8 +50,8 @@
}</script>
<div id="observablehq-center">
<main id="observablehq-main" class="observablehq">
<span><link rel="stylesheet" href="./_file/custom-styles.css">
<link rel="stylesheet" href="./_file/subsection/additional-styles.css">
<span><link rel="stylesheet" href="./custom-styles.css">
<link rel="stylesheet" href="./subsection/additional-styles.css">
<link rel="stylesheet" href="https://example.com/style.css">
</span><div id="cell-a7808707" class="observablehq observablehq--block"></div>
<div id="cell-03b99abc" class="observablehq observablehq--block"></div>
Expand Down
22 changes: 14 additions & 8 deletions test/output/build/files/subsection/subfiles.html
Original file line number Diff line number Diff line change
Expand Up @@ -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")
))
Expand All @@ -50,10 +55,11 @@
}</script>
<div id="observablehq-center">
<main id="observablehq-main" class="observablehq">
<span><link rel="stylesheet" href="../_file/custom-styles.css">
<link rel="stylesheet" href="../_file/subsection/additional-styles.css">
<span><link rel="stylesheet" href="../custom-styles.css">
<link rel="stylesheet" href="./additional-styles.css">
</span><div id="cell-62f1fd0c" class="observablehq observablehq--block"></div>
<div id="cell-94d347ec" class="observablehq observablehq--block"></div>
<div id="cell-41cecaf7" class="observablehq observablehq--block"></div>
<div id="cell-ef9a31ef" class="observablehq observablehq--block"></div>
<div id="cell-834ecf9f" class="observablehq observablehq--block"></div>
</main>
Expand Down
4 changes: 2 additions & 2 deletions test/output/build/imports/foo/foo.html
Original file line number Diff line number Diff line change
Expand Up @@ -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};
}});

Expand Down
2 changes: 1 addition & 1 deletion test/output/build/missing-file/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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")
))
Expand Down
6 changes: 3 additions & 3 deletions test/output/build/multi/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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};
}});
Expand All @@ -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};
}});

Expand Down
2 changes: 1 addition & 1 deletion test/output/build/simple/simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -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};
}});
Expand Down
Loading