goscript 0.0.82 → 0.0.83

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 (68) hide show
  1. package/dist/gs/os/dir.gs.js +41 -27
  2. package/dist/gs/os/dir.gs.js.map +1 -1
  3. package/dist/gs/os/exec.gs.js +1 -2
  4. package/dist/gs/os/exec.gs.js.map +1 -1
  5. package/dist/gs/os/exec_posix.gs.js +1 -1
  6. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  7. package/dist/gs/os/file_constants_js.gs.js +71 -7
  8. package/dist/gs/os/file_constants_js.gs.js.map +1 -1
  9. package/dist/gs/os/file_js.gs.js +168 -24
  10. package/dist/gs/os/file_js.gs.js.map +1 -1
  11. package/dist/gs/os/file_posix_js.gs.js +75 -11
  12. package/dist/gs/os/file_posix_js.gs.js.map +1 -1
  13. package/dist/gs/os/file_unix_js.gs.d.ts +3 -3
  14. package/dist/gs/os/file_unix_js.gs.js +218 -21
  15. package/dist/gs/os/file_unix_js.gs.js.map +1 -1
  16. package/dist/gs/os/getwd_js.gs.js +19 -6
  17. package/dist/gs/os/getwd_js.gs.js.map +1 -1
  18. package/dist/gs/os/path.gs.js +3 -3
  19. package/dist/gs/os/path.gs.js.map +1 -1
  20. package/dist/gs/os/pidfd_js.gs.js +0 -3
  21. package/dist/gs/os/pidfd_js.gs.js.map +1 -1
  22. package/dist/gs/os/proc.gs.js +6 -3
  23. package/dist/gs/os/proc.gs.js.map +1 -1
  24. package/dist/gs/os/proc_js.gs.js +10 -5
  25. package/dist/gs/os/proc_js.gs.js.map +1 -1
  26. package/dist/gs/os/rawconn_js.gs.d.ts +6 -3
  27. package/dist/gs/os/rawconn_js.gs.js +16 -10
  28. package/dist/gs/os/rawconn_js.gs.js.map +1 -1
  29. package/dist/gs/os/removeall_js.gs.js +2 -4
  30. package/dist/gs/os/removeall_js.gs.js.map +1 -1
  31. package/dist/gs/os/root_js.gs.d.ts +4 -1
  32. package/dist/gs/os/root_js.gs.js +90 -40
  33. package/dist/gs/os/root_js.gs.js.map +1 -1
  34. package/dist/gs/os/root_noopenat.gs.js +13 -16
  35. package/dist/gs/os/root_noopenat.gs.js.map +1 -1
  36. package/dist/gs/os/stat_js.gs.js +40 -4
  37. package/dist/gs/os/stat_js.gs.js.map +1 -1
  38. package/dist/gs/os/stat_unix_js.gs.d.ts +1 -1
  39. package/dist/gs/os/stat_unix_js.gs.js +5 -10
  40. package/dist/gs/os/stat_unix_js.gs.js.map +1 -1
  41. package/dist/gs/os/tempfile.gs.d.ts +1 -1
  42. package/dist/gs/os/tempfile.gs.js +24 -7
  43. package/dist/gs/os/tempfile.gs.js.map +1 -1
  44. package/dist/gs/os/types_js.gs.d.ts +78 -1
  45. package/dist/gs/os/types_js.gs.js +464 -23
  46. package/dist/gs/os/types_js.gs.js.map +1 -1
  47. package/gs/os/dir.gs.ts +40 -28
  48. package/gs/os/exec.gs.ts +2 -4
  49. package/gs/os/exec_posix.gs.ts +1 -2
  50. package/gs/os/file_constants_js.gs.ts +70 -8
  51. package/gs/os/file_js.gs.ts +156 -26
  52. package/gs/os/file_posix_js.gs.ts +69 -13
  53. package/gs/os/file_unix_js.gs.ts +212 -24
  54. package/gs/os/file_unix_js.test.ts +131 -0
  55. package/gs/os/getwd_js.gs.ts +18 -8
  56. package/gs/os/path.gs.ts +3 -4
  57. package/gs/os/pidfd_js.gs.ts +3 -8
  58. package/gs/os/proc.gs.ts +6 -4
  59. package/gs/os/proc_js.gs.ts +11 -8
  60. package/gs/os/rawconn_js.gs.ts +22 -14
  61. package/gs/os/removeall_js.gs.ts +3 -6
  62. package/gs/os/root_js.gs.ts +94 -42
  63. package/gs/os/root_noopenat.gs.ts +13 -20
  64. package/gs/os/stat_js.gs.ts +37 -6
  65. package/gs/os/stat_unix_js.gs.ts +6 -13
  66. package/gs/os/tempfile.gs.ts +27 -9
  67. package/gs/os/types_js.gs.ts +528 -26
  68. package/package.json +1 -1
