Skip to content

Commit

Permalink
feat: switch to use external file system module
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Aug 17, 2024
1 parent fa57d3c commit e15a889
Show file tree
Hide file tree
Showing 17 changed files with 89 additions and 2,188 deletions.
9 changes: 5 additions & 4 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
},
"imports": {
"@denosaurs/plug": "jsr:@denosaurs/plug@^1.0.6",
"@miyauci/file-system": "./src/file_system/mod.ts",
"@miyauci/file-system-access": "./src/mod.ts",
"@miyauci/file-system-access/deno": "./src/deno/mod.ts",
"@miyauci/fs": "jsr:@miyauci/fs@1.0.0-beta.1",
"@miyauci/infra": "jsr:@miyauci/infra@1.0.0-beta.2",
"@std/bytes": "jsr:@std/bytes@^1.0.2",
"@std/media-types": "jsr:@std/media-types@^1.0.2",
"@std/path": "jsr:@std/path@^1.0.1"
"@std/path": "jsr:@std/path@^1.0.1",
"@miyauci/file-system-access": "./src/mod.ts",
"@miyauci/file-system-access/deno": "./src/deno/mod.ts"
},
"exports": {
".": "./src/mod.ts",
Expand Down
28 changes: 27 additions & 1 deletion deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

199 changes: 8 additions & 191 deletions src/deno/adaptor.ts
Original file line number Diff line number Diff line change
@@ -1,200 +1,17 @@
import type {
AccessMode,
FileEntry,
FileLocator,
FileSystemAccessResult,
FileSystemEntry,
FileSystemLocator,
IO,
UnderlyingFileSystem,
} from "@miyauci/file-system";
import { join } from "@std/path/join";
import { isDirectoryEntry } from "@miyauci/file-system";
import { readdirSync, statSync } from "node:fs";
import { type FileEntry, UA, type UserAgent } from "@miyauci/fs";
import { FileSystem } from "@miyauci/fs/deno";
import { openDirectoryDialog, openFileDialog } from "./ffi.ts";
import type { Adaptor, OpenDirectoryPicker, OpenFileDialog } from "../type.ts";
import { typeByExtension } from "@std/media-types";
import { extname } from "@std/path/extname";

export class DenoAdaptor implements Adaptor {
io: IO = new DenoIO();

openFileDialog: OpenFileDialog = openFileDialog;
openDirectoryDialog: OpenDirectoryPicker = openDirectoryDialog;

fs: UnderlyingFileSystem = new DenoFs();
}

class DenoFs implements UnderlyingFileSystem {
create(entry: FileSystemEntry, locator: FileSystemLocator): void {
const fullPath = join(locator.root, ...locator.path, entry.name);

if (isDirectoryEntry(entry)) {
Deno.mkdirSync(fullPath);
} else {
const file = Deno.openSync(fullPath, { createNew: true, write: true });

file.writeSync(entry.binaryData);
file.utimeSync(entry.modificationTimestamp, entry.modificationTimestamp);

file.close();
}
}

remove(entry: FileSystemEntry, locator: FileSystemLocator): void {
const fullPath = join(locator.root, ...locator.path.slice(1), entry.name);

Deno.remove(fullPath, { recursive: true });
}

stream(
entry: FileEntry,
locator: FileSystemLocator,
): ReadableStream<Uint8Array> {
const fullPath = join(locator.root, ...locator.path);

return new ReadableStream({
async start(controller) {
using file = await Deno.open(fullPath, { read: true });

await file.read(entry.binaryData);

controller.enqueue(entry.binaryData);
controller.close();
},
});
}

write(locator: FileLocator, data: Uint8Array): void {
const fullPath = join(locator.root, ...locator.path);

Deno.writeFile(fullPath, data);
}
}

export class DenoIO implements IO {
time: number = Date.now();
async queryAccess(
locator: FileLocator,
mode: AccessMode,
): Promise<FileSystemAccessResult> {
const path = join(locator.root, ...locator.path);

switch (mode) {
case "read": {
const status = await Deno.permissions.request({ name: "read", path });

return { permissionState: status.state, errorName: "" };
}

case "readwrite": {
const readStatus = await Deno.permissions.request({
name: "read",
path,
});

if (readStatus.state !== "granted") {
return {
permissionState: readStatus.state,
errorName: "NotAllowedError",
};
}

const writeStatus = await Deno.permissions.request({
name: "write",
path,
});

if (writeStatus.state !== "granted") {
return {
permissionState: writeStatus.state,
errorName: "NotAllowedError",
};
}

return {
permissionState: "granted",
errorName: "",
};
}
}
}

async requestAccess(
locator: FileLocator,
mode: AccessMode,
): Promise<FileSystemAccessResult> {
const path = join(locator.root, ...locator.path);

switch (mode) {
case "read": {
const status = await Deno.permissions.request({ name: "read", path });

return { permissionState: status.state, errorName: "" };
}

case "readwrite": {
const readStatus = await Deno.permissions.request({
name: "read",
path,
});

if (readStatus.state !== "granted") {
return {
permissionState: readStatus.state,
errorName: "NotAllowedError",
};
}

const writeStatus = await Deno.permissions.request({
name: "write",
path,
});

if (writeStatus.state !== "granted") {
return {
permissionState: writeStatus.state,
errorName: "NotAllowedError",
};
}

return {
permissionState: "granted",
errorName: "",
};
}
}
}

children(locator: FileSystemLocator): FileSystemLocator[] {
const path = join(locator.root, ...locator.path);

const dir = readdirSync(path, { withFileTypes: true });

return dir.map<FileSystemLocator>((entry) => {
const path = locator.path.concat(entry.name);

if (entry.isDirectory()) {
return { kind: "directory", root: locator.root, path };
}

if (entry.isFile()) {
return { kind: "file", root: locator.root, path };
}

throw new Error();
});
}

modificationTimestamp(locator: FileSystemLocator): number {
const path = join(locator.root, ...locator.path);
const file = statSync(path);

return file.mtime?.getTime() ?? this.time;
}

binaryData(locator: FileSystemLocator): Uint8Array {
const path = join(locator.root, ...locator.path);
const file = statSync(path);

return new Uint8Array(file.size);
userAgent: UserAgent = new UA();
typeByEntry(entry: FileEntry): string | undefined {
return typeByExtension(extname(entry.name));
}
locateEntry = FileSystem.prototype.locateEntry;
}
Loading

0 comments on commit e15a889

Please sign in to comment.