forked from fedify-dev/fedify
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.ts
More file actions
155 lines (145 loc) · 4.06 KB
/
Copy pathconfig.ts
File metadata and controls
155 lines (145 loc) · 4.06 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { createConfigContext } from "@optique/config";
import { message } from "@optique/core";
import { printError } from "@optique/run";
import { readFileSync } from "node:fs";
import { parse as parseToml } from "smol-toml";
import {
array,
boolean,
check,
forward,
type InferOutput,
integer,
minValue,
number,
object,
optional,
picklist,
pipe,
string,
} from "valibot";
/**
* Schema for the webfinger command configuration.
*/
const webfingerSchema = object({
allowPrivateAddress: optional(boolean()),
maxRedirection: optional(number()),
});
/**
* Schema for the lookup command configuration.
*/
const lookupSchema = pipe(
object({
authorizedFetch: optional(boolean()),
firstKnock: optional(
picklist(["draft-cavage-http-signatures-12", "rfc9421"]),
),
allowPrivateAddress: optional(boolean()),
traverse: optional(boolean()),
recurse: optional(
picklist([
"replyTarget",
"quoteUrl",
"https://www.w3.org/ns/activitystreams#inReplyTo",
"https://www.w3.org/ns/activitystreams#quoteUrl",
"https://misskey-hub.net/ns#_misskey_quote",
"http://fedibird.com/ns#quoteUri",
]),
),
recurseDepth: optional(pipe(number(), integer(), minValue(1))),
suppressErrors: optional(boolean()),
defaultFormat: optional(picklist(["default", "raw", "compact", "expand"])),
separator: optional(string()),
timeout: optional(number()),
}),
forward(
check(
(input) => !(input.traverse === true && input.recurse != null),
"lookup.traverse and lookup.recurse cannot be used together.",
),
["recurse"],
),
forward(
check(
(input) => input.recurse != null || input.recurseDepth == null,
"lookup.recurseDepth requires lookup.recurse.",
),
["recurseDepth"],
),
);
/**
* Schema for the inbox command configuration.
*/
const inboxSchema = object({
actorName: optional(string()),
actorSummary: optional(string()),
authorizedFetch: optional(boolean()),
noTunnel: optional(boolean()),
follow: optional(array(string())),
acceptFollow: optional(array(string())),
});
/**
* Schema for the relay command configuration.
*/
const relaySchema = object({
protocol: optional(picklist(["mastodon", "litepub"])),
port: optional(number()),
name: optional(string()),
persistent: optional(string()),
noTunnel: optional(boolean()),
acceptFollow: optional(array(string())),
rejectFollow: optional(array(string())),
});
/**
* Schema for the nodeinfo command configuration.
*/
const nodeinfoSchema = object({
raw: optional(boolean()),
bestEffort: optional(boolean()),
showFavicon: optional(boolean()),
showMetadata: optional(boolean()),
});
/**
* Schema for the complete configuration file.
*/
export const configSchema = object({
// Global settings
debug: optional(boolean()),
userAgent: optional(string()),
tunnelService: optional(
picklist(["localhost.run", "serveo.net", "pinggy.io"]),
),
// Command-specific sections
webfinger: optional(webfingerSchema),
lookup: optional(lookupSchema),
inbox: optional(inboxSchema),
relay: optional(relaySchema),
nodeinfo: optional(nodeinfoSchema),
});
/**
* Type representing the configuration file structure.
*/
export type Config = InferOutput<typeof configSchema>;
/**
* Config context for use with bindConfig().
*/
export const configContext = createConfigContext({ schema: configSchema });
/**
* Try to load and parse a TOML config file.
* Returns an empty object if the file doesn't exist.
* Logs a warning and returns empty object for other errors (parsing, permissions).
*/
export function tryLoadToml(filePath: string): Record<string, unknown> {
try {
return parseToml(readFileSync(filePath, "utf-8"));
} catch (error) {
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
return {}; // File not found, which is fine.
}
// For other errors (e.g., parsing, permissions), warn the user.
printError(
message`Could not load or parse config file at ${filePath}. It will be ignored.`,
);
return {};
}
}