233 lines
5.4 kB
1
import { ExtensionSettingsManifest } from "./config";
2
import { Snowflake } from "./discord";
3
import { WebpackModuleFunc } from "./discord/webpack";
4
5
export enum ExtensionTag {
6
Accessibility = "accessibility",
7
Appearance = "appearance",
8
Chat = "chat",
9
Commands = "commands",
10
ContextMenu = "contextMenu",
11
DangerZone = "dangerZone",
12
Development = "development",
13
Fixes = "fixes",
14
Fun = "fun",
15
Markdown = "markdown",
16
Voice = "voice",
17
Privacy = "privacy",
18
Profiles = "profiles",
19
QualityOfLife = "qol",
20
Library = "library"
21
}
22
23
export type ExtensionAuthor =
24
| string
25
| {
26
name: string;
27
id?: Snowflake;
28
};
29
30
export type ExtensionManifest = {
31
$schema?: string;
32
33
/**
34
* A unique identifier for your extension.
35
*/
36
id: string;
37
38
/**
39
* A version string for your extension - doesn't need to follow a specific format. Required for publishing.
40
*/
41
version?: string;
42
43
/**
44
* The API level this extension targets. If it does not match the current version, the extension will not be loaded.
45
*/
46
apiLevel?: number;
47
48
/**
49
* Which environment this extension is capable of running in.
50
*/
51
environment?: ExtensionEnvironment;
52
53
/**
54
* Metadata about your extension for use in Moonbase.
55
*/
56
meta?: {
57
/**
58
* A human friendly name for your extension as a proper noun.
59
*/
60
name?: string;
61
62
/**
63
* A short tagline that appears below the name.
64
*/
65
tagline?: string;
66
67
/**
68
* A longer description that can use Markdown.
69
*/
70
description?: string;
71
72
/**
73
* List of authors that worked on this extension - accepts string or object with ID.
74
*/
75
authors?: ExtensionAuthor[];
76
77
/**
78
* A list of tags that are relevant to the extension.
79
*/
80
tags?: ExtensionTag[];
81
82
/**
83
* The URL to the source repository.
84
*/
85
source?: string;
86
87
/**
88
* A donation link (or other method of support). If you don't want financial contributions, consider putting your favorite charity here!
89
*/
90
donate?: string;
91
92
/**
93
* A changelog to show in Moonbase.
94
* Moonbase will show the changelog for the latest version, even if it is not installed.
95
*/
96
changelog?: string;
97
98
/**
99
* Whether the extension is deprecated and no longer receiving updates.
100
*/
101
deprecated?: boolean;
102
};
103
104
/**
105
* A list of extension IDs that are required for the extension to load.
106
*/
107
dependencies?: string[];
108
109
/**
110
* A list of extension IDs that the user may want to install.
111
*/
112
suggested?: string[];
113
114
/**
115
* A list of extension IDs that the extension is incompatible with.
116
* If two incompatible extensions are enabled, one of them will not load.
117
*/
118
incompatible?: string[];
119
120
/**
121
* A list of settings for your extension, where the key is the settings ID.
122
*/
123
settings?: Record<string, ExtensionSettingsManifest>;
124
125
/**
126
* A list of URLs to bypass CORS for.
127
* This is implemented by checking if the start of the URL matches.
128
* @example https://moonlight-mod.github.io/
129
*/
130
cors?: string[];
131
132
/**
133
* A list of URLs to block all requests to.
134
* This is implemented by checking if the start of the URL matches.
135
* @example https://moonlight-mod.github.io/
136
*/
137
blocked?: string[];
138
};
139
140
export enum ExtensionEnvironment {
141
/**
142
* The extension will run on both platforms, the host/native modules MAY be loaded
143
*/
144
Both = "both",
145
146
/**
147
* Extension will run on desktop only, the host/native modules are guaranteed to load
148
*/
149
Desktop = "desktop",
150
151
/**
152
* Currently equivalent to Both
153
*/
154
Web = "web"
155
}
156
157
export enum ExtensionLoadSource {
158
Developer,
159
Core,
160
Normal
161
}
162
163
export type DetectedExtension = {
164
id: string;
165
manifest: ExtensionManifest;
166
source: { type: ExtensionLoadSource; url?: string };
167
scripts: {
168
web?: string;
169
webPath?: string;
170
webpackModules?: Record<string, string>;
171
nodePath?: string;
172
hostPath?: string;
173
style?: string;
174
};
175
};
176
177
export type ProcessedExtensions = {
178
extensions: DetectedExtension[];
179
dependencyGraph: Map<string, Set<string> | null>;
180
};
181
182
export type PatchMatch = string | RegExp;
183
export type PatchReplaceFn = (substring: string, ...args: string[]) => string;
184
export type PatchReplaceModule = (orig: string) => WebpackModuleFunc;
185
186
export enum PatchReplaceType {
187
Normal,
188
Module
189
}
190
191
export type PatchReplace =
192
| {
193
type?: PatchReplaceType.Normal;
194
match: PatchMatch;
195
replacement: string | PatchReplaceFn;
196
}
197
| {
198
type: PatchReplaceType.Module;
199
replacement: PatchReplaceModule;
200
};
201
202
export type Patch = {
203
find: PatchMatch;
204
replace: PatchReplace | PatchReplace[];
205
hardFail?: boolean; // if any patches fail, all fail
206
prerequisite?: () => boolean;
207
};
208
209
export type ExplicitExtensionDependency = {
210
ext?: string;
211
id: string;
212
};
213
214
export type ExtensionDependency = string | RegExp | ExplicitExtensionDependency;
215
216
export type ExtensionWebpackModule = {
217
entrypoint?: boolean;
218
dependencies?: ExtensionDependency[];
219
run?: WebpackModuleFunc;
220
};
221
222
export type ExtensionWebExports = {
223
patches?: Patch[];
224
webpackModules?: Record<string, ExtensionWebpackModule>;
225
styles?: string[];
226
};
227
228
export type IdentifiedPatch = Patch & {
229
ext: string;
230
id: number;
231
};
232
233
export type IdentifiedWebpackModule = ExtensionWebpackModule & ExplicitExtensionDependency;
234