@effect/platform-node-shared 0.0.0-snapshot-c0ae728e57df2c572ea803e1bb7121088cd67b49

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.
Files changed (154) hide show
  1. package/Http/Etag/package.json +6 -0
  2. package/Http/Multipart/package.json +6 -0
  3. package/LICENSE +21 -0
  4. package/NodeCommandExecutor/package.json +6 -0
  5. package/NodeFileSystem/package.json +6 -0
  6. package/NodeKeyValueStore/package.json +6 -0
  7. package/NodePath/package.json +6 -0
  8. package/NodeRuntime/package.json +6 -0
  9. package/NodeSink/package.json +6 -0
  10. package/NodeStream/package.json +6 -0
  11. package/NodeTerminal/package.json +6 -0
  12. package/README.md +64 -0
  13. package/dist/cjs/Http/Etag.js +43 -0
  14. package/dist/cjs/Http/Etag.js.map +1 -0
  15. package/dist/cjs/Http/Multipart.js +48 -0
  16. package/dist/cjs/Http/Multipart.js.map +1 -0
  17. package/dist/cjs/NodeCommandExecutor.js +38 -0
  18. package/dist/cjs/NodeCommandExecutor.js.map +1 -0
  19. package/dist/cjs/NodeFileSystem.js +42 -0
  20. package/dist/cjs/NodeFileSystem.js.map +1 -0
  21. package/dist/cjs/NodeKeyValueStore.js +42 -0
  22. package/dist/cjs/NodeKeyValueStore.js.map +1 -0
  23. package/dist/cjs/NodePath.js +52 -0
  24. package/dist/cjs/NodePath.js.map +1 -0
  25. package/dist/cjs/NodeRuntime.js +38 -0
  26. package/dist/cjs/NodeRuntime.js.map +1 -0
  27. package/dist/cjs/NodeSink.js +43 -0
  28. package/dist/cjs/NodeSink.js.map +1 -0
  29. package/dist/cjs/NodeStream.js +68 -0
  30. package/dist/cjs/NodeStream.js.map +1 -0
  31. package/dist/cjs/NodeTerminal.js +43 -0
  32. package/dist/cjs/NodeTerminal.js.map +1 -0
  33. package/dist/cjs/internal/commandExecutor.js +151 -0
  34. package/dist/cjs/internal/commandExecutor.js.map +1 -0
  35. package/dist/cjs/internal/error.js +44 -0
  36. package/dist/cjs/internal/error.js.map +1 -0
  37. package/dist/cjs/internal/fileSystem.js +370 -0
  38. package/dist/cjs/internal/fileSystem.js.map +1 -0
  39. package/dist/cjs/internal/http/etag.js +74 -0
  40. package/dist/cjs/internal/http/etag.js.map +1 -0
  41. package/dist/cjs/internal/http/multipart.js +119 -0
  42. package/dist/cjs/internal/http/multipart.js.map +1 -0
  43. package/dist/cjs/internal/path.js +72 -0
  44. package/dist/cjs/internal/path.js.map +1 -0
  45. package/dist/cjs/internal/runtime.js +59 -0
  46. package/dist/cjs/internal/runtime.js.map +1 -0
  47. package/dist/cjs/internal/sink.js +52 -0
  48. package/dist/cjs/internal/sink.js.map +1 -0
  49. package/dist/cjs/internal/stream.js +208 -0
  50. package/dist/cjs/internal/stream.js.map +1 -0
  51. package/dist/cjs/internal/terminal.js +121 -0
  52. package/dist/cjs/internal/terminal.js.map +1 -0
  53. package/dist/dts/Http/Etag.d.ts +16 -0
  54. package/dist/dts/Http/Etag.d.ts.map +1 -0
  55. package/dist/dts/Http/Multipart.d.ts +29 -0
  56. package/dist/dts/Http/Multipart.d.ts.map +1 -0
  57. package/dist/dts/NodeCommandExecutor.d.ts +12 -0
  58. package/dist/dts/NodeCommandExecutor.d.ts.map +1 -0
  59. package/dist/dts/NodeFileSystem.d.ts +11 -0
  60. package/dist/dts/NodeFileSystem.d.ts.map +1 -0
  61. package/dist/dts/NodeKeyValueStore.d.ts +12 -0
  62. package/dist/dts/NodeKeyValueStore.d.ts.map +1 -0
  63. package/dist/dts/NodePath.d.ts +21 -0
  64. package/dist/dts/NodePath.d.ts.map +1 -0
  65. package/dist/dts/NodeRuntime.d.ts +10 -0
  66. package/dist/dts/NodeRuntime.d.ts.map +1 -0
  67. package/dist/dts/NodeSink.d.ts +22 -0
  68. package/dist/dts/NodeSink.d.ts.map +1 -0
  69. package/dist/dts/NodeStream.d.ts +79 -0
  70. package/dist/dts/NodeStream.d.ts.map +1 -0
  71. package/dist/dts/NodeTerminal.d.ts +18 -0
  72. package/dist/dts/NodeTerminal.d.ts.map +1 -0
  73. package/dist/dts/internal/commandExecutor.d.ts +2 -0
  74. package/dist/dts/internal/commandExecutor.d.ts.map +1 -0
  75. package/dist/dts/internal/error.d.ts +2 -0
  76. package/dist/dts/internal/error.d.ts.map +1 -0
  77. package/dist/dts/internal/fileSystem.d.ts +2 -0
  78. package/dist/dts/internal/fileSystem.d.ts.map +1 -0
  79. package/dist/dts/internal/http/etag.d.ts +2 -0
  80. package/dist/dts/internal/http/etag.d.ts.map +1 -0
  81. package/dist/dts/internal/http/multipart.d.ts +2 -0
  82. package/dist/dts/internal/http/multipart.d.ts.map +1 -0
  83. package/dist/dts/internal/path.d.ts +2 -0
  84. package/dist/dts/internal/path.d.ts.map +1 -0
  85. package/dist/dts/internal/runtime.d.ts +2 -0
  86. package/dist/dts/internal/runtime.d.ts.map +1 -0
  87. package/dist/dts/internal/sink.d.ts +2 -0
  88. package/dist/dts/internal/sink.d.ts.map +1 -0
  89. package/dist/dts/internal/stream.d.ts +2 -0
  90. package/dist/dts/internal/stream.d.ts.map +1 -0
  91. package/dist/dts/internal/terminal.d.ts +2 -0
  92. package/dist/dts/internal/terminal.d.ts.map +1 -0
  93. package/dist/esm/Http/Etag.js +12 -0
  94. package/dist/esm/Http/Etag.js.map +1 -0
  95. package/dist/esm/Http/Multipart.js +17 -0
  96. package/dist/esm/Http/Multipart.js.map +1 -0
  97. package/dist/esm/NodeCommandExecutor.js +7 -0
  98. package/dist/esm/NodeCommandExecutor.js.map +1 -0
  99. package/dist/esm/NodeFileSystem.js +10 -0
  100. package/dist/esm/NodeFileSystem.js.map +1 -0
  101. package/dist/esm/NodeKeyValueStore.js +10 -0
  102. package/dist/esm/NodeKeyValueStore.js.map +1 -0
  103. package/dist/esm/NodePath.js +20 -0
  104. package/dist/esm/NodePath.js.map +1 -0
  105. package/dist/esm/NodeRuntime.js +7 -0
  106. package/dist/esm/NodeRuntime.js.map +1 -0
  107. package/dist/esm/NodeSink.js +12 -0
  108. package/dist/esm/NodeSink.js.map +1 -0
  109. package/dist/esm/NodeStream.js +37 -0
  110. package/dist/esm/NodeStream.js.map +1 -0
  111. package/dist/esm/NodeTerminal.js +12 -0
  112. package/dist/esm/NodeTerminal.js.map +1 -0
  113. package/dist/esm/internal/commandExecutor.js +120 -0
  114. package/dist/esm/internal/commandExecutor.js.map +1 -0
  115. package/dist/esm/internal/error.js +37 -0
  116. package/dist/esm/internal/error.js.map +1 -0
  117. package/dist/esm/internal/fileSystem.js +339 -0
  118. package/dist/esm/internal/fileSystem.js.map +1 -0
  119. package/dist/esm/internal/http/etag.js +43 -0
  120. package/dist/esm/internal/http/etag.js.map +1 -0
  121. package/dist/esm/internal/http/multipart.js +85 -0
  122. package/dist/esm/internal/http/multipart.js.map +1 -0
  123. package/dist/esm/internal/path.js +41 -0
  124. package/dist/esm/internal/path.js.map +1 -0
  125. package/dist/esm/internal/runtime.js +27 -0
  126. package/dist/esm/internal/runtime.js.map +1 -0
  127. package/dist/esm/internal/sink.js +19 -0
  128. package/dist/esm/internal/sink.js.map +1 -0
  129. package/dist/esm/internal/stream.js +170 -0
  130. package/dist/esm/internal/stream.js.map +1 -0
  131. package/dist/esm/internal/terminal.js +89 -0
  132. package/dist/esm/internal/terminal.js.map +1 -0
  133. package/dist/esm/package.json +4 -0
  134. package/package.json +105 -0
  135. package/src/Http/Etag.ts +18 -0
  136. package/src/Http/Multipart.ts +40 -0
  137. package/src/NodeCommandExecutor.ts +13 -0
  138. package/src/NodeFileSystem.ts +13 -0
  139. package/src/NodeKeyValueStore.ts +20 -0
  140. package/src/NodePath.ts +25 -0
  141. package/src/NodeRuntime.ts +11 -0
  142. package/src/NodeSink.ts +30 -0
  143. package/src/NodeStream.ts +109 -0
  144. package/src/NodeTerminal.ts +20 -0
  145. package/src/internal/commandExecutor.ts +203 -0
  146. package/src/internal/error.ts +51 -0
  147. package/src/internal/fileSystem.ts +575 -0
  148. package/src/internal/http/etag.ts +44 -0
  149. package/src/internal/http/multipart.ts +107 -0
  150. package/src/internal/path.ts +58 -0
  151. package/src/internal/runtime.ts +36 -0
  152. package/src/internal/sink.ts +57 -0
  153. package/src/internal/stream.ts +325 -0
  154. package/src/internal/terminal.ts +123 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import type { PlatformError } from "@effect/platform/Error"