package/gs/os/dir.gs.ts CHANGED
@@ -1,42 +1,54 @@
1
1
  import * as $ from "@goscript/builtin/index.js";
2
2
  import { ErrUnimplemented } from "./error.gs.js";
3
+ import { createFileInfo, getDeno, getNodeFS, newHostError } from "./types_js.gs.js";
4
+ import { FileInfoToDirEntry } from "@goscript/io/fs/readdir.js";
3
5
 
4
6
  import * as fs from "@goscript/io/fs/index.js"
5
7
 
6
8
  type DirEntry = fs.DirEntry;
7
9
 
8
- // ReadDir reads the named directory,
9
- // returning all its directory entries sorted by filename.
10
- // If an error occurs reading the directory,
11
- // ReadDir returns the entries it was able to read before the error,
12
- // along with the error.
13
10
  export function ReadDir(name: string): [$.Slice<DirEntry>, $.GoError] {
14
- // Directory reading not supported in JavaScript environment
11
+ const denoObj = getDeno()
12
+ if (denoObj?.readDirSync) {
13
+ try {
14
+ const entries: DirEntry[] = []
15
+ for (const entry of denoObj.readDirSync(name)) {
16
+ const dirEntry = FileInfoToDirEntry(createFileInfo(entry.name, {
17
+ isDirectory: () => entry.isDirectory,
18
+ isSymbolicLink: () => entry.isSymlink,
19
+ mode: 0,
20
+ size: 0,
21
+ }))
22
+ if (dirEntry !== null) {
23
+ entries.push(dirEntry)
24
+ }
25
+ }
26
+ entries.sort((a, b) => (a?.Name() ?? "").localeCompare(b?.Name() ?? ""))
27
+ return [$.arrayToSlice(entries), null]
28
+ } catch (err) {
29
+ return [null, newHostError(err)]
30
+ }
31
+ }
32
+ const nodeFS = getNodeFS()
33
+ if (nodeFS?.readdirSync) {
34
+ try {
35
+ const entries = nodeFS.readdirSync(name, { withFileTypes: true }).map((entry: any) =>
36
+ FileInfoToDirEntry(createFileInfo(entry.name, {
37
+ isDirectory: () => typeof entry.isDirectory === "function" ? entry.isDirectory() : false,
38
+ isSymbolicLink: () => typeof entry.isSymbolicLink === "function" ? entry.isSymbolicLink() : false,
39
+ mode: 0,
40
+ size: 0,
41
+ }))
42
+ ).filter((entry: DirEntry | null): entry is DirEntry => entry !== null)
43
+ entries.sort((a, b) => (a?.Name() ?? "").localeCompare(b?.Name() ?? ""))
44
+ return [$.arrayToSlice(entries), null]
45
+ } catch (err) {
46
+ return [null, newHostError(err)]
47
+ }
48
+ }
15
49
  return [null, ErrUnimplemented]
16
50
  }
17
51
 
