228 lines
5.2 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 changelog to show in Moonbase.
89
* Moonbase will show the changelog for the latest version, even if it is not installed.
90
*/
91
changelog?: string;
92
93
/**
94
* Whether the extension is deprecated and no longer receiving updates.
95
*/
96
deprecated?: boolean;
97
};
98
99
/**
100
* A list of extension IDs that are required for the extension to load.
101
*/
102
dependencies?: string[];
103
104
/**
105
* A list of extension IDs that the user may want to install.
106
*/
107
suggested?: string[];
108
109
/**
110
* A list of extension IDs that the extension is incompatible with.
111
* If two incompatible extensions are enabled, one of them will not load.
112
*/
113
incompatible?: string[];
114
115
/**
116
* A list of settings for your extension, where the key is the settings ID.
117
*/
118
settings?: Record<string, ExtensionSettingsManifest>;
119
120
/**
121
* A list of URLs to bypass CORS for.
122
* This is implemented by checking if the start of the URL matches.
123
* @example https://moonlight-mod.github.io/
124
*/
125
cors?: string[];
126
127
/**
128
* A list of URLs to block all requests to.
129
* This is implemented by checking if the start of the URL matches.
130
* @example https://moonlight-mod.github.io/
131
*/
132
blocked?: string[];
133
};
134
135
export enum ExtensionEnvironment {
136
/**
137
* The extension will run on both platforms, the host/native modules MAY be loaded
138
*/
139
Both = "both",
140
141
/**
142
* Extension will run on desktop only, the host/native modules are guaranteed to load
143
*/
144
Desktop = "desktop",
145
146
/**
147
* Currently equivalent to Both
148
*/
149
Web = "web"
150
}
151
152
export enum ExtensionLoadSource {
153
Developer,
154
Core,
155
Normal
156
}
157
158
export type DetectedExtension = {
159
id: string;
160
manifest: ExtensionManifest;
161
source: { type: ExtensionLoadSource; url?: string };
162
scripts: {
163
web?: string;
164
webPath?: string;
165
webpackModules?: Record<string, string>;
166
nodePath?: string;
167
hostPath?: string;
168
style?: string;
169
};
170
};
171
172
export type ProcessedExtensions = {
173
extensions: DetectedExtension[];
174
dependencyGraph: Map<string, Set<string> | null>;
175
};
176
177
export type PatchMatch = string | RegExp;
178
export type PatchReplaceFn = (substring: string, ...args: string[]) => string;
179
export type PatchReplaceModule = (orig: string) => WebpackModuleFunc;
180
181
export enum PatchReplaceType {
182
Normal,
183
Module
184
}
185
186
export type PatchReplace =
187
| {
188
type?: PatchReplaceType.Normal;
189
match: PatchMatch;
190
replacement: string | PatchReplaceFn;
191
}
192
| {
193
type: PatchReplaceType.Module;
194
replacement: PatchReplaceModule;
195
};
196
197
export type Patch = {
198
find: PatchMatch;
199
replace: PatchReplace | PatchReplace[];
200
hardFail?: boolean; // if any patches fail, all fail
201
prerequisite?: () => boolean;
202
};
203
204
export type ExplicitExtensionDependency = {
205
ext?: string;
206
id: string;
207
};
208
209
export type ExtensionDependency = string | RegExp | ExplicitExtensionDependency;
210
211
export type ExtensionWebpackModule = {
212
entrypoint?: boolean;
213
dependencies?: ExtensionDependency[];
214
run?: WebpackModuleFunc;
215
};
216
217
export type ExtensionWebExports = {
218
patches?: Patch[];
219
webpackModules?: Record<string, ExtensionWebpackModule>;
220
styles?: string[];
221
};
222
223
export type IdentifiedPatch = Patch & {
224
ext: string;
225
id: number;
226
};
227
228
export type IdentifiedWebpackModule = ExtensionWebpackModule & ExplicitExtensionDependency;
229