5
+ import type { SizeInput } from "@effect/platform/FileSystem"
6
+ import type { Channel } from "effect/Channel"
7
+ import type { Chunk } from "effect/Chunk"
8
+ import type { Effect } from "effect/Effect"
9
+ import type { LazyArg } from "effect/Function"
10
+ import type { Stream } from "effect/Stream"
11
+ import type { Duplex, Readable } from "node:stream"
12
+ import * as internal from "./internal/stream.js"
13
+
14
+ /**
15
+ * @category models
16
+ * @since 1.0.0
17
+ */
18
+ export interface FromReadableOptions {
19
+ /** Defaults to undefined, which lets Node.js decide the chunk size */
20
+ readonly chunkSize?: SizeInput
21
+ }
22
+
23
+ /**
24
+ * @category model
25
+ * @since 1.0.0
26
+ */
27
+ export interface FromWritableOptions {
28
+ readonly endOnDone?: boolean
29
+ readonly encoding?: BufferEncoding
30
+ }
31
+
32
+ /**
33
+ * @category constructors
34
+ * @since 1.0.0
35
+ */
36
+ export const fromReadable: <E, A = Uint8Array>(
37
+ evaluate: LazyArg<Readable | NodeJS.ReadableStream>,
38
+ onError: (error: unknown) => E,
39
+ { chunkSize }?: FromReadableOptions
40
+ ) => Stream<A, E> = internal.fromReadable
41
+
42
+ /**
43
+ * @category constructors
44
+ * @since 1.0.0
45
+ */
46
+ export const fromReadableChannel: <E, A = Uint8Array>(
47
+ evaluate: LazyArg<Readable | NodeJS.ReadableStream>,
48
+ onError: (error: unknown) => E,
49
+ chunkSize: number | undefined
50
+ ) => Channel<never, unknown, unknown, unknown, E, Chunk<A>, void> = internal.fromReadableChannel
51
+
52
+ /**
53
+ * @category constructors
54
+ * @since 1.0.0
55
+ */
56
+ export const fromDuplex: <IE, E, I = Uint8Array, O = Uint8Array>(
57
+ evaluate: LazyArg<Duplex>,
58
+ onError: (error: unknown) => E,
59
+ options?: FromReadableOptions & FromWritableOptions
60
+ ) => Channel<never, IE, Chunk<I>, unknown, IE | E, Chunk<O>, void> = internal.fromDuplex
61
+
62
+ /**
63
+ * @category combinators
64
+ * @since 1.0.0
65
+ */
66
+ export const pipeThroughDuplex: {
67
+ <E2, B = Uint8Array>(
68
+ duplex: LazyArg<Duplex>,
69
+ onError: (error: unknown) => E2,
70
+ options?: (FromReadableOptions & FromWritableOptions) | undefined
71
+ ): <R, E, A>(self: Stream<A, E, R>) => Stream<B, E2 | E, R>
72
+ <R, E, A, E2, B = Uint8Array>(
73
+ self: Stream<A, E, R>,
74
+ duplex: LazyArg<Duplex>,
75
+ onError: (error: unknown) => E2,
76
+ options?: (FromReadableOptions & FromWritableOptions) | undefined
77
+ ): Stream<B, E | E2, R>
78
+ } = internal.pipeThroughDuplex
79
+
80
+ /**
81
+ * @category combinators
82
+ * @since 1.0.0
83
+ */
84
+ export const pipeThroughSimple: {
85
+ (duplex: LazyArg<Duplex>): <R, E>(self: Stream<string | Uint8Array, E, R>) => Stream<Uint8Array, E | PlatformError, R>
86
+ <R, E>(self: Stream<string | Uint8Array, E, R>, duplex: LazyArg<Duplex>): Stream<Uint8Array, PlatformError | E, R>
87
+ } = internal.pipeThroughSimple
88
+
89
+ /**
90
+ * @since 1.0.0
91
+ * @category conversions
92
+ */
93
+ export const toString: <E>(
94
+ readable: LazyArg<Readable | NodeJS.ReadableStream>,
95
+ options: {
96
+ readonly onFailure: (error: unknown) => E
97
+ readonly encoding?: BufferEncoding | undefined
98
+ readonly maxBytes?: SizeInput | undefined
99
+ }
100
+ ) => Effect<string, E> = internal.toString
101
+
102
+ /**
103
+ * @since 1.0.0
104
+ * @category conversions
105
+ */
106
+ export const toUint8Array: <E>(
107
+ readable: LazyArg<Readable | NodeJS.ReadableStream>,
108
+ options: { readonly onFailure: (error: unknown) => E; readonly maxBytes?: SizeInput | undefined }
109
+ ) => Effect<Uint8Array, E> = internal.toUint8Array
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import type { Terminal, UserInput } from "@effect/platform/Terminal"
5
+ import type { Effect } from "effect/Effect"
6
+ import type { Layer } from "effect/Layer"
7
+ import type { Scope } from "effect/Scope"
8
+ import * as InternalTerminal from "./internal/terminal.js"
9
+ /**
10
+ * @since 1.0.0
11
+ * @category constructors
12
+ */
13
+ export const make: (shouldQuit?: (input: UserInput) => boolean) => Effect<Terminal, never, Scope> =
14
+ InternalTerminal.make
15
+
16
+ /**
17
+ * @since 1.0.0
18
+ * @category layer
19
+ */
20
+ export const layer: Layer<Terminal> = InternalTerminal.layer
@@ -0,0 +1,203 @@
1
+ import * as Command from "@effect/platform/Command"
2
+ import * as CommandExecutor from "@effect/platform/CommandExecutor"
3
+ import type * as Error from "@effect/platform/Error"
4
+ import * as FileSystem from "@effect/platform/FileSystem"
5
+ import * as Deferred from "effect/Deferred"
6
+ import * as Effect from "effect/Effect"
7
+ import { constUndefined, pipe } from "effect/Function"
8
+ import * as Layer from "effect/Layer"
9
+ import * as Option from "effect/Option"
10
+ import type * as Scope from "effect/Scope"
11
+ import * as Sink from "effect/Sink"
12
+ import * as Stream from "effect/Stream"
13
+ import * as ChildProcess from "node:child_process"
14
+ import { handleErrnoException } from "./error.js"
15
+ import { fromWritable } from "./sink.js"
16
+ import { fromReadable } from "./stream.js"
17
+
18
+ const inputToStdioOption = (stdin: Option.Option<Command.Command.Input>): "pipe" | "inherit" =>
19
+ Option.match(stdin, { onNone: () => "inherit", onSome: () => "pipe" })
20
+
21
+ const outputToStdioOption = (output: Command.Command.Output): "pipe" | "inherit" =>
22
+ typeof output === "string" ? output : "pipe"
23
+
24
+ const toError = (err: unknown): Error => err instanceof globalThis.Error ? err : new globalThis.Error(String(err))
25
+
26
+ const toPlatformError = (
27
+ method: string,
28
+ error: NodeJS.ErrnoException,
29
+ command: Command.Command
30
+ ): Error.PlatformError => {
31
+ const flattened = Command.flatten(command).reduce((acc, curr) => {
32
+ const command = `${curr.command} ${curr.args.join(" ")}`
33
+ return acc.length === 0 ? command : `${acc} | ${command}`
34
+ }, "")
35
+ return handleErrnoException("Command", method)(error, [flattened])
36
+ }
37
+
38
+ type ExitCode = readonly [code: number | null, signal: NodeJS.Signals | null]
39
+ type ExitCodeDeferred = Deferred.Deferred<never, ExitCode>
40
+
41
+ const runCommand =
42
+ (fileSystem: FileSystem.FileSystem) =>
43
+ (command: Command.Command): Effect.Effect<CommandExecutor.Process, Error.PlatformError, Scope.Scope> => {
44
+ switch (command._tag) {
45
+ case "StandardCommand": {
46
+ const spawn = Effect.flatMap(
47
+ Deferred.make<never, ExitCode>(),
48
+ (exitCode) =>
49
+ Effect.async<readonly [ChildProcess.ChildProcess, ExitCodeDeferred], Error.PlatformError, never>(
50
+ (resume) => {
51
+ const handle = ChildProcess.spawn(command.command, command.args, {
52
+ stdio: [
53
+ inputToStdioOption(command.stdin),
54
+ outputToStdioOption(command.stdout),
55
+ outputToStdioOption(command.stderr)
56
+ ],
57
+ cwd: Option.getOrElse(command.cwd, constUndefined),
58
+ shell: command.shell,
59
+ env: { ...process.env, ...Object.fromEntries(command.env) }
60
+ })
61
+ handle.on("error", (err) => {
62
+ resume(Effect.fail(toPlatformError("spawn", err, command)))
63
+ })
64
+ handle.on("exit", (...args) => {
65
+ Deferred.unsafeDone(exitCode, Effect.succeed(args))
66
+ })
67
+ handle.on("spawn", () => {
68
+ resume(Effect.succeed([handle, exitCode]))
69
+ })
70
+ return Effect.sync(() => {
71
+ handle.kill("SIGTERM")
72
+ })
73
+ }
74
+ )
75
+ )
76
+ return pipe(
77
+ // Validate that the directory is accessible
78
+ Option.match(command.cwd, {
79
+ onNone: () => Effect.unit,
80
+ onSome: (dir) => fileSystem.access(dir)
81
+ }),
82
+ Effect.zipRight(
83
+ Effect.acquireRelease(
84
+ spawn,
85
+ ([handle, exitCode]) =>
86
+ Effect.flatMap(Deferred.isDone(exitCode), (done) =>
87
+ done ? Effect.unit : Effect.suspend(() => {
88
+ if (handle.kill("SIGTERM")) {
89
+ return Deferred.await(exitCode)
90
+ }
91
+ return Effect.unit
92
+ }))
93
+ )
94
+ ),
95
+ Effect.map(([handle, exitCodeDeferred]): CommandExecutor.Process => {
96
+ let stdin: Sink.Sink<never, Error.PlatformError, unknown, never, void> = Sink.drain
97
+
98
+ if (handle.stdin !== null) {
99
+ stdin = fromWritable(
100
+ () => handle.stdin!,
101
+ (err) => toPlatformError("toWritable", toError(err), command)
102
+ )
103
+ }
104
+
105
+ const exitCode: CommandExecutor.Process["exitCode"] = Effect.flatMap(
106
+ Deferred.await(exitCodeDeferred),
107
+ ([code, signal]) => {
108
+ if (code !== null) {
109
+ return Effect.succeed(CommandExecutor.ExitCode(code))
110
+ }
111
+ // If code is `null`, then `signal` must be defined. See the NodeJS
112
+ // documentation for the `"exit"` event on a `child_process`.
113
+ // https://nodejs.org/api/child_process.html#child_process_event_exit
114
+ return Effect.fail(
115
+ toPlatformError(
116
+ "exitCode",
117
+ new globalThis.Error(`Process interrupted due to receipt of signal: ${signal}`),
118
+ command
119
+ )
120
+ )
121
+ }
122
+ )
123
+
124
+ const isRunning = Effect.negate(Deferred.isDone(exitCodeDeferred))
125
+
126
+ const kill: CommandExecutor.Process["kill"] = (signal = "SIGTERM") =>
127
+ Effect.suspend(() =>
128
+ handle.kill(signal)
129
+ ? Effect.asUnit(Deferred.await(exitCodeDeferred))
130
+ : Effect.fail(toPlatformError("kill", new globalThis.Error("Failed to kill process"), command))
131
+ )
132
+
133
+ const pid = CommandExecutor.ProcessId(handle.pid!)
134
+ const stderr = fromReadable<Error.PlatformError, Uint8Array>(
135
+ () => handle.stderr!,
136
+ (err) => toPlatformError("fromReadable(stderr)", toError(err), command)
137
+ )
138
+ let stdout: Stream.Stream<Uint8Array, Error.PlatformError> = fromReadable<
139
+ Error.PlatformError,
140
+ Uint8Array
141
+ >(
142
+ () => handle.stdout!,
143
+ (err) => toPlatformError("fromReadable(stdout)", toError(err), command)
144
+ )
145
+ // TODO: add Sink.isSink
146
+ if (typeof command.stdout !== "string") {
147
+ stdout = Stream.transduce(stdout, command.stdout)
148
+ }
149
+ return {
150
+ [CommandExecutor.ProcessTypeId]: CommandExecutor.ProcessTypeId,
151
+ pid,
152
+ exitCode,
153
+ isRunning,
154
+ kill,
155
+ stdin,
156
+ stderr,
157
+ stdout
158
+ }
159
+ }),
160
+ Effect.tap((process) =>
161
+ Option.match(command.stdin, {
162
+ onNone: () => Effect.unit,
163
+ onSome: (stdin) => Effect.forkDaemon(Stream.run(stdin, process.stdin))
164
+ })
165
+ )
166
+ )
167
+ }
168
+ case "PipedCommand": {
169
+ const flattened = Command.flatten(command)
170
+ if (flattened.length === 1) {
171
+ return pipe(flattened[0], runCommand(fileSystem))
172
+ }
173
+ const head = flattened[0]
174
+ const tail = flattened.slice(1)
175
+ const initial = tail.slice(0, tail.length - 1)
176
+ const last = tail[tail.length - 1]
177
+ const stream = initial.reduce(
178
+ (stdin, command) =>
179
+ pipe(
180
+ Command.stdin(command, stdin),
181
+ runCommand(fileSystem),
182
+ Effect.map((process) => process.stdout),
183
+ Stream.unwrapScoped
184
+ ),
185
+ pipe(
186
+ runCommand(fileSystem)(head),
187
+ Effect.map((process) => process.stdout),
188
+ Stream.unwrapScoped
189
+ )
190
+ )
191
+ return pipe(Command.stdin(last, stream), runCommand(fileSystem))
192
+ }
193
+ }
194
+ }
195
+
196
+ /** @internal */
197
+ export const layer: Layer.Layer<CommandExecutor.CommandExecutor, never, FileSystem.FileSystem> = Layer.effect(
198
+ CommandExecutor.CommandExecutor,
199
+ pipe(
200
+ FileSystem.FileSystem,
201
+ Effect.map((fileSystem) => CommandExecutor.makeExecutor(runCommand(fileSystem)))
202
+ )
203
+ )
@@ -0,0 +1,51 @@
1
+ import type { PlatformError, SystemErrorReason } from "@effect/platform/Error"
2
+ import { SystemError } from "@effect/platform/Error"
3
+ import type { PathLike } from "node:fs"
4
+
5
+ /** @internal */
6
+ export const handleErrnoException = (module: SystemError["module"], method: string) =>
7
+ (
8
+ err: NodeJS.ErrnoException,
9
+ [path]: [path: PathLike | number, ...args: Array<any>]
10
+ ): PlatformError => {
11
+ let reason: SystemErrorReason = "Unknown"
12
+
13
+ switch (err.code) {
14
+ case "ENOENT":
15
+ reason = "NotFound"
16
+ break
17
+
18
+ case "EACCES":
19
+ reason = "PermissionDenied"
20
+ break
21
+
22
+ case "EEXIST":
23
+ reason = "AlreadyExists"
24
+ break
25
+
26
+ case "EISDIR":
27
+ reason = "BadResource"
28
+ break
29
+
30
+ case "ENOTDIR":
31
+ reason = "BadResource"
32
+ break
33
+
34
+ case "EBUSY":
35
+ reason = "Busy"
36
+ break
37
+
38
+ case "ELOOP":
39
+ reason = "BadResource"
40
+ break
41
+ }
42
+
43
+ return SystemError({
44
+ reason,
45
+ module,
46
+ method,
47
+ pathOrDescriptor: path as string | number,
48
+ syscall: err.syscall,
49
+ message: err.message
50
+ })
51
+ }