18
- // CopyFS copies the file system fsys into the directory dir,
19
- // creating dir if necessary.
20
- //
21
- // Files are created with mode 0o666 plus any execute permissions
22
- // from the source, and directories are created with mode 0o777
23
- // (before umask).
24
- //
25
- // CopyFS will not overwrite existing files. If a file name in fsys
26
- // already exists in the destination, CopyFS will return an error
27
- // such that errors.Is(err, fs.ErrExist) will be true.
28
- //
29
- // Symbolic links in fsys are not supported. A *PathError with Err set
30
- // to ErrInvalid is returned when copying from a symbolic link.
31
- //
32
- // Symbolic links in dir are followed.
33
- //
34
- // New files added to fsys (including if dir is a subdirectory of fsys)
35
- // while CopyFS is running are not guaranteed to be copied.
36
- //
37
- // Copying stops at and returns the first error encountered.
38
52
  export function CopyFS(dir: string, fsys: fs.FS): $.GoError {
39
- // File system copying not supported in JavaScript environment
40
53
  return ErrUnimplemented
41
54
  }
42
-
package/gs/os/exec.gs.ts CHANGED
@@ -137,7 +137,7 @@ export class ProcAttr {
137
137
  );
138
138
  }
139
139
 
140
- // Stub ProcessState for JavaScript environment
140
+ // ProcessState mirrors the minimal JavaScript process surface.
141
141
  export class ProcessState {
142
142
  public _fields: {}
143
143
 
@@ -159,14 +159,13 @@ export class ProcessState {
159
159
  );
160
160
  }
161
161
 
162
- // Signal interface stub
162
+ // Signal matches the Go signal interface shape when available.
163
163
  export type Signal = null | {
164
164
  Signal(): void
165
165
  String(): string
166
166
  }
167
167
  export const Signal = null as any;
168
168
 
169
- // Stub functions that return ErrUnimplemented
170
169
  export function Getpid(): number {
171
170
  return -1 // Not available in JavaScript
172
171
  }
@@ -195,4 +194,3 @@ export function newHandleProcess(pid: number, handle: number): Process {
195
194
  export function newPIDProcess(pid: number): Process {
196
195
  return new Process({Pid: pid})
197
196
  }
198
-
@@ -36,7 +36,7 @@ export class ProcessState {
36
36
  return cloned
37
37
  }
38
38
 
39
- // All methods return stub values for JavaScript environment
39
+ // JavaScript does not expose process timing and wait status details.
40
40
  public UserTime(): any {
41
41
  return 0 // Duration not available
42
42
  }
@@ -92,4 +92,3 @@ export class ProcessState {
92
92
  { "pid": { kind: $.TypeKind.Basic, name: "number" } }
93
93
  );
94
94
  }
95
-
@@ -1,8 +1,16 @@
1
1
  import * as $ from "@goscript/builtin/index.js";
2
2
  import { ErrUnimplemented } from "./error.gs.js";
3
+ import { getDeno, getEnv, getNodeFS, getPlatform, newHostError } from "./types_js.gs.js";
3
4
 
4
- // JavaScript-specific stubs for file constants and operations
5
- // These provide the required constants and stub implementations
5
+ function pickFirstEnv(keys: string[]): string {
6
+ for (const key of keys) {
7
+ const value = getEnv(key)
8
+ if (value !== "") {
9
+ return value
10
+ }
11
+ }
12
+ return ""
13
+ }
6
14
 
7
15
  // File open flags - using values compatible with typical Unix systems
8
16
  export const O_RDONLY = 0
@@ -19,7 +27,7 @@ export const SEEK_SET = 0
19
27
  export const SEEK_CUR = 1
20
28
  export const SEEK_END = 2
21
29
 
