Repository navigation
Expand file tree
/
Copy pathHostProcess.ts
More file actions
110 lines (97 loc) · 3.64 KB
/
Copy pathHostProcess.ts
File metadata and controls
110 lines (97 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as NodeDns from "node:dns";
import * as NodeOS from "node:os";
import * as NodeSea from "node:sea";
export const Platform = Context.Reference<NodeJS.Platform>("@t3tools/shared/HostProcess/Platform", {
defaultValue: () => process.platform,
});
export const Architecture = Context.Reference<NodeJS.Architecture>(
"@t3tools/shared/HostProcess/Architecture",
{
defaultValue: () => process.arch,
},
);
export const Hostname = Context.Reference<string>("@t3tools/shared/HostProcess/Hostname", {
defaultValue: () => NodeOS.hostname(),
});
export const HomeDirectory = Context.Reference<string>(
"@t3tools/shared/HostProcess/HomeDirectory",
{
defaultValue: () => NodeOS.homedir(),
},
);
export const Environment = Context.Reference<NodeJS.ProcessEnv>(
"@t3tools/shared/HostProcess/Environment",
{
defaultValue: () => process.env,
},
);
export const WorkingDirectory = Context.Reference<string>(
"@t3tools/shared/HostProcess/WorkingDirectory",
{
defaultValue: () => process.cwd(),
},
);
export const ExecutablePath = Context.Reference<string>(
"@t3tools/shared/HostProcess/ExecutablePath",
{
defaultValue: () => process.execPath,
},
);
export const Arguments = Context.Reference<ReadonlyArray<string>>(
"@t3tools/shared/HostProcess/Arguments",
{
defaultValue: () => process.argv,
},
);
/**
* The command the shell was given, before Node resolved it to the binary:
* `t3` for a PATH lookup, `./t3` or the launcher symlink for an explicit
* path. `process.argv[0]` and `execPath` are always the resolved binary.
*/
export const InvokedAs = Context.Reference<string>("@t3tools/shared/HostProcess/InvokedAs", {
defaultValue: () => process.argv0,
});
/**
* Whether this process is a Node single-executable rather than a script run
* by a Node on the machine. Code that needs a sibling file or a Node to run
* one branches on this: an executable hosts such things as hidden
* subcommands of itself.
*/
export const IsExecutable = Context.Reference<boolean>("@t3tools/shared/HostProcess/IsExecutable", {
defaultValue: () => NodeSea.isSea(),
});
/**
* Every IP address this machine answers to: the interface addresses, plus
* whatever the resolver returns for the machine's own hostname. The latter
* matters because a hostname can map to an address no interface carries —
* Debian-style hosts put `127.0.1.1` in `/etc/hosts` — and a program that
* records "its" address by resolving its hostname (Firefox's profile lock
* does) will write that one. "Is this address ours" has to accept both.
*
* Best effort: a failed lookup just leaves the interface set.
*/
export const Addresses = Context.Reference<Effect.Effect<ReadonlySet<string>>>(
"@t3tools/shared/HostProcess/Addresses",
{
defaultValue: () =>
Effect.gen(function* () {
const interfaces = Object.values(NodeOS.networkInterfaces())
.flat()
.flatMap((entry) => (entry ? [entry.address] : []));
const resolved = yield* Effect.tryPromise(() =>
NodeDns.promises.lookup(NodeOS.hostname(), { all: true }),
).pipe(
Effect.map((entries) => entries.map((entry) => entry.address)),
Effect.orElseSucceed(() => [] as ReadonlyArray<string>),
);
return new Set([...interfaces, ...resolved]);
}),
},
);
/** Undefined on platforms without POSIX uids (Windows). */
export const UserId = Context.Reference<number | undefined>("@t3tools/shared/HostProcess/UserId", {
defaultValue: () => process.getuid?.(),
});
export const isWindows = Effect.map(Platform, (platform) => platform === "win32");