Skip to content

Commit

Permalink
Add workflows for node and bun, add tasks, add tests, add isDir,isFil…
Browse files Browse the repository at this point in the history
…e and isSymlink.
  • Loading branch information
Hexagon committed Mar 27, 2024
1 parent e303487 commit bfbd843
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 46 deletions.
29 changes: 0 additions & 29 deletions .github/workflows/deno.yml

This file was deleted.

20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
deno_ci:
uses: cross-org/workflows/.github/workflows/deno-ci.yml@main
with:
entrypoint: mod.ts
bun_ci:
uses: cross-org/workflows/.github/workflows/bun-ci.yml@main
with:
jsr_dependencies: "@cross/test @std/assert @cross/runtime"
node_ci:
uses: cross-org/workflows/.github/workflows/node-ci.yml@main
with:
jsr_dependencies: "@cross/test @std/assert @cross/runtime"
test_target: "src/*.test.ts"
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ will cover most scenarios, this library focuses on the file system operations.

## Coverage

| Method | Deno | Node | Bun | Browser (LocalStorage) |
| ------ | ---- | ---- | --- | ---------------------- |
| stat | X | X | X | |
| ... | | | | |
| Method | Deno | Node | Bun | Browser (LocalStorage) |
| --------- | ---- | ---- | --- | ---------------------- |
| stat | X | X | X | |
| exists | X | X | X | |
| isDir | X | X | X | |
| isFile | X | X | X | |
| isSymlink | X | X | X | |
| ... | | | | |

## Contribution guide

Expand Down
14 changes: 13 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,17 @@
"name": "@cross/fs",
"version": "0.0.3",
"exports": "./mod.ts",
"imports": { "@cross/runtime": "jsr:@cross/runtime@^1.0.0" }
"imports": {
"@cross/runtime": "jsr:@cross/runtime@^1.0.0",
"@cross/test": "jsr:@cross/test@^0.0.9",
"@std/assert": "jsr:@std/assert@^0.220.1"
},
"publish": {
"exclude": [".github", "*.test.ts"]
},
"tasks": {
"check": "deno fmt --check && deno lint && deno check mod.ts && deno task check-deps",
"test": "deno test -A",
"check-deps": "deno run -rA jsr:@check/deps"
}
}
3 changes: 2 additions & 1 deletion mod.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { stat } from "./stat/mod.ts";
export { stat } from "./src/stat.ts";
export { exists } from "./src/exists.ts";
14 changes: 14 additions & 0 deletions src/exists.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { assertEquals } from "@std/assert";
import { test } from "@cross/test";

import { exists } from "./exists.ts";

test("exists returns true on existing file", async () => {
const result = await exists("./mod.ts");
assertEquals(result, true);
});

test("exists returns false on non-existant file", async () => {
const result = await exists("./mod-nonexistant.ts");
assertEquals(result, false);
});
13 changes: 13 additions & 0 deletions src/exists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { NotFoundError, stat } from "./stat.ts";
export async function exists(path: string): Promise<boolean> {
try {
await stat(path);
return true;
} catch (error) {
if (error instanceof NotFoundError) {
return false;
} else {
throw error;
}
}
}
29 changes: 29 additions & 0 deletions src/is.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { assertEquals } from "@std/assert";
import { test } from "@cross/test";

import { isDir, isFile } from "./is.ts";

test("isFile returns true on existing file", async () => {
const result = await isFile("./mod.ts");
assertEquals(result, true);
});

test("isFile returns false on non-existiantfile", async () => {
const result = await isFile("./mod-nonexistant.ts");
assertEquals(result, false);
});

test("isDir returns false on existing file", async () => {
const result = await isDir("./mod.ts");
assertEquals(result, false);
});

test("isFile returns false on existing dir", async () => {
const result = await isFile("./src");
assertEquals(result, false);
});

test("isDir returns true on existing dir", async () => {
const result = await isDir("./src");
assertEquals(result, true);
});
37 changes: 37 additions & 0 deletions src/is.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { NotFoundError, stat } from "./stat.ts";
export async function isDir(path: string) {
try {
const result = await stat(path);
return result.isDirectory;
} catch (error) {
if (error instanceof NotFoundError) {
return false;
} else {
throw error;
}
}
}
export async function isFile(path: string) {
try {
const result = await stat(path);
return result.isFile;
} catch (error) {
if (error instanceof NotFoundError) {
return false;
} else {
throw error;
}
}
}
export async function isSymlink(path: string) {
try {
const result = await stat(path);
return result.isSymlink;
} catch (error) {
if (error instanceof NotFoundError) {
return false;
} else {
throw error;
}
}
}
47 changes: 36 additions & 11 deletions stat/mod.ts → src/stat.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { CurrentRuntime, Runtime } from "@cross/runtime";

interface StatOptions {
export interface StatOptions {
/* Request bigInts, Only used with node */
bigInt: false | undefined;
}

interface StatResult {
export interface StatResult {
/** Common Properties */
isFile: boolean;
isDirectory: boolean;
Expand Down Expand Up @@ -61,24 +61,49 @@ interface StatResult {
isSocket: boolean | null;
}

export class NotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = "NotFoundError";
}
}

async function statWrap(
path: string,
options?: StatOptions,
): Promise<StatResult> {
switch (CurrentRuntime) {
case Runtime.Node:
/* Falls through */
// deno-lint-ignore no-case-declarations
case Runtime.Bun:
const { stat } = await import("node:fs/promises");
return mapNodeStats(
await stat(path, options),
options?.bigInt === undefined ? true : false,
);

try {
//@ts-ignore Cross
const { stat } = await import("node:fs/promises");
return mapNodeStats(
//@ts-ignore Cross
await stat(path, options),
options?.bigInt === undefined ? true : false,
);
} catch (err) {
//@ts-ignore Cross
if ((err as NodeJS.ErrnoException).code === "ENOENT") {
throw new NotFoundError(`File not found: ${path}`);
} else {
throw err;
}
}
case Runtime.Deno:
return mapDenoStats(await Deno.stat(path));

try {
//@ts-ignore Cross
return mapDenoStats(await Deno.stat(path));
} catch (err) {
//@ts-ignore Cross
if (err instanceof Deno.errors.NotFound) {
throw new NotFoundError(`File not found: ${path}`);
} else {
throw err;
}
}
case Runtime.Browser: // Add browser case for clarity
throw new Error("File system access not supported in the browser");

Expand Down

0 comments on commit bfbd843

Please sign in to comment.