22
- // LinkError stub for compatibility
30
+ // LinkError carries details for link-related path errors.
23
31
  export class LinkError {
24
32
  public get Op(): string {
25
33
  return this._fields.Op.value
@@ -76,23 +84,77 @@ export class LinkError {
76
84
  }
77
85
  }
78
86
 
79
- // Directory and file operation stubs
80
87
  export function Readlink(name: string): [string, $.GoError] {
88
+ const denoObj = getDeno()
89
+ if (denoObj?.readLinkSync) {
90
+ try {
91
+ return [denoObj.readLinkSync(name), null]
92
+ } catch (err) {
93
+ return ["", newHostError(err)]
94
+ }
95
+ }
96
+ const nodeFS = getNodeFS()
97
+ if (nodeFS?.readlinkSync) {
98
+ try {
99
+ return [nodeFS.readlinkSync(name), null]
100
+ } catch (err) {
101
+ return ["", newHostError(err)]
102
+ }
103
+ }
81
104
  return ["", ErrUnimplemented]
82
105
  }
83
106
 
84
107
  export function TempDir(): string {
85
- return "/tmp"
108
+ const value = pickFirstEnv(["TMPDIR", "TEMP", "TMP"])
109
+ if (value !== "") {
110
+ return value
111
+ }
112
+ return getPlatform() === "win32" ? "." : "/tmp"
86
113
  }
87
114
 
88
115
  export function UserCacheDir(): [string, $.GoError] {
89
- return ["", ErrUnimplemented]
116
+ if (getPlatform() === "win32") {
117
+ const value = pickFirstEnv(["LOCALAPPDATA", "APPDATA", "USERPROFILE"])
118
+ if (value !== "") {
119
+ return [value, null]
120
+ }
121
+ return ["", ErrUnimplemented]
122
+ }
123
+ const value = pickFirstEnv(["XDG_CACHE_HOME"])
124
+ if (value !== "") {
125
+ return [value, null]
126
+ }
127
+ const [home, err] = UserHomeDir()
128
+ if (err !== null || home === "") {
129
+ return ["", err ?? ErrUnimplemented]
130
+ }
131
+ return [home.replace(/\/+$/, "") + "/.cache", null]
90
132
  }
91
133
 
92
134
  export function UserConfigDir(): [string, $.GoError] {
93
- return ["", ErrUnimplemented]
135
+ if (getPlatform() === "win32") {
136
+ const value = pickFirstEnv(["APPDATA", "USERPROFILE"])
137
+ if (value !== "") {
138
+ return [value, null]
139
+ }
140
+ return ["", ErrUnimplemented]
141
+ }
142
+ const value = pickFirstEnv(["XDG_CONFIG_HOME"])
143
+ if (value !== "") {
144
+ return [value, null]
145
+ }
146
+ const [home, err] = UserHomeDir()
147
+ if (err !== null || home === "") {
148
+ return ["", err ?? ErrUnimplemented]
149
+ }
150
+ return [home.replace(/\/+$/, "") + "/.config", null]
94
151
  }
95
152
 
96
153
  export function UserHomeDir(): [string, $.GoError] {
154
+ const keys = getPlatform() === "win32" ? ["USERPROFILE", "HOMEDRIVE", "HOME"] : ["HOME"]
155
+ const value = pickFirstEnv(keys)
156
+ if (value !== "") {
157
+ return [value, null]
158
+ }
97
159
  return ["", ErrUnimplemented]
98
- }
160
+ }
@@ -1,99 +1,229 @@
1
1
  import * as $ from "@goscript/builtin/index.js";
2
- import { ErrUnimplemented } from "./error.gs.js";
2
+ import { ErrInvalid, ErrUnimplemented } from "./error.gs.js";
3
3
  import { File } from "./types_js.gs.js";
4
+ import { getDeno, getNodeFS, newHostError } from "./types_js.gs.js";
5
+ import { O_CREATE, O_RDONLY, O_RDWR, O_TRUNC } from "./file_constants_js.gs.js";
6
+ import { Link as linkPath, openFileNolog, readlink, Remove as removePath, rename as renamePath, Symlink as symlinkPath, Truncate as truncatePath } from "./file_unix_js.gs.js";
7
+ import { Lstat as lstatPath, Stat as statPath } from "./stat_js.gs.js";
8
+ import { ValidPath } from "@goscript/io/fs/index.js"
4
9
 
5
10
  import * as fs from "@goscript/io/fs/index.js"
6
11
 
7
- // JavaScript-specific implementations for filesystem operations
8
- // These functions stub filesystem operations that cannot be implemented
9
- // in a JavaScript environment
10
-
11
- // File operations - stub implementations
12
12
  export function Open(name: string): [File | null, $.GoError] {
13
- return [null, ErrUnimplemented]
13
+ return OpenFile(name, O_RDONLY, 0)
14
14
  }
