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
132 lines (122 loc) · 3.42 KB
/
Copy pathconfig.ts
File metadata and controls
132 lines (122 loc) · 3.42 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
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,
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 = object({
authorizedFetch: optional(boolean()),
firstKnock: optional(
picklist(["draft-cavage-http-signatures-12", "rfc9421"]),
),
traverse: optional(boolean()),
recurse: optional(
picklist([
"replyTarget",
"https://www.w3.org/ns/activitystreams#inReplyTo",
]),
),
recurseDepth: optional(pipe(number(), integer(), minValue(1))),
suppressErrors: optional(boolean()),
defaultFormat: optional(picklist(["default", "raw", "compact", "expand"])),
separator: optional(string()),
timeout: optional(number()),
});
/**
* 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 {};
}
}