Skip to content

Commit

Permalink
feat: add new encoding for file option to from file system (#68)
Browse files Browse the repository at this point in the history
* feat: add new encoding for file option to from file system

* fix: default to null if no encoding is specified

* test: add tests for encoding

* feat: add encoding to metadata options
  • Loading branch information
luxass authored Dec 30, 2024
1 parent 3d3786d commit b1d8bd2
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
38 changes: 30 additions & 8 deletions src/file-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,30 @@ export interface FromFileSystemOptions {
* ```
*/
extras?: DirectoryJSON;

/**
* A function that determines the encoding to be used for a file.
* @default utf-8
*
* @example
* ```ts
* const files = await fromFileSystem("path/to/dir", {
* getEncodingForFile: (path) => "utf-8",
* });
* ```
*/
getEncodingForFile?: EncodingForFileFn;
}

const DEFAULT_ENCODING_FOR_FILE_FN = () => "utf-8" as BufferEncoding;

/**
* A function type that determines the encoding for a given file path.
* @param {string} path - The path to the file.
* @returns {BufferEncoding | null} The encoding to be used for the file, as a {@link BufferEncoding}.
*/
export type EncodingForFileFn = (path: string) => BufferEncoding | null;

/**
* Processes a directory and its contents recursively, creating a JSON representation of the file system.
*
Expand Down Expand Up @@ -97,7 +119,7 @@ async function processDirectory(
} else if (options.followLinks && file.isSymbolicLink()) {
files[filePath] = symlink(await readlink(fullPath));
} else {
files[filePath] = await readFile(fullPath, "utf8");
files[filePath] = await readFile(fullPath, options.getEncodingForFile(fullPath));
}
}

Expand Down Expand Up @@ -141,7 +163,7 @@ function processDirectorySync(
} else if (options.followLinks && file.isSymbolicLink()) {
files[filePath] = symlink(readlinkSync(fullPath));
} else {
files[filePath] = readFileSync(fullPath, "utf-8");
files[filePath] = readFileSync(fullPath, options.getEncodingForFile(fullPath));
}
}

Expand Down Expand Up @@ -173,12 +195,12 @@ export async function fromFileSystem(
return {};
}

const processOptions = {
const files = await processDirectory(path, {
ignore: options?.ignore ?? [],
followLinks: options?.followLinks ?? true,
};
getEncodingForFile: options?.getEncodingForFile ?? DEFAULT_ENCODING_FOR_FILE_FN,
});

const files = await processDirectory(path, processOptions);
return {
...files,
...options?.extras,
Expand Down Expand Up @@ -210,12 +232,12 @@ export function fromFileSystemSync(
return {};
}

const processOptions = {
const files = processDirectorySync(path, {
ignore: options?.ignore ?? [],
followLinks: options?.followLinks ?? true,
};
getEncodingForFile: options?.getEncodingForFile ?? DEFAULT_ENCODING_FOR_FILE_FN,
});

const files = processDirectorySync(path, processOptions);
return {
...files,
...options?.extras,
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export {
FIXTURE_TYPE_LINK_SYMBOL,
FIXTURE_TYPE_SYMLINK_SYMBOL,
} from "./constants";
export type { FromFileSystemOptions } from "./file-system";
export type { EncodingForFileFn, FromFileSystemOptions } from "./file-system";
export {
fromFileSystem,
fromFileSystemSync,
Expand Down
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ export interface FSMetadata {
/**
* The POSIX permission of the file system entry.
*/
mode: number;
mode?: number;

/**
* The encoding of the file system entry.
*/
encoding?: BufferEncoding | null;
}

/**
Expand Down
40 changes: 40 additions & 0 deletions test/file-system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,44 @@ describe("map file contents", () => {

expect(result).toMatchObject(mockFiles);
});

it("should use different encodings when using `getEncodingForFile`", async () => {
const mockFiles = {
"file.txt": "this is just a file!\n",
"README.md": "# vitest-testdirs\n",
"nested": {
"README.md": "# Nested Fixture Folder\n",
// eslint-disable-next-line node/prefer-global/buffer
"image.txt": Buffer.from([72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33, 10]),
},
};

const result = await fromFileSystem("./test/fixtures/file-system/test-dir", {
getEncodingForFile: (path) => {
return path.endsWith("image.txt") ? null : "utf8";
},
});

expect(result).toMatchObject(mockFiles);
});

it("should use different encodings when using `getEncodingForFile` (sync)", () => {
const mockFiles = {
"file.txt": "this is just a file!\n",
"README.md": "# vitest-testdirs\n",
"nested": {
"README.md": "# Nested Fixture Folder\n",
// eslint-disable-next-line node/prefer-global/buffer
"image.txt": Buffer.from([72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33, 10]),
},
};

const result = fromFileSystemSync("./test/fixtures/file-system/test-dir", {
getEncodingForFile: (path) => {
return path.endsWith("image.txt") ? null : "utf8";
},
});

expect(result).toMatchObject(mockFiles);
});
});

0 comments on commit b1d8bd2

Please sign in to comment.