15
15
 
16
16
  export function Create(name: string): [File | null, $.GoError] {
17
- return [null, ErrUnimplemented]
17
+ return OpenFile(name, O_RDWR | O_CREATE | O_TRUNC, 0o666)
18
18
  }
19
19
 
20
20
  export function OpenFile(name: string, flag: number, perm: number): [File | null, $.GoError] {
21
- return [null, ErrUnimplemented]
21
+ return openFileNolog(name, flag, perm)
22
22
  }
23
23
 
24
24
  export function ReadFile(name: string): [$.Bytes, $.GoError] {
25
+ const denoObj = getDeno()
26
+ if (denoObj?.readFileSync) {
27
+ try {
28
+ return [denoObj.readFileSync(name), null]
29
+ } catch (err) {
30
+ return [null, newHostError(err)]
31
+ }
32
+ }
33
+ const nodeFS = getNodeFS()
34
+ if (nodeFS?.readFileSync) {
35
+ try {
36
+ return [nodeFS.readFileSync(name), null]
37
+ } catch (err) {
38
+ return [null, newHostError(err)]
39
+ }
40
+ }
25
41
  return [null, ErrUnimplemented]
26
42
  }
27
43
 
28
44
  export function WriteFile(name: string, data: $.Bytes, perm: number): $.GoError {
45
+ const buf = $.bytesToUint8Array(data)
46
+ const denoObj = getDeno()
47
+ if (denoObj?.writeFileSync) {
48
+ try {
49
+ denoObj.writeFileSync(name, buf, { mode: perm })
50
+ return null
51
+ } catch (err) {
52
+ return newHostError(err)
53
+ }
54
+ }
55
+ const nodeFS = getNodeFS()
56
+ if (nodeFS?.writeFileSync) {
57
+ try {
58
+ nodeFS.writeFileSync(name, buf, { mode: perm })
59
+ return null
60
+ } catch (err) {
61
+ return newHostError(err)
62
+ }
63
+ }
29
64
  return ErrUnimplemented
30
65
  }
31
66
 
32
- // Directory operations - stub implementations
33
67
  export function Mkdir(name: string, perm: number): $.GoError {
68
+ const denoObj = getDeno()
69
+ if (denoObj?.mkdirSync) {
70
+ try {
71
+ denoObj.mkdirSync(name, { mode: perm })
72
+ return null
73
+ } catch (err) {
74
+ return newHostError(err)
75
+ }
76
+ }
77
+ const nodeFS = getNodeFS()
78
+ if (nodeFS?.mkdirSync) {
79
+ try {
80
+ nodeFS.mkdirSync(name, { mode: perm })
81
+ return null
82
+ } catch (err) {
83
+ return newHostError(err)
84
+ }
85
+ }
34
86
  return ErrUnimplemented
35
87
  }
36
88
 
37
89
  export function MkdirAll(path: string, perm: number): $.GoError {
90
+ const denoObj = getDeno()
91
+ if (denoObj?.mkdirSync) {
92
+ try {
93
+ denoObj.mkdirSync(path, { mode: perm, recursive: true })
94
+ return null
95
+ } catch (err) {
96
+ return newHostError(err)
97
+ }
98
+ }
99
+ const nodeFS = getNodeFS()
100
+ if (nodeFS?.mkdirSync) {
101
+ try {
102
+ nodeFS.mkdirSync(path, { mode: perm, recursive: true })
103
+ return null
104
+ } catch (err) {
105
+ return newHostError(err)
106
+ }
107
+ }
38
108
  return ErrUnimplemented
39
109
  }
40
110
 
41
111
  export function Remove(name: string): $.GoError {
42
- return ErrUnimplemented
112
+ return removePath(name)
43
113
  }
44
114
 
