@b9g/filesystem 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/filesystem",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Universal File System Access API implementations for all platforms",
5
5
  "license": "MIT",
6
6
  "devDependencies": {
package/src/bun-s3.d.ts CHANGED
@@ -14,7 +14,10 @@ export declare class S3FileSystemBackend implements FileSystemBackend {
14
14
  stat(path: string): Promise<{
15
15
  kind: "file" | "directory";
16
16
  } | null>;
17
- readFile(path: string): Promise<Uint8Array>;
17
+ readFile(path: string): Promise<{
18
+ content: Uint8Array;
19
+ lastModified?: number;
20
+ }>;
18
21
  writeFile(path: string, data: Uint8Array): Promise<void>;
19
22
  listDir(path: string): Promise<Array<{
20
23
  name: string;
package/src/bun-s3.js CHANGED
@@ -39,14 +39,17 @@ var S3FileSystemBackend = class {
39
39
  const key = this.#getS3Key(path);
40
40
  const result = await this.#s3Client.get({ key });
41
41
  if (result.Body) {
42
+ let content;
42
43
  if (result.Body instanceof Uint8Array) {
43
- return result.Body;
44
+ content = result.Body;
44
45
  } else if (typeof result.Body === "string") {
45
- return new TextEncoder().encode(result.Body);
46
+ content = new TextEncoder().encode(result.Body);
46
47
  } else {
47
48
  const arrayBuffer = await result.Body.arrayBuffer();
48
- return new Uint8Array(arrayBuffer);
49
+ content = new Uint8Array(arrayBuffer);
49
50
  }
51
+ const lastModified = result.LastModified ? new Date(result.LastModified).getTime() : void 0;
52
+ return { content, lastModified };
50
53
  }
51
54
  throw new DOMException("File not found", "NotFoundError");
52
55
  } catch (error) {
package/src/index.d.ts CHANGED
@@ -32,12 +32,15 @@ export interface FileSystemBackend {
32
32
  kind: "file" | "directory";
33
33
  } | null>;
34
34
  /**
35
- * Read file content as bytes
35
+ * Read file content and metadata
36
36
  * @param path Path to the file
37
- * @returns File content as Uint8Array
37
+ * @returns File content and metadata
38
38
  * @throws NotFoundError if file doesn't exist
39
39
  */
40
- readFile(path: string): Promise<Uint8Array>;
40
+ readFile(path: string): Promise<{
41
+ content: Uint8Array;
42
+ lastModified?: number;
43
+ }>;
41
44
  /**
42
45
  * Write file content
43
46
  * @param path Path to the file
package/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="./index.d.ts" />
2
2
  // src/index.ts
3
+ import mime from "mime";
3
4
  var ShovelWritableFileStream = class extends WritableStream {
4
5
  #chunks;
5
6
  #backend;
@@ -118,14 +119,13 @@ var ShovelFileHandle = class extends ShovelHandle {
118
119
  }
119
120
  async getFile() {
120
121
  try {
121
- const content = await this.backend.readFile(this.path);
122
+ const { content, lastModified } = await this.backend.readFile(this.path);
122
123
  const filename = this.name;
123
124
  const mimeType = this.#getMimeType(filename);
124
125
  const buffer = content.slice().buffer;
125
126
  return new File([buffer], filename, {
126
127
  type: mimeType,
127
- lastModified: Date.now()
128
- // TODO: Could be stored in backend if needed
128
+ lastModified: lastModified ?? Date.now()
129
129
  });
130
130
  } catch (error) {
131
131
  throw new DOMException(`File not found: ${this.path}`, "NotFoundError");
@@ -141,21 +141,7 @@ var ShovelFileHandle = class extends ShovelHandle {
141
141
  );
142
142
  }
143
143
  #getMimeType(filename) {
144
- const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
145
- const mimeTypes = {
146
- ".html": "text/html",
147
- ".css": "text/css",
148
- ".js": "application/javascript",
149
- ".json": "application/json",
150
- ".png": "image/png",
151
- ".jpg": "image/jpeg",
152
- ".jpeg": "image/jpeg",
153
- ".gif": "image/gif",
154
- ".svg": "image/svg+xml",
155
- ".pdf": "application/pdf",
156
- ".zip": "application/zip"
157
- };
158
- return mimeTypes[ext] || "application/octet-stream";
144
+ return mime.getType(filename) || "application/octet-stream";
159
145
  }
160
146
  };
161
147
  var ShovelDirectoryHandle = class _ShovelDirectoryHandle extends ShovelHandle {
package/src/memory.d.ts CHANGED
@@ -31,7 +31,10 @@ export declare class MemoryFileSystemBackend implements FileSystemBackend {
31
31
  stat(path: string): Promise<{
32
32
  kind: "file" | "directory";
33
33
  } | null>;
34
- readFile(path: string): Promise<Uint8Array>;
34
+ readFile(path: string): Promise<{
35
+ content: Uint8Array;
36
+ lastModified?: number;
37
+ }>;
35
38
  writeFile(path: string, data: Uint8Array): Promise<void>;
36
39
  listDir(path: string): Promise<Array<{
37
40
  name: string;
package/src/memory.js CHANGED
@@ -24,7 +24,10 @@ var MemoryFileSystemBackend = class {
24
24
  if (!entry || !("content" in entry)) {
25
25
  throw new DOMException("File not found", "NotFoundError");
26
26
  }
27
- return entry.content;
27
+ return {
28
+ content: entry.content,
29
+ lastModified: entry.lastModified
30
+ };
28
31
  }
29
32
  async writeFile(path, data) {
30
33
  const { parentDir, name } = this.#resolveParent(path);
package/src/node.d.ts CHANGED
@@ -14,7 +14,10 @@ export declare class NodeFileSystemBackend implements FileSystemBackend {
14
14
  stat(filePath: string): Promise<{
15
15
  kind: "file" | "directory";
16
16
  } | null>;
17
- readFile(filePath: string): Promise<Uint8Array>;
17
+ readFile(filePath: string): Promise<{
18
+ content: Uint8Array;
19
+ lastModified?: number;
20
+ }>;
18
21
  writeFile(filePath: string, data: Uint8Array): Promise<void>;
19
22
  listDir(dirPath: string): Promise<Array<{
20
23
  name: string;
package/src/node.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /// <reference types="./node.d.ts" />
2
2
  // src/node.ts
3
- import {
4
- ShovelDirectoryHandle
5
- } from "./index.js";
3
+ import { ShovelDirectoryHandle } from "./index.js";
6
4
  import * as FS from "fs/promises";
7
5
  import * as Path from "path";
8
6
  var NodeFileSystemBackend = class {
@@ -31,8 +29,14 @@ var NodeFileSystemBackend = class {
31
29
  async readFile(filePath) {
32
30
  try {
33
31
  const fullPath = this.#resolvePath(filePath);
34
- const buffer = await FS.readFile(fullPath);
35
- return new Uint8Array(buffer);
32
+ const [buffer, stats] = await Promise.all([
33
+ FS.readFile(fullPath),
34
+ FS.stat(fullPath)
35
+ ]);
36
+ return {
37
+ content: new Uint8Array(buffer),
38
+ lastModified: stats.mtimeMs
39
+ };
36
40
  } catch (error) {
37
41
  if (error.code === "ENOENT") {
38
42
  throw new DOMException("File not found", "NotFoundError");