Skip to content

Commit ddce1e1

Browse files
authored
mimeType for FileAttachment (#281)
* mimeType for FileAttachment * coerce mimeType to string, if present
1 parent 21e5d9a commit ddce1e1

File tree

2 files changed

+12
-24
lines changed

2 files changed

+12
-24
lines changed

README.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -408,24 +408,7 @@ const document = await FileAttachment("index.html").html();
408408

409409
*Note: this function is not part of the Observable standard library (in notebooks), but is provided by this module as a means for defining custom file attachment implementations when working directly with the Observable runtime.*
410410

411-
Returns a [*FileAttachment*](#FileAttachment) function given the specified *resolve* function. The *resolve* function is an async function that takes a *name* and returns a URL at which the file of that name can be loaded. For example:
412-
413-
```js
414-
const FileAttachment = FileAttachments((name) =>
415-
`https://my.server/notebooks/demo/${name}`
416-
);
417-
```
418-
419-
Or, with a more complex example, calling an API to produce temporary URLs:
420-
421-
```js
422-
const FileAttachment = FileAttachments(async (name) =>
423-
if (cachedUrls.has(name)) return cachedUrls.get(name);
424-
const url = await fetchSignedFileUrl(notebookId, name);
425-
cachedUrls.set(name, url);
426-
return url;
427-
);
428-
```
411+
Returns a [*FileAttachment*](#FileAttachment) function given the specified *resolve* function. The *resolve* function is a function that takes a *name* and returns either an object {url, mimeType} representing the requested file if it exists, or null if the file does not exist. The url field (though not the object itself!) may be represented as a Promise if the URL is not yet known, such as for a file that is currently being uploaded. The mimeType must be a string, or undefined if the mime type is not known. For backwards compatibility, the *resolve* function may instead return just a URL, either a string or a promise.
429412

430413
### Generators
431414

src/fileAttachment.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ async function dsv(file, delimiter, {array = false, typed = false} = {}) {
1818
}
1919

2020
export class AbstractFile {
21-
constructor(name) {
21+
constructor(name, mimeType) {
2222
Object.defineProperty(this, "name", {value: name, enumerable: true});
23+
if (mimeType !== undefined) Object.defineProperty(this, "mimeType", {value: mimeType + "", enumerable: true});
2324
}
2425
async blob() {
2526
return (await remote_fetch(this)).blob();
@@ -79,8 +80,8 @@ export class AbstractFile {
7980
}
8081

8182
class FileAttachment extends AbstractFile {
82-
constructor(url, name) {
83-
super(name);
83+
constructor(url, name, mimeType) {
84+
super(name, mimeType);
8485
Object.defineProperty(this, "_url", {value: url});
8586
}
8687
async url() {
@@ -95,9 +96,13 @@ export function NoFileAttachments(name) {
9596
export default function FileAttachments(resolve) {
9697
return Object.assign(
9798
name => {
98-
const url = resolve(name += ""); // Returns a Promise, string, or null.
99-
if (url == null) throw new Error(`File not found: ${name}`);
100-
return new FileAttachment(url, name);
99+
const result = resolve(name += "");
100+
if (result == null) throw new Error(`File not found: ${name}`);
101+
if (typeof result === "object" && "url" in result) {
102+
const {url, mimeType} = result;
103+
return new FileAttachment(url, name, mimeType);
104+
}
105+
return new FileAttachment(result, name);
101106
},
102107
{prototype: FileAttachment.prototype} // instanceof
103108
);

0 commit comments

Comments
 (0)