Skip to content
Source
Sign inSign up
Open History to see the last commit

filesystem.ts

91 lines3.5 KB

1import * as Schema from "effect/Schema";
2import { NonNegativeInt, TrimmedNonEmptyString } from "./baseSchemas.ts";
3​
4const FILESYSTEM_PATH_MAX_LENGTH = 512;
5​
6export const FILESYSTEM_METADATA_BATCH_LIMIT = 64;
7​
8export const FilesystemGetMetadataInput = Schema.Struct({
9 // Absolute host paths, including ~/; clients must anchor relative paths.
10 paths: Schema.Array(
11 TrimmedNonEmptyString.check(Schema.isMaxLength(FILESYSTEM_PATH_MAX_LENGTH)),
12 ).check(Schema.isMinLength(1), Schema.isMaxLength(FILESYSTEM_METADATA_BATCH_LIMIT)),
13});
14export type FilesystemGetMetadataInput = typeof FilesystemGetMetadataInput.Type;
15​
16export const FilesystemEntryMetadata = Schema.Struct({
17 kind: Schema.Literals(["file", "directory", "other"]),
18 byteLength: Schema.optionalKey(NonNegativeInt),
19 mimeType: Schema.optionalKey(TrimmedNonEmptyString),
20});
21export type FilesystemEntryMetadata = typeof FilesystemEntryMetadata.Type;
22​
23// Entries follow request order; null means missing, unreadable, or unsupported.
24export const FilesystemGetMetadataResult = Schema.Struct({
25 entries: Schema.Array(Schema.NullOr(FilesystemEntryMetadata)),
26});
27export type FilesystemGetMetadataResult = typeof FilesystemGetMetadataResult.Type;
28​
29export const FilesystemBrowseInput = Schema.Struct({
30 partialPath: TrimmedNonEmptyString.check(Schema.isMaxLength(FILESYSTEM_PATH_MAX_LENGTH)),
31 cwd: Schema.optional(TrimmedNonEmptyString.check(Schema.isMaxLength(FILESYSTEM_PATH_MAX_LENGTH))),
32});
33export type FilesystemBrowseInput = typeof FilesystemBrowseInput.Type;
34​
35export const FilesystemBrowseEntry = Schema.Struct({
36 name: TrimmedNonEmptyString,
37 fullPath: TrimmedNonEmptyString,
38});
39export type FilesystemBrowseEntry = typeof FilesystemBrowseEntry.Type;
40​
41export const FilesystemBrowseResult = Schema.Struct({
42 parentPath: TrimmedNonEmptyString,
43 entries: Schema.Array(FilesystemBrowseEntry),
44});
45export type FilesystemBrowseResult = typeof FilesystemBrowseResult.Type;
46​
47export const FilesystemBrowseFailure = Schema.Literals([
48 "windows_path_unsupported",
49 "current_project_required",
50 "read_directory_failed",
51]);
52export type FilesystemBrowseFailure = typeof FilesystemBrowseFailure.Type;
53​
54function decodedFilesystemBrowseErrorMessage(props: object): string | undefined {
55 if (!("message" in props)) return undefined;
56 return typeof props.message === "string" ? props.message : undefined;
58​
59export class FilesystemBrowseError extends Schema.TaggedError<FilesystemBrowseError>()(
60 "FilesystemBrowseError",
61 {
62 partialPath: Schema.optional(TrimmedNonEmptyString),
63 cwd: Schema.optional(TrimmedNonEmptyString),
64 failure: Schema.optional(FilesystemBrowseFailure),
65 parentPath: Schema.optional(TrimmedNonEmptyString),
66 platform: Schema.optional(TrimmedNonEmptyString),
67 /** Set when the directory does not exist; older clients ignore it. */
68 pathMissing: Schema.optional(Schema.Boolean),
69 message: TrimmedNonEmptyString,
70 cause: Schema.optional(Schema.Defect()),
71 },
72) {
73 // @effect-diagnostics-next-line overriddenSchemaConstructor:off
74 constructor(props: {
75 readonly partialPath: string;
76 readonly cwd?: string | undefined;
77 readonly failure: FilesystemBrowseFailure;
78 readonly parentPath?: string;
79 readonly platform?: string;
80 readonly pathMissing?: boolean;
81 readonly cause?: unknown;
82 }) {
83 const cwd = props.cwd === undefined ? "" : ` from '${props.cwd}'`;
84 super({
85 ...props,
86 message:
87 decodedFilesystemBrowseErrorMessage(props) ??
88 `Failed to browse filesystem path '${props.partialPath}'${cwd}.`,
89 } as any);
90 }