45
115
  export function RemoveAll(path: string): $.GoError {
116
+ const denoObj = getDeno()
117
+ if (denoObj?.removeSync) {
118
+ try {
119
+ denoObj.removeSync(path, { recursive: true })
120
+ return null
121
+ } catch (err) {
122
+ return newHostError(err)
123
+ }
124
+ }
125
+ const nodeFS = getNodeFS()
126
+ if (nodeFS?.rmSync) {
127
+ try {
128
+ nodeFS.rmSync(path, { force: true, recursive: true })
129
+ return null
130
+ } catch (err) {
131
+ return newHostError(err)
132
+ }
133
+ }
46
134
  return ErrUnimplemented
47
135
  }
48
136
 
49
137
  export function Chdir(dir: string): $.GoError {
138
+ const denoObj = getDeno()
139
+ if (denoObj?.chdir) {
140
+ try {
141
+ denoObj.chdir(dir)
142
+ return null
143
+ } catch (err) {
144
+ return newHostError(err)
145
+ }
146
+ }
147
+ const processObj = (globalThis as any).process
148
+ if (processObj?.chdir) {
149
+ try {
150
+ processObj.chdir(dir)
151
+ return null
152
+ } catch (err) {
153
+ return newHostError(err)
154
+ }
155
+ }
50
156
  return ErrUnimplemented
51
157
  }
52
158
 
53
159
  export function Chmod(name: string, mode: number): $.GoError {
160
+ const denoObj = getDeno()
161
+ if (denoObj?.chmodSync) {
162
+ try {
163
+ denoObj.chmodSync(name, mode)
164
+ return null
165
+ } catch (err) {
166
+ return newHostError(err)
167
+ }
168
+ }
169
+ const nodeFS = getNodeFS()
170
+ if (nodeFS?.chmodSync) {
171
+ try {
172
+ nodeFS.chmodSync(name, mode)
173
+ return null
174
+ } catch (err) {
175
+ return newHostError(err)
176
+ }
177
+ }
54
178
  return ErrUnimplemented
55
179
  }
56
180
 
57
181
  export function Rename(oldpath: string, newpath: string): $.GoError {
58
- return ErrUnimplemented
182
+ return renamePath(oldpath, newpath)
59
183
  }
60
184
 
61
- // File information operations - stub implementations
62
185
  export function Stat(name: string): [fs.FileInfo, $.GoError] {
63
- return [null, ErrUnimplemented]
186
+ return statPath(name)
64
187
  }
65
188
 
66
189
  export function Lstat(name: string): [fs.FileInfo, $.GoError] {
67
- return [null, ErrUnimplemented]
190
+ return lstatPath(name)
68
191
  }
69
192
 
70
- // Link operations - stub implementations
71
193
  export function Link(oldname: string, newname: string): $.GoError {
72
- return ErrUnimplemented
194
+ return linkPath(oldname, newname)
73
195
  }
74
196
 
75
197
  export function Symlink(oldname: string, newname: string): $.GoError {
76
- return ErrUnimplemented
198
+ return symlinkPath(oldname, newname)
77
199
  }
78
200
 
79
201
  export function Readlink(name: string): [string, $.GoError] {
80
- return ["", ErrUnimplemented]
202
+ return readlink(name)
81
203
  }
82
204
 
83
205
  export function Truncate(name: string, size: number): $.GoError {
84
- return ErrUnimplemented
206
+ return truncatePath(name, size)
85
207
  }
86
208
 
87
- // File system information - stub implementations
88
209
  export function DirFS(dir: string): fs.FS {
89
- // Return a stub filesystem that always returns ErrUnimplemented
90
- return new stubFS()
210
+ return new hostFS({ root: dir })
91
211
  }
92
212
 
