crx-monkey-next 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/api.d.ts +3 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/api.js +4 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/api.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/i18n.d.ts +17 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/i18n.js +38 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/i18n.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/main.d.ts +16 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/main.js +8 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/main.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/message.d.ts +30 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/message.js +75 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/message.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/runtime.d.ts +43 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/runtime.js +89 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/client/runtime.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/node/plugins/tsBundler.d.ts +28 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/node/plugins/tsBundler.js +151 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/node/plugins/tsBundler.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/node/typeDefs.d.ts +200 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/node/typeDefs.js +2 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/src/node/typeDefs.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/dist/client/tsconfig.client.tsbuildinfo +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/api.d.ts +3 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/api.js +4 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/api.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/i18n.d.ts +17 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/i18n.js +38 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/i18n.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/main.d.ts +17 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/main.js +9 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/main.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/message.d.ts +30 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/message.js +75 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/message.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/runtime.d.ts +32 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/runtime.js +58 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/client/runtime.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/node/typeDefs.d.ts +189 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/node/typeDefs.js +2 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/src/node/typeDefs.js.map +1 -0
- package/.rollup.cache/home/yakisova41/crx-monkey-next/packages/crx-monkey/tsconfig.client.tsbuildinfo +1 -0
- package/README.md +34 -0
- package/bin/crx-monkey +2 -0
- package/bun.lockb +0 -0
- package/dist/client/main.d.ts +187 -0
- package/dist/client/main.js +200 -0
- package/dist/client/tsconfig.client.tsbuildinfo +1 -0
- package/dist/node/exports.d.ts +213 -0
- package/dist/node/exports.js +650 -0
- package/dist/node/main.js +2759 -0
- package/jest.config.js +17 -0
- package/package.json +81 -0
- package/rollup.config.js +101 -0
- package/src/client/i18n.ts +42 -0
- package/src/client/main.ts +20 -0
- package/src/client/message.ts +118 -0
- package/src/client/runtime.ts +109 -0
- package/src/node/BundlerRegisterer.ts +311 -0
- package/src/node/ConfigLoader.ts +127 -0
- package/src/node/CrxmBundler.ts +213 -0
- package/src/node/Distributior.ts +295 -0
- package/src/node/Logger.ts +77 -0
- package/src/node/Watcher.ts +166 -0
- package/src/node/__tests__/config.test.ts +157 -0
- package/src/node/__tests__/manifest.test.ts +380 -0
- package/src/node/build.ts +64 -0
- package/src/node/dev.ts +146 -0
- package/src/node/development/CreateDevClient.ts +168 -0
- package/src/node/development/codes/extension.ts +187 -0
- package/src/node/development/codes/sw.ts +41 -0
- package/src/node/development/codes/userjs.ts +150 -0
- package/src/node/exports.ts +135 -0
- package/src/node/file.ts +45 -0
- package/src/node/inversify.config.ts +53 -0
- package/src/node/main.ts +34 -0
- package/src/node/manifest/ManifestFactory.ts +165 -0
- package/src/node/manifest/ManifestLoader.ts +71 -0
- package/src/node/manifest/ManifestParser.ts +191 -0
- package/src/node/manifest/i18n.ts +93 -0
- package/src/node/plugins/htmlBundler/HTMLTools.ts +332 -0
- package/src/node/plugins/htmlBundler/main.ts +140 -0
- package/src/node/plugins/sassBundler.ts +59 -0
- package/src/node/plugins/tsBundler.ts +197 -0
- package/src/node/server/FileServer.ts +97 -0
- package/src/node/server/SockServer.ts +143 -0
- package/src/node/typeDefs.ts +221 -0
- package/src/node/types.ts +24 -0
- package/src/node/userscript/CodeInjector.ts +164 -0
- package/src/node/userscript/UserscriptBundler.ts +138 -0
- package/src/node/userscript/UserscriptHeader.ts +76 -0
- package/src/node/userscript/UserscriptRegisterer.ts +204 -0
- package/src/node/utils.ts +25 -0
- package/tsconfig.client.json +20 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import esbuild, { BuildOptions, Plugin, PluginBuild } from 'esbuild';
|
|
2
|
+
import { CrxmBundlerPlugin, CrxmBundlerPluginWatch, CrxmResultSender } from '../typeDefs';
|
|
3
|
+
import typescript, {
|
|
4
|
+
CompilerOptions,
|
|
5
|
+
parseJsonConfigFileContent,
|
|
6
|
+
readConfigFile,
|
|
7
|
+
sys,
|
|
8
|
+
} from 'typescript';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
|
|
11
|
+
export interface TsBundlerOptions {
|
|
12
|
+
/**
|
|
13
|
+
* The options esbuild.
|
|
14
|
+
*/
|
|
15
|
+
esbuild?: BuildOptions;
|
|
16
|
+
/**
|
|
17
|
+
* Use checking types.
|
|
18
|
+
*/
|
|
19
|
+
typeCheck?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The path tsconfig.json
|
|
22
|
+
*/
|
|
23
|
+
tsconfig?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface EsbuildTypecheckPluginArgs {
|
|
27
|
+
compilerOptions?: CompilerOptions;
|
|
28
|
+
exit: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function esbuildTypecheckPlugin(options: EsbuildTypecheckPluginArgs = { exit: false }) {
|
|
32
|
+
const tsPlugin: Plugin = {
|
|
33
|
+
name: 'esbuild-typecheck-plugin',
|
|
34
|
+
setup: (build: PluginBuild) => {
|
|
35
|
+
build.onLoad(
|
|
36
|
+
{
|
|
37
|
+
filter: new RegExp(/^.*.(ts|tsx)$/),
|
|
38
|
+
},
|
|
39
|
+
(args) => {
|
|
40
|
+
const { path } = args;
|
|
41
|
+
|
|
42
|
+
const compilerOptions =
|
|
43
|
+
options.compilerOptions !== undefined
|
|
44
|
+
? options.compilerOptions
|
|
45
|
+
: { strict: true, noEmit: true };
|
|
46
|
+
|
|
47
|
+
const program = typescript.createProgram([path], compilerOptions);
|
|
48
|
+
|
|
49
|
+
const diagnostics = typescript.getPreEmitDiagnostics(program);
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
diagnostics.forEach((d) => {
|
|
53
|
+
const message = typescript.flattenDiagnosticMessageText(d.messageText, '\n');
|
|
54
|
+
if (d.file && d.start !== undefined) {
|
|
55
|
+
const { line, character } = d.file.getLineAndCharacterOfPosition(d.start);
|
|
56
|
+
|
|
57
|
+
console.error(
|
|
58
|
+
`\n ${chalk.bgBlueBright(' Typescript ')} ${chalk.bold(message)}\n ${chalk.gray(`${d.file.fileName} (${line + 1},${character + 1})`)}\n`,
|
|
59
|
+
);
|
|
60
|
+
if (options.exit) {
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
throw new Error(message);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
} catch (e) {
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
return tsPlugin;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Bundle typescript by esbuild
|
|
80
|
+
* @param options
|
|
81
|
+
* @returns
|
|
82
|
+
*/
|
|
83
|
+
export function tsBundler(options: TsBundlerOptions = { esbuild: {} }): CrxmBundlerPlugin {
|
|
84
|
+
const tsPluginOptions: EsbuildTypecheckPluginArgs = {
|
|
85
|
+
compilerOptions: {},
|
|
86
|
+
exit: true,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
if (options.tsconfig !== undefined) {
|
|
90
|
+
const tsconfig = readConfigFile(options.tsconfig, sys.readFile);
|
|
91
|
+
const parsedOptions = parseJsonConfigFileContent(tsconfig.config, sys, './');
|
|
92
|
+
|
|
93
|
+
if (tsconfig.config !== undefined) {
|
|
94
|
+
tsPluginOptions.compilerOptions = parsedOptions.options;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
name: 'Crxm Typescript Plugin',
|
|
100
|
+
plugin: async (filePath: string) => {
|
|
101
|
+
return await esbuild
|
|
102
|
+
.build({
|
|
103
|
+
...(options.esbuild !== undefined ? options.esbuild : {}),
|
|
104
|
+
entryPoints: [filePath],
|
|
105
|
+
treeShaking: true,
|
|
106
|
+
bundle: true,
|
|
107
|
+
metafile: true,
|
|
108
|
+
write: false,
|
|
109
|
+
format: 'iife',
|
|
110
|
+
target: 'esnext',
|
|
111
|
+
platform: 'browser',
|
|
112
|
+
logLevel: 'error',
|
|
113
|
+
tsconfig: options.tsconfig,
|
|
114
|
+
external: ['esbuild', 'esbuild/*', 'fs-extra', 'fs-extra/*', 'fs', 'path', 'crypto'],
|
|
115
|
+
|
|
116
|
+
plugins: [
|
|
117
|
+
...(options.esbuild?.plugins !== undefined ? options.esbuild.plugins : []),
|
|
118
|
+
...(options.typeCheck ? [esbuildTypecheckPlugin(tsPluginOptions)] : []),
|
|
119
|
+
],
|
|
120
|
+
})
|
|
121
|
+
.then((result) => {
|
|
122
|
+
const outputFile = result.outputFiles[0];
|
|
123
|
+
return outputFile.contents;
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Bundle typescript by esbuild
|
|
131
|
+
* @param options
|
|
132
|
+
* @returns
|
|
133
|
+
*/
|
|
134
|
+
export function tsBundlerWatch(
|
|
135
|
+
options: TsBundlerOptions = { esbuild: {} },
|
|
136
|
+
): CrxmBundlerPluginWatch {
|
|
137
|
+
return {
|
|
138
|
+
name: 'Crxm Watch Typescript Plugin',
|
|
139
|
+
plugin: async (filePath: string, sendResult: CrxmResultSender) => {
|
|
140
|
+
const watchPlugin: Plugin = {
|
|
141
|
+
name: 'send-esbuild-build-result-to-crxm-plugin',
|
|
142
|
+
setup: (build: PluginBuild) => {
|
|
143
|
+
build.onEnd((result) => {
|
|
144
|
+
if (result.outputFiles !== undefined) {
|
|
145
|
+
const outputFile = result.outputFiles[0].contents;
|
|
146
|
+
sendResult(outputFile);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const tsPluginOptions: EsbuildTypecheckPluginArgs = {
|
|
153
|
+
compilerOptions: {
|
|
154
|
+
target: 99,
|
|
155
|
+
},
|
|
156
|
+
exit: false,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
if (options.tsconfig !== undefined) {
|
|
160
|
+
const tsconfig = readConfigFile(options.tsconfig, sys.readFile);
|
|
161
|
+
const parsedOptions = parseJsonConfigFileContent(tsconfig.config, sys, './');
|
|
162
|
+
|
|
163
|
+
if (tsconfig.config !== undefined) {
|
|
164
|
+
tsPluginOptions.compilerOptions = parsedOptions.options;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const ctx = await esbuild.context({
|
|
169
|
+
...(options.esbuild !== undefined ? options.esbuild : {}),
|
|
170
|
+
entryPoints: [filePath],
|
|
171
|
+
format: 'iife',
|
|
172
|
+
treeShaking: true,
|
|
173
|
+
bundle: true,
|
|
174
|
+
metafile: true,
|
|
175
|
+
write: false,
|
|
176
|
+
target: 'esnext',
|
|
177
|
+
platform: 'browser',
|
|
178
|
+
logLevel: 'error',
|
|
179
|
+
tsconfig: options.tsconfig,
|
|
180
|
+
plugins: [
|
|
181
|
+
...(options.esbuild?.plugins !== undefined ? options.esbuild.plugins : []),
|
|
182
|
+
...(options.typeCheck ? [esbuildTypecheckPlugin(tsPluginOptions)] : []),
|
|
183
|
+
watchPlugin,
|
|
184
|
+
],
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
await ctx.watch();
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
stop: async () => {
|
|
191
|
+
await ctx.dispose();
|
|
192
|
+
// console.log(`${filePath} watching stoped`);
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { resolve, dirname, isAbsolute } from 'path';
|
|
3
|
+
import fse from 'fs-extra';
|
|
4
|
+
import * as http from 'http';
|
|
5
|
+
import consola from 'consola';
|
|
6
|
+
import { inject, injectable } from 'inversify';
|
|
7
|
+
import { TYPES } from '../types';
|
|
8
|
+
import { ConfigLoader } from '../ConfigLoader';
|
|
9
|
+
/*
|
|
10
|
+
/**
|
|
11
|
+
* The server of send to script code.
|
|
12
|
+
*/
|
|
13
|
+
@injectable()
|
|
14
|
+
export class FileServer {
|
|
15
|
+
private readonly app: express.Express;
|
|
16
|
+
private server: null | http.Server = null;
|
|
17
|
+
|
|
18
|
+
constructor(@inject(TYPES.ConfigLoader) private readonly configLoader: ConfigLoader) {
|
|
19
|
+
const {
|
|
20
|
+
server: { host, port },
|
|
21
|
+
} = this.configLoader.useConfig();
|
|
22
|
+
if (host === undefined || port === undefined) {
|
|
23
|
+
throw new Error("Server host, port or websocket's port were not specificated");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.app = express();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Start server.
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
public async start() {
|
|
34
|
+
this.setup();
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
server: { host, port },
|
|
38
|
+
} = this.configLoader.useConfig();
|
|
39
|
+
|
|
40
|
+
if (host === undefined || port === undefined) {
|
|
41
|
+
throw new Error("Server host, port or websocket's port were not specificated");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
this.server = this.app.listen(port, host, () => {
|
|
46
|
+
resolve(1);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public async dispose() {
|
|
52
|
+
if (this.server === null) {
|
|
53
|
+
throw consola.error(new Error('Dispose can be used after Watch is started'));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.server.close();
|
|
57
|
+
this.server = null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private setup() {
|
|
61
|
+
const {
|
|
62
|
+
output: { chrome, userjs },
|
|
63
|
+
manifest,
|
|
64
|
+
} = this.configLoader.useConfig();
|
|
65
|
+
|
|
66
|
+
if (chrome === undefined || userjs === undefined) {
|
|
67
|
+
throw new Error('');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.app.get('/userscript', (req, res) => {
|
|
71
|
+
let filepath = userjs;
|
|
72
|
+
|
|
73
|
+
if (!isAbsolute(userjs)) {
|
|
74
|
+
filepath = resolve(dirname(manifest), userjs);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (fse.existsSync(filepath)) {
|
|
78
|
+
res.sendFile(filepath);
|
|
79
|
+
} else {
|
|
80
|
+
res.send(400);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
this.app.get('/dev.user.js', (req, res) => {
|
|
85
|
+
let filepath = userjs;
|
|
86
|
+
|
|
87
|
+
if (!isAbsolute(userjs)) {
|
|
88
|
+
filepath = resolve(dirname(manifest), dirname(userjs), 'dev.user.js');
|
|
89
|
+
}
|
|
90
|
+
if (fse.existsSync(filepath)) {
|
|
91
|
+
res.sendFile(filepath);
|
|
92
|
+
} else {
|
|
93
|
+
res.send(400);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import { WebSocketServer, type WebSocket } from 'ws';
|
|
3
|
+
import { TYPES } from '../types';
|
|
4
|
+
import { ConfigLoader } from '../ConfigLoader';
|
|
5
|
+
import { Logger } from '../Logger';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The websocket server of manage auto reload.
|
|
10
|
+
*/
|
|
11
|
+
@injectable()
|
|
12
|
+
export class SockServer {
|
|
13
|
+
private readonly wserver: WebSocketServer;
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
private listeners: SockServerLisntener<any>[] = [];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Start and setup server.
|
|
19
|
+
* @param host
|
|
20
|
+
* @param port
|
|
21
|
+
*/
|
|
22
|
+
constructor(
|
|
23
|
+
@inject(TYPES.ConfigLoader) private readonly configLoader: ConfigLoader,
|
|
24
|
+
@inject(TYPES.Logger) private readonly logger: Logger,
|
|
25
|
+
) {
|
|
26
|
+
const {
|
|
27
|
+
server: { host, websocket },
|
|
28
|
+
} = this.configLoader.useConfig();
|
|
29
|
+
|
|
30
|
+
this.wserver = new WebSocketServer({
|
|
31
|
+
port: websocket,
|
|
32
|
+
host: host,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
//this.setup();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-constraint
|
|
39
|
+
public addMsgListener<T extends SockRecieveContent>(listener: SockServerLisntener<T>) {
|
|
40
|
+
this.listeners.push(listener);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private dispatch<T extends SockRecieveContent>(msg: SockRecieve<T>) {
|
|
44
|
+
this.listeners.forEach((l) => {
|
|
45
|
+
l(msg);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public setup() {
|
|
50
|
+
this.wserver.addListener('connection', (socket) => {
|
|
51
|
+
this.sendMsg<SockServerResponseConnected>(socket, {
|
|
52
|
+
type: 'connected',
|
|
53
|
+
content: null,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
socket.addEventListener('message', (e) => {
|
|
57
|
+
if (typeof e.data === 'string') {
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
const data: SockRecieve<any> = JSON.parse(e.data);
|
|
60
|
+
this.dispatch(data);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.sendMsg<SockServerResponseContent>(socket, {
|
|
64
|
+
type: 'send_ok',
|
|
65
|
+
content: null,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Send reload signal to websocket client.
|
|
73
|
+
* @param token
|
|
74
|
+
*/
|
|
75
|
+
public reload(token: ReloadTokens) {
|
|
76
|
+
this.wserver.clients.forEach((client) => {
|
|
77
|
+
this.sendMsg<SockServerResponseReload>(client, {
|
|
78
|
+
type: 'reload',
|
|
79
|
+
content: token,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
this.logger.dispatchDebug(`🔃 Dispatch reload ${chalk.gray('"' + token + '"')}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public sendMsg<T extends SockServerResponseContent>(
|
|
87
|
+
socket: WebSocket,
|
|
88
|
+
data: SockServerResponse<T>,
|
|
89
|
+
) {
|
|
90
|
+
socket.send(JSON.stringify(data));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public dispose() {
|
|
94
|
+
this.wserver.close();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface SockServerResponseConnected extends SockServerResponseContent {
|
|
99
|
+
type: 'connected';
|
|
100
|
+
content: null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface SockServerResponseReload extends SockServerResponseContent {
|
|
104
|
+
type: 'reload';
|
|
105
|
+
content: ReloadTokens;
|
|
106
|
+
}
|
|
107
|
+
export type ReloadTokens =
|
|
108
|
+
| 'RELOAD_CONTENT_SCRIPT'
|
|
109
|
+
| 'RELOAD_CSS'
|
|
110
|
+
| 'RELOAD_SW'
|
|
111
|
+
| 'RELOAD_POPUP_JS'
|
|
112
|
+
| 'RELOAD_POPUP_HTML'
|
|
113
|
+
| 'ALL';
|
|
114
|
+
|
|
115
|
+
export interface SockServerResponse<T extends SockServerResponseContent> {
|
|
116
|
+
type: T['type'];
|
|
117
|
+
content: T['content'];
|
|
118
|
+
}
|
|
119
|
+
export interface SockServerResponseContent {
|
|
120
|
+
type: string;
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
122
|
+
content: any;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface SockServerConsoleRecieved extends SockRecieveContent {
|
|
126
|
+
type: 'console';
|
|
127
|
+
content: {
|
|
128
|
+
type: 'log' | 'warn' | 'error';
|
|
129
|
+
contents: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
type SockServerLisntener<T extends SockRecieveContent> = (msg: SockRecieve<T>) => any;
|
|
135
|
+
export interface SockRecieve<T extends SockRecieveContent> {
|
|
136
|
+
type: T['type'];
|
|
137
|
+
content: T['content'];
|
|
138
|
+
}
|
|
139
|
+
export interface SockRecieveContent {
|
|
140
|
+
type: string;
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
142
|
+
content: any;
|
|
143
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The config for crx monkey.
|
|
3
|
+
*/
|
|
4
|
+
export interface CrxmConfig {
|
|
5
|
+
output?: {
|
|
6
|
+
/**
|
|
7
|
+
* Directory of outputs.
|
|
8
|
+
*/
|
|
9
|
+
chrome?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The path containing the filename of the output userscript.
|
|
12
|
+
*/
|
|
13
|
+
userjs?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The path of manifest.
|
|
17
|
+
*/
|
|
18
|
+
manifest?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Server settings.
|
|
21
|
+
*/
|
|
22
|
+
server?: {
|
|
23
|
+
/**
|
|
24
|
+
* The port of file server.
|
|
25
|
+
*/
|
|
26
|
+
port?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The hostname using by file server and sockserver.
|
|
29
|
+
*/
|
|
30
|
+
host?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The port of websocket
|
|
33
|
+
*/
|
|
34
|
+
websocket?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Disable websocket for reloading in userscript
|
|
37
|
+
*/
|
|
38
|
+
disable_sock_in_userjs?: boolean;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Additional Userscript header
|
|
42
|
+
*/
|
|
43
|
+
header?: UserScriptHeader;
|
|
44
|
+
/**
|
|
45
|
+
* Setting build plugin for any file
|
|
46
|
+
* `Record<File regular expression, Bundler plugin>`
|
|
47
|
+
*/
|
|
48
|
+
build?: Record<string, CrxmBundlerPlugin>;
|
|
49
|
+
/**
|
|
50
|
+
* Setting watch plugin for any file
|
|
51
|
+
* `Record<File regular expression, Bundler plugin>`
|
|
52
|
+
*/
|
|
53
|
+
watch?: Record<string, CrxmBundlerPluginWatch>;
|
|
54
|
+
/**
|
|
55
|
+
* The log level.
|
|
56
|
+
* * `info` Show only infomations.
|
|
57
|
+
* * `error` Show infomations and errors.
|
|
58
|
+
* * `debug` Show all logs dispatched.
|
|
59
|
+
*/
|
|
60
|
+
logLevel?: 'info' | 'error' | 'debug';
|
|
61
|
+
/**
|
|
62
|
+
* A directory copied as it is to `/public` in dist.
|
|
63
|
+
*/
|
|
64
|
+
public?: string | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Define variables to bundled script.
|
|
67
|
+
*/
|
|
68
|
+
define?: {
|
|
69
|
+
sw?: Record<string, string>;
|
|
70
|
+
contentscripts?: Record<string, string>;
|
|
71
|
+
popup?: Record<string, string>;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type DeepRequired<T> = {
|
|
76
|
+
[P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type CrxmConfigRequired = DeepRequired<CrxmConfig>;
|
|
80
|
+
|
|
81
|
+
export type UserScriptHeader = Array<[keyof UserScriptHeaderProps, string]>;
|
|
82
|
+
|
|
83
|
+
export interface UserScriptHeaderProps {
|
|
84
|
+
'@name': string;
|
|
85
|
+
'@namespace'?: string;
|
|
86
|
+
'@copyright'?: string;
|
|
87
|
+
'@version': string;
|
|
88
|
+
'@description'?: string;
|
|
89
|
+
'@icon'?: string;
|
|
90
|
+
'@iconURL'?: string;
|
|
91
|
+
'@defaulticon'?: string;
|
|
92
|
+
'@icon64'?: string;
|
|
93
|
+
'@icon64URL'?: string;
|
|
94
|
+
'@grant'?: string;
|
|
95
|
+
'@author'?: string;
|
|
96
|
+
'@homepage'?: string;
|
|
97
|
+
'@homepageURL'?: string;
|
|
98
|
+
'@website'?: string;
|
|
99
|
+
'@source'?: string;
|
|
100
|
+
'@antifeature'?: string;
|
|
101
|
+
'@require'?: string;
|
|
102
|
+
'@resource'?: string;
|
|
103
|
+
'@include'?: string;
|
|
104
|
+
'@match'?: string;
|
|
105
|
+
'@exclude'?: string;
|
|
106
|
+
'@run-at'?: string;
|
|
107
|
+
'@sandbox'?: string;
|
|
108
|
+
'@connect'?: string;
|
|
109
|
+
'@noframes'?: string;
|
|
110
|
+
'@updateURL'?: string;
|
|
111
|
+
'@downloadURL'?: string;
|
|
112
|
+
'@supportURL'?: string;
|
|
113
|
+
'@webRequest'?: string;
|
|
114
|
+
'@unwrap'?: string;
|
|
115
|
+
[key: string]: string | undefined;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface CrxmManifest extends chrome.runtime.ManifestV3 {
|
|
119
|
+
content_scripts?: CrxmContentScripts;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface CrxmManifestImportantKeys {
|
|
123
|
+
description: string;
|
|
124
|
+
content_scripts: CrxmContentScripts;
|
|
125
|
+
background: { service_worker: string; type: string } | undefined;
|
|
126
|
+
name: string;
|
|
127
|
+
version: string;
|
|
128
|
+
manifest_version: 3;
|
|
129
|
+
action:
|
|
130
|
+
| {
|
|
131
|
+
default_icon:
|
|
132
|
+
| {
|
|
133
|
+
'16'?: string;
|
|
134
|
+
'24'?: string;
|
|
135
|
+
'32'?: string;
|
|
136
|
+
}
|
|
137
|
+
| undefined;
|
|
138
|
+
default_title?: string;
|
|
139
|
+
default_popup?: string;
|
|
140
|
+
}
|
|
141
|
+
| undefined;
|
|
142
|
+
icons: Record<number, string> | undefined;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type CrxmContentScript = {
|
|
146
|
+
matches?: string[] | undefined;
|
|
147
|
+
exclude_matches?: string[] | undefined;
|
|
148
|
+
css?: string[] | undefined;
|
|
149
|
+
js?: string[] | undefined;
|
|
150
|
+
run_at?: 'document_start' | 'document_end' | 'document_idle' | undefined;
|
|
151
|
+
all_frames?: boolean | undefined;
|
|
152
|
+
match_about_blank?: boolean | undefined;
|
|
153
|
+
include_globs?: string[] | undefined;
|
|
154
|
+
exclude_globs?: string[] | undefined;
|
|
155
|
+
world?: 'ISOLATED' | 'MAIN' | undefined;
|
|
156
|
+
|
|
157
|
+
userscript_direct_inject?: boolean;
|
|
158
|
+
trusted_inject?: boolean;
|
|
159
|
+
use_isolated_connection?: boolean;
|
|
160
|
+
[key: string]: unknown;
|
|
161
|
+
};
|
|
162
|
+
export type CrxmContentScripts = Array<CrxmContentScript>;
|
|
163
|
+
|
|
164
|
+
export type CrxmManifestImportantKeyRequired = DeepRequired<CrxmManifestImportantKeys>;
|
|
165
|
+
|
|
166
|
+
export type CrxmManifestRequired = CrxmManifestImportantKeyRequired & chrome.runtime.ManifestV3;
|
|
167
|
+
|
|
168
|
+
export type BuildTarget = {
|
|
169
|
+
hash: string;
|
|
170
|
+
entryPoint: string;
|
|
171
|
+
usingPlugin: {
|
|
172
|
+
build: CrxmBundlerPlugin;
|
|
173
|
+
watch: CrxmBundlerPluginWatch;
|
|
174
|
+
};
|
|
175
|
+
flag: string;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export type ScriptUpdateHandler = (target: BuildTarget) => unknown;
|
|
179
|
+
|
|
180
|
+
export interface I_CrxmBundler {
|
|
181
|
+
compileResults: Record<string, Uint8Array>;
|
|
182
|
+
addTarget(
|
|
183
|
+
entryPoint: string,
|
|
184
|
+
usingPlugin: { build: CrxmBundlerPlugin; watch: CrxmBundlerPluginWatch },
|
|
185
|
+
flag: string,
|
|
186
|
+
): string;
|
|
187
|
+
removeTarget(targetEntryPoint: string): void;
|
|
188
|
+
getInternalHashFromPath(filePath: string, flag: string | null): string;
|
|
189
|
+
getBuildResultFromPath(filePath: string): Uint8Array | undefined;
|
|
190
|
+
build(): Promise<void>;
|
|
191
|
+
compileForce(hash: string): Promise<BuildTarget>;
|
|
192
|
+
watch(): Promise<void>;
|
|
193
|
+
stopWatch(): Promise<void>;
|
|
194
|
+
addListener(handler: ScriptUpdateHandler): void;
|
|
195
|
+
removeListener(handler: ScriptUpdateHandler): void;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Plugin for used when build.
|
|
200
|
+
*/
|
|
201
|
+
export type CrxmBundlerPlugin = {
|
|
202
|
+
name: string;
|
|
203
|
+
plugin: (filepath: string, bundler: I_CrxmBundler) => Promise<Uint8Array>;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Plugin for used when watch.
|
|
207
|
+
*/
|
|
208
|
+
export type CrxmBundlerPluginWatch = {
|
|
209
|
+
name: string;
|
|
210
|
+
plugin: (
|
|
211
|
+
filepath: string,
|
|
212
|
+
sendResult: CrxmResultSender,
|
|
213
|
+
bundler: I_CrxmBundler,
|
|
214
|
+
) => Promise<CrxmBundlerPluginWatcher>;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export type CrxmBundlerPluginWatcher = {
|
|
218
|
+
stop: () => Promise<void>;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export type CrxmResultSender = (result: Uint8Array) => void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* For inversify
|
|
3
|
+
*/
|
|
4
|
+
export const TYPES = {
|
|
5
|
+
ConfigLoader: Symbol.for('I_ConfigLoader'),
|
|
6
|
+
ManifestLoader: Symbol.for('I_ManifestLoader'),
|
|
7
|
+
ManifestParser: Symbol.for('I_ManifestParser'),
|
|
8
|
+
CrxmBundler: Symbol.for('I_CrxmBundler'),
|
|
9
|
+
Watcher: Symbol.for('I_Watcher'),
|
|
10
|
+
BundlerRegisterer: Symbol.for('I_BundlerRegisterer'),
|
|
11
|
+
Distributior: Symbol.for('I_Distributior'),
|
|
12
|
+
ManifestFactory: Symbol.for('I_ManifestFactory'),
|
|
13
|
+
UserscriptBundler: Symbol.for('I_UserscriptBundler'),
|
|
14
|
+
UserscriptHeaderFactory: Symbol.for('I_UserscriptHeaderFactory'),
|
|
15
|
+
UserscriptRegisterer: Symbol.for('I_UserscriptRegisterer'),
|
|
16
|
+
Logger: Symbol.for('I_Logger'),
|
|
17
|
+
SockServer: Symbol.for('I_SockServer'),
|
|
18
|
+
CreateDevClient: Symbol.for('I_CreateDevClient'),
|
|
19
|
+
FileServer: Symbol.for('I_FileServer'),
|
|
20
|
+
|
|
21
|
+
BuildID: Symbol.for('BuildID'),
|
|
22
|
+
CacheDir: Symbol.for('CacheDir'),
|
|
23
|
+
IsWatch: Symbol.for('IsWatch'),
|
|
24
|
+
};
|