this repo has no description
1import {
2 ExtensionManifest,
3 DetectedExtension,
4 ExtensionLoadSource,
5 constants
6} from "@moonlight-mod/types";
7import { readConfig } from "./config";
8import requireImport from "./util/import";
9import { getCoreExtensionsPath, getExtensionsPath } from "./util/data";
10
11function findManifests(dir: string): string[] {
12 const fs = requireImport("fs");
13 const path = requireImport("path");
14 const ret = [];
15
16 for (const file of fs.readdirSync(dir)) {
17 if (file === "manifest.json") {
18 ret.push(path.join(dir, file));
19 }
20
21 if (fs.statSync(path.join(dir, file)).isDirectory()) {
22 ret.push(...findManifests(path.join(dir, file)));
23 }
24 }
25
26 return ret;
27}
28
29function loadDetectedExtensions(
30 dir: string,
31 type: ExtensionLoadSource
32): DetectedExtension[] {
33 const fs = requireImport("fs");
34 const path = requireImport("path");
35 const ret: DetectedExtension[] = [];
36
37 const manifests = findManifests(dir);
38 for (const manifestPath of manifests) {
39 if (!fs.existsSync(manifestPath)) continue;
40 const dir = path.dirname(manifestPath);
41
42 const manifest: ExtensionManifest = JSON.parse(
43 fs.readFileSync(manifestPath, "utf8")
44 );
45
46 const webPath = path.join(dir, "index.js");
47 const nodePath = path.join(dir, "node.js");
48 const hostPath = path.join(dir, "host.js");
49
50 // if none exist (empty manifest) don't give a shit
51 if (
52 !fs.existsSync(webPath) &&
53 !fs.existsSync(nodePath) &&
54 !fs.existsSync(hostPath)
55 ) {
56 continue;
57 }
58
59 const web = fs.existsSync(webPath)
60 ? fs.readFileSync(webPath, "utf8")
61 : undefined;
62
63 let url: string | undefined = undefined;
64 const urlPath = path.join(dir, constants.repoUrlFile);
65 if (type === ExtensionLoadSource.Normal && fs.existsSync(urlPath)) {
66 url = fs.readFileSync(urlPath, "utf8");
67 }
68
69 const wpModules: Record<string, string> = {};
70 const wpModulesPath = path.join(dir, "webpackModules");
71 if (fs.existsSync(wpModulesPath)) {
72 const wpModulesFile = fs.readdirSync(wpModulesPath);
73
74 for (const wpModuleFile of wpModulesFile) {
75 if (wpModuleFile.endsWith(".js")) {
76 wpModules[wpModuleFile.replace(".js", "")] = fs.readFileSync(
77 path.join(wpModulesPath, wpModuleFile),
78 "utf8"
79 );
80 }
81 }
82 }
83
84 ret.push({
85 id: manifest.id,
86 manifest,
87 source: {
88 type,
89 url
90 },
91 scripts: {
92 web,
93 webPath: web != null ? webPath : undefined,
94 webpackModules: wpModules,
95 nodePath: fs.existsSync(nodePath) ? nodePath : undefined,
96 hostPath: fs.existsSync(hostPath) ? hostPath : undefined
97 }
98 });
99 }
100
101 return ret;
102}
103
104function getExtensionsNative(): DetectedExtension[] {
105 const config = readConfig();
106 const res = [];
107
108 res.push(
109 ...loadDetectedExtensions(getCoreExtensionsPath(), ExtensionLoadSource.Core)
110 );
111
112 res.push(
113 ...loadDetectedExtensions(getExtensionsPath(), ExtensionLoadSource.Normal)
114 );
115
116 for (const devSearchPath of config.devSearchPaths ?? []) {
117 res.push(
118 ...loadDetectedExtensions(devSearchPath, ExtensionLoadSource.Developer)
119 );
120 }
121
122 return res;
123}
124
125export function getExtensions(): DetectedExtension[] {
126 webPreload: {
127 return moonlightNode.extensions;
128 }
129
130 nodePreload: {
131 return getExtensionsNative();
132 }
133
134 injector: {
135 return getExtensionsNative();
136 }
137
138 throw new Error("Called getExtensions() outside of node-preload/web-preload");
139}