93
- class stubFS {
213
+ class hostFS {
214
+ public root: string
215
+
216
+ constructor(init?: Partial<{ root?: string }>) {
217
+ this.root = init?.root ?? "."
218
+ }
219
+
94
220
  public Open(name: string): [fs.File, $.GoError] {
95
- return [null, ErrUnimplemented]
221
+ if (!ValidPath(name)) {
222
+ return [null, ErrInvalid]
223
+ }
224
+ const fullPath = name === "." ? this.root : this.root.replace(/\/+$/, "") + "/" + name
225
+ return Open(fullPath)
96
226
  }
97
227
  }
98
228
 
99
-
229
+
@@ -1,40 +1,96 @@
1
1
  import * as $ from "@goscript/builtin/index.js";
2
2
  import { ErrUnimplemented } from "./error.gs.js";
3
+ import { getDeno, getNodeFS, newHostError } from "./types_js.gs.js";
3
4
 
4
- // JavaScript-specific stubs for POSIX file operations
5
- // These operations are not available in JavaScript environments
6
-
7
- // syscallMode stub
8
5
  export function syscallMode(i: number): number {
9
6
  return 0
10
7
  }
11
8
 
12
- // ignoringEINTR stub
13
9
  export function ignoringEINTR(fn: () => $.GoError): $.GoError {
14
- return ErrUnimplemented
10
+ return fn()
15
11
  }
16
12
 
17
- // ignoringEINTR2 stub
18
13
  export function ignoringEINTR2(fn: () => [string, $.GoError]): [string, $.GoError] {
19
- return ["", ErrUnimplemented]
14
+ return fn()
20
15
  }
21
16
 
22
- // Chmod operation stub
23
17
  export function Chmod(name: string, mode: number): $.GoError {
18
+ const denoObj = getDeno()
19
+ if (denoObj?.chmodSync) {
20
+ try {
21
+ denoObj.chmodSync(name, mode)
22
+ return null
23
+ } catch (err) {
24
+ return newHostError(err)
25
+ }
26
+ }
27
+ const nodeFS = getNodeFS()
28
+ if (nodeFS?.chmodSync) {
29
+ try {
30
+ nodeFS.chmodSync(name, mode)
31
+ return null
32
+ } catch (err) {
33
+ return newHostError(err)
34
+ }
35
+ }
24
36
  return ErrUnimplemented
25
37
  }
26
38
 
27
- // Chown operation stub
28
39
  export function Chown(name: string, uid: number, gid: number): $.GoError {
40
+ const denoObj = getDeno()
41
+ if (denoObj?.chownSync) {
42
+ try {
43
+ denoObj.chownSync(name, uid, gid)
44
+ return null
45
+ } catch (err) {
46
+ return newHostError(err)
47
+ }
48
+ }
49
+ const nodeFS = getNodeFS()
50
+ if (nodeFS?.chownSync) {
51
+ try {
52
+ nodeFS.chownSync(name, uid, gid)
53
+ return null
54
+ } catch (err) {
55
+ return newHostError(err)
56
+ }
57
+ }
29
58
  return ErrUnimplemented
30
59
  }
31
60
 
32
- // Lchown operation stub
33
61
  export function Lchown(name: string, uid: number, gid: number): $.GoError {
62
+ const nodeFS = getNodeFS()
63
+ if (nodeFS?.lchownSync) {
64
+ try {
65
+ nodeFS.lchownSync(name, uid, gid)
66
+ return null
67
+ } catch (err) {
68
+ return newHostError(err)
69
+ }
70
+ }
34
71
  return ErrUnimplemented
35
72
  }
36
73
 
37
- // Chtimes operation stub
38
74
  export function Chtimes(name: string, atime: any, mtime: any): $.GoError {
75
+ const at = typeof atime?.UnixMilli === "function" ? new Date(atime.UnixMilli()) : new Date(atime)
76
+ const mt = typeof mtime?.UnixMilli === "function" ? new Date(mtime.UnixMilli()) : new Date(mtime)
77
+ const denoObj = getDeno()
78
+ if (denoObj?.utimeSync) {
79
+ try {
80
+ denoObj.utimeSync(name, at, mt)
81
+ return null
82
+ } catch (err) {
83
+ return newHostError(err)
84
+ }
85
+ }
86
+ const nodeFS = getNodeFS()
87
+ if (nodeFS?.utimesSync) {
88
+ try {
89
+ nodeFS.utimesSync(name, at, mt)
90
+ return null
91
+ } catch (err) {
92
+ return newHostError(err)
93
+ }
94
+ }
39
95
  return ErrUnimplemented
40
- }
96
+ }