@lukaskj/xmonkey 2.2.4 → 2.2.5
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/dist/build.d.ts +1 -0
- package/dist/build.js +205 -0
- package/dist/console-script/console-script.decorator.d.ts +3 -0
- package/dist/console-script/console-script.decorator.js +9 -0
- package/dist/console-script/console-script.interface.d.ts +6 -0
- package/dist/console-script/console-script.interface.js +3 -0
- package/dist/console-script/index.d.ts +2 -0
- package/dist/console-script/index.js +2 -0
- package/dist/esbuild/build.d.ts +1 -0
- package/dist/esbuild/build.js +28 -0
- package/dist/esbuild/plugins/xmonkey-output-stats-plugin.d.ts +2 -0
- package/dist/esbuild/plugins/xmonkey-output-stats-plugin.js +17 -0
- package/dist/esbuild/plugins/xmonkey-strip-metadata-plugin.d.ts +2 -0
- package/dist/esbuild/plugins/xmonkey-strip-metadata-plugin.js +76 -0
- package/dist/esbuild/plugins/xmonkey-styles-plugin.d.ts +2 -0
- package/dist/esbuild/plugins/xmonkey-styles-plugin.js +34 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +29 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +0 -0
- package/dist/styles/_base.scss +3 -0
- package/dist/styles/_colors.scss +13 -0
- package/dist/styles/_utils.scss +82 -0
- package/dist/styles/_variables.scss +10 -0
- package/dist/styles/_xmonkey-wrapper.scss +89 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.js +1 -0
- package/dist/ui-script/index.d.ts +2 -0
- package/dist/ui-script/index.js +2 -0
- package/dist/ui-script/ui-script.decorator.d.ts +3 -0
- package/dist/ui-script/ui-script.decorator.js +19 -0
- package/dist/ui-script/ui-script.interface.d.ts +5 -0
- package/dist/ui-script/ui-script.interface.js +1 -0
- package/dist/utils/get-storage-key-id-from-string.d.ts +1 -0
- package/dist/utils/get-storage-key-id-from-string.js +3 -0
- package/dist/utils/is-null-or-undefined.d.ts +2 -0
- package/dist/utils/is-null-or-undefined.js +4 -0
- package/dist/utils/sleep.d.ts +1 -0
- package/dist/utils/sleep.js +3 -0
- package/dist/x-monkey-window-component.d.ts +7 -0
- package/dist/x-monkey-window-component.js +16 -0
- package/package.json +1 -1
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
+
for (let key of __getOwnPropNames(from))
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
11
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
12
|
+
}
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
16
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
17
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
18
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
19
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
20
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
21
|
+
mod
|
|
22
|
+
));
|
|
23
|
+
|
|
24
|
+
// src/esbuild/build.ts
|
|
25
|
+
var esbuild = __toESM(require("esbuild"));
|
|
26
|
+
var import_esbuild_sass_plugin = require("esbuild-sass-plugin");
|
|
27
|
+
|
|
28
|
+
// src/esbuild/plugins/xmonkey-strip-metadata-plugin.ts
|
|
29
|
+
var import_promises = require("fs/promises");
|
|
30
|
+
var import_json5 = __toESM(require("json5"));
|
|
31
|
+
function xMonkeyStripMetadataPlugin() {
|
|
32
|
+
return {
|
|
33
|
+
name: "xmonkey-strip-metadata-plugin",
|
|
34
|
+
setup(build2) {
|
|
35
|
+
let foundMetadata = false;
|
|
36
|
+
let metadataContent = "";
|
|
37
|
+
build2.onLoad({ filter: /.(ts|tsx)/, namespace: "file" }, async (args) => {
|
|
38
|
+
if (foundMetadata)
|
|
39
|
+
return;
|
|
40
|
+
const source = await (0, import_promises.readFile)(args.path, "utf8");
|
|
41
|
+
const scriptMetadataIndex = source.match(/@(ConsoleScript|UiScript)\(/)?.index;
|
|
42
|
+
if (!scriptMetadataIndex || scriptMetadataIndex < 0)
|
|
43
|
+
return;
|
|
44
|
+
foundMetadata = true;
|
|
45
|
+
const regex = /\@(ConsoleScript|UiScript)\([^\)]*\)(\.[^\)]*\))?/gi;
|
|
46
|
+
const metadataDecoratorMatcher = source.match(regex);
|
|
47
|
+
if (metadataDecoratorMatcher) {
|
|
48
|
+
metadataContent = metadataDecoratorMatcher.at(0);
|
|
49
|
+
const startJsonMetadataIndex = metadataContent.indexOf("{");
|
|
50
|
+
const endJsonMetadataIndex = metadataContent.lastIndexOf("}");
|
|
51
|
+
const metadataJsonString = metadataContent.substring(startJsonMetadataIndex, endJsonMetadataIndex + 1);
|
|
52
|
+
const contents = source.replace(metadataJsonString, "");
|
|
53
|
+
const extension = args.path.split(".").pop();
|
|
54
|
+
const loader = extension === "tsx" ? "tsx" : "ts";
|
|
55
|
+
return { contents, loader };
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
});
|
|
59
|
+
build2.onEnd(async (result) => {
|
|
60
|
+
if (!build2.initialOptions?.outfile || !build2.initialOptions?.bundle) {
|
|
61
|
+
console.error("Wrong build configuration. Options 'bundle' must be enabled and 'outfile' must be set.");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (!foundMetadata) {
|
|
65
|
+
console.error("ScriptMetadata decorator not found.");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (result.errors.length) {
|
|
69
|
+
console.error("Error building. Script Metadata cannot be added to final script.");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const fileContents = await (0, import_promises.readFile)(build2.initialOptions.outfile);
|
|
73
|
+
const scriptMetadataString = getScriptMetadataString(metadataContent);
|
|
74
|
+
await (0, import_promises.writeFile)(build2.initialOptions.outfile, `${scriptMetadataString}
|
|
75
|
+
|
|
76
|
+
${fileContents.toString()}`);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function getScriptMetadataString(scriptMetadataFunctionCallString) {
|
|
82
|
+
scriptMetadataFunctionCallString = scriptMetadataFunctionCallString.trim();
|
|
83
|
+
const startJsonMetadataIndex = scriptMetadataFunctionCallString.indexOf("{");
|
|
84
|
+
const endJsonMetadataIndex = scriptMetadataFunctionCallString.lastIndexOf("}");
|
|
85
|
+
if (startJsonMetadataIndex < 0 || endJsonMetadataIndex < 0) {
|
|
86
|
+
return "";
|
|
87
|
+
}
|
|
88
|
+
const jsonMetadataString = scriptMetadataFunctionCallString.substring(
|
|
89
|
+
startJsonMetadataIndex,
|
|
90
|
+
endJsonMetadataIndex + 1
|
|
91
|
+
);
|
|
92
|
+
const metadataObject = import_json5.default.parse(jsonMetadataString);
|
|
93
|
+
const tag = "// ==UserScript==";
|
|
94
|
+
const tagEnd = "// ==/UserScript==";
|
|
95
|
+
const headersArr = [];
|
|
96
|
+
const spaces = 13;
|
|
97
|
+
for (const key in metadataObject) {
|
|
98
|
+
if (Array.isArray(metadataObject[key])) {
|
|
99
|
+
metadataObject[key].forEach((item) => {
|
|
100
|
+
headersArr.push(`${key.padEnd(spaces, " ")}${item}`);
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
headersArr.push(`${key.padEnd(spaces, " ")}${metadataObject[key]}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const headers = headersArr.map((h) => `// ${h}`).join("\n");
|
|
107
|
+
return `${tag}
|
|
108
|
+
${headers}
|
|
109
|
+
${tagEnd}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/esbuild/plugins/xmonkey-styles-plugin.ts
|
|
113
|
+
var import_promises2 = require("fs/promises");
|
|
114
|
+
function xMonkeyStylesPlugin() {
|
|
115
|
+
return {
|
|
116
|
+
name: "xmonkey-styles-plugin",
|
|
117
|
+
setup(build2) {
|
|
118
|
+
build2.onEnd(async (result) => {
|
|
119
|
+
if (!build2.initialOptions?.outfile || !build2.initialOptions?.bundle) {
|
|
120
|
+
console.error("Wrong build configuration. Options 'bundle' must be enabled and 'outfile' must be set.");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (!result.metafile) {
|
|
124
|
+
console.warn("ESBuild metafile not enabled. Style bundle skipped.");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const outputs = result.metafile.outputs;
|
|
128
|
+
let cssFilePath = "";
|
|
129
|
+
for (const file in outputs) {
|
|
130
|
+
const ext = file.split(".").pop();
|
|
131
|
+
if (ext === "css") {
|
|
132
|
+
cssFilePath = file;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (!cssFilePath.length) {
|
|
137
|
+
console.warn("[-] StyleSheet output skipped.");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const jsOutFile = build2.initialOptions.outfile;
|
|
141
|
+
const cssContents = (await (0, import_promises2.readFile)(cssFilePath)).toString();
|
|
142
|
+
(0, import_promises2.appendFile)(jsOutFile, `
|
|
143
|
+
GM.addStyle("\\
|
|
144
|
+
${cssContents.trim()}\\
|
|
145
|
+
");`);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/esbuild/plugins/xmonkey-output-stats-plugin.ts
|
|
152
|
+
function xMonkeyOutputStatsPlugin() {
|
|
153
|
+
return {
|
|
154
|
+
name: "xmonkey-output-stats-plugin",
|
|
155
|
+
setup(build2) {
|
|
156
|
+
build2.onEnd(async (result) => {
|
|
157
|
+
const outputs = result.metafile?.outputs;
|
|
158
|
+
const outputTotal = Object.keys(outputs).reduce((prev, cur) => prev + outputs[cur].bytes, 0);
|
|
159
|
+
const bundleTotal = humanFileSize(outputTotal);
|
|
160
|
+
console.log("[*] Bundle total:", bundleTotal);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function humanFileSize(size) {
|
|
166
|
+
const i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
|
|
167
|
+
return (size / Math.pow(1024, i)).toFixed(1) + "" + ["b", "kB", "MB", "GB", "TB"][i];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/esbuild/build.ts
|
|
171
|
+
async function buildXmonkeyScript(scriptBasePath) {
|
|
172
|
+
const entryFile2 = scriptBasePath;
|
|
173
|
+
console.info(`Building file: '${entryFile2}'`);
|
|
174
|
+
await esbuild.build({
|
|
175
|
+
entryPoints: [entryFile2],
|
|
176
|
+
outfile: "dist/index.js",
|
|
177
|
+
bundle: true,
|
|
178
|
+
treeShaking: true,
|
|
179
|
+
minify: process.env.DEBUG ? false : true,
|
|
180
|
+
platform: "browser",
|
|
181
|
+
format: "iife",
|
|
182
|
+
// target: "esnext",
|
|
183
|
+
sourcemap: false,
|
|
184
|
+
keepNames: true,
|
|
185
|
+
logLevel: "info",
|
|
186
|
+
metafile: true,
|
|
187
|
+
plugins: [
|
|
188
|
+
xMonkeyStripMetadataPlugin(),
|
|
189
|
+
// xMonkeyDevPlugin(),
|
|
190
|
+
(0, import_esbuild_sass_plugin.sassPlugin)({ style: "compressed" }),
|
|
191
|
+
xMonkeyStylesPlugin(),
|
|
192
|
+
xMonkeyOutputStatsPlugin()
|
|
193
|
+
]
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/build.ts
|
|
198
|
+
var entryFile = process.argv[2];
|
|
199
|
+
if (!entryFile) {
|
|
200
|
+
console.error(`No entryfile specified. Try adding the script to build in the argument.`);
|
|
201
|
+
console.error(`Example: npm run build src/example-script.ts`);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
buildXmonkeyScript(entryFile);
|
|
205
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2VzYnVpbGQvYnVpbGQudHMiLCAiLi4vc3JjL2VzYnVpbGQvcGx1Z2lucy94bW9ua2V5LXN0cmlwLW1ldGFkYXRhLXBsdWdpbi50cyIsICIuLi9zcmMvZXNidWlsZC9wbHVnaW5zL3htb25rZXktc3R5bGVzLXBsdWdpbi50cyIsICIuLi9zcmMvZXNidWlsZC9wbHVnaW5zL3htb25rZXktb3V0cHV0LXN0YXRzLXBsdWdpbi50cyIsICIuLi9zcmMvYnVpbGQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCAqIGFzIGVzYnVpbGQgZnJvbSBcImVzYnVpbGRcIjtcbmltcG9ydCB7IHNhc3NQbHVnaW4gfSBmcm9tIFwiZXNidWlsZC1zYXNzLXBsdWdpblwiO1xuaW1wb3J0IHsgeE1vbmtleVN0cmlwTWV0YWRhdGFQbHVnaW4gfSBmcm9tIFwiLi9wbHVnaW5zL3htb25rZXktc3RyaXAtbWV0YWRhdGEtcGx1Z2luLmpzXCI7XG5pbXBvcnQgeyB4TW9ua2V5U3R5bGVzUGx1Z2luIH0gZnJvbSBcIi4vcGx1Z2lucy94bW9ua2V5LXN0eWxlcy1wbHVnaW4uanNcIjtcbmltcG9ydCB7IHhNb25rZXlPdXRwdXRTdGF0c1BsdWdpbiB9IGZyb20gXCIuL3BsdWdpbnMveG1vbmtleS1vdXRwdXQtc3RhdHMtcGx1Z2luLmpzXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBidWlsZFhtb25rZXlTY3JpcHQoc2NyaXB0QmFzZVBhdGg6IHN0cmluZykge1xuICAvLyBsZXQgZW50cnlGaWxlID0gcHJvY2Vzcy5hcmd2WzJdO1xuICBjb25zdCBlbnRyeUZpbGUgPSBzY3JpcHRCYXNlUGF0aDtcbiAgY29uc29sZS5pbmZvKGBCdWlsZGluZyBmaWxlOiAnJHtlbnRyeUZpbGV9J2ApO1xuXG4gIGF3YWl0IGVzYnVpbGQuYnVpbGQoe1xuICAgIGVudHJ5UG9pbnRzOiBbZW50cnlGaWxlXSxcbiAgICBvdXRmaWxlOiBcImRpc3QvaW5kZXguanNcIixcbiAgICBidW5kbGU6IHRydWUsXG4gICAgdHJlZVNoYWtpbmc6IHRydWUsXG4gICAgbWluaWZ5OiBwcm9jZXNzLmVudi5ERUJVRyA/IGZhbHNlIDogdHJ1ZSxcbiAgICBwbGF0Zm9ybTogXCJicm93c2VyXCIsXG4gICAgZm9ybWF0OiBcImlpZmVcIixcbiAgICAvLyB0YXJnZXQ6IFwiZXNuZXh0XCIsXG4gICAgc291cmNlbWFwOiBmYWxzZSxcbiAgICBrZWVwTmFtZXM6IHRydWUsXG4gICAgbG9nTGV2ZWw6IFwiaW5mb1wiLFxuICAgIG1ldGFmaWxlOiB0cnVlLFxuICAgIHBsdWdpbnM6IFtcbiAgICAgIHhNb25rZXlTdHJpcE1ldGFkYXRhUGx1Z2luKCksXG4gICAgICAvLyB4TW9ua2V5RGV2UGx1Z2luKCksXG4gICAgICBzYXNzUGx1Z2luKHsgc3R5bGU6IFwiY29tcHJlc3NlZFwiIH0pLFxuICAgICAgeE1vbmtleVN0eWxlc1BsdWdpbigpLFxuICAgICAgeE1vbmtleU91dHB1dFN0YXRzUGx1Z2luKCksXG4gICAgXSxcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSBcImVzYnVpbGRcIjtcbmltcG9ydCB7IHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBKU09ONSBmcm9tIFwianNvbjVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHhNb25rZXlTdHJpcE1ldGFkYXRhUGx1Z2luKCk6IFBsdWdpbiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJ4bW9ua2V5LXN0cmlwLW1ldGFkYXRhLXBsdWdpblwiLFxuICAgIHNldHVwKGJ1aWxkKSB7XG4gICAgICBsZXQgZm91bmRNZXRhZGF0YSA9IGZhbHNlO1xuICAgICAgbGV0IG1ldGFkYXRhQ29udGVudCA9IFwiXCI7XG5cbiAgICAgIGJ1aWxkLm9uTG9hZCh7IGZpbHRlcjogLy4odHN8dHN4KS8sIG5hbWVzcGFjZTogXCJmaWxlXCIgfSwgYXN5bmMgKGFyZ3MpID0+IHtcbiAgICAgICAgaWYgKGZvdW5kTWV0YWRhdGEpIHJldHVybjtcbiAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgcmVhZEZpbGUoYXJncy5wYXRoLCBcInV0ZjhcIik7XG4gICAgICAgIGNvbnN0IHNjcmlwdE1ldGFkYXRhSW5kZXggPSBzb3VyY2UubWF0Y2goL0AoQ29uc29sZVNjcmlwdHxVaVNjcmlwdClcXCgvKT8uaW5kZXg7XG5cbiAgICAgICAgaWYgKCFzY3JpcHRNZXRhZGF0YUluZGV4IHx8IHNjcmlwdE1ldGFkYXRhSW5kZXggPCAwKSByZXR1cm47XG4gICAgICAgIGZvdW5kTWV0YWRhdGEgPSB0cnVlO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1lc2NhcGVcbiAgICAgICAgY29uc3QgcmVnZXggPSAvXFxAKENvbnNvbGVTY3JpcHR8VWlTY3JpcHQpXFwoW15cXCldKlxcKShcXC5bXlxcKV0qXFwpKT8vZ2k7XG4gICAgICAgIGNvbnN0IG1ldGFkYXRhRGVjb3JhdG9yTWF0Y2hlciA9IHNvdXJjZS5tYXRjaChyZWdleCk7XG4gICAgICAgIGlmIChtZXRhZGF0YURlY29yYXRvck1hdGNoZXIpIHtcbiAgICAgICAgICBtZXRhZGF0YUNvbnRlbnQgPSBtZXRhZGF0YURlY29yYXRvck1hdGNoZXIuYXQoMCkgYXMgc3RyaW5nO1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwibWV0YWRhdGFDb250ZW50XCIsIG1ldGFkYXRhQ29udGVudCk7XG4gICAgICAgICAgY29uc3Qgc3RhcnRKc29uTWV0YWRhdGFJbmRleCA9IG1ldGFkYXRhQ29udGVudC5pbmRleE9mKFwie1wiKTtcbiAgICAgICAgICBjb25zdCBlbmRKc29uTWV0YWRhdGFJbmRleCA9IG1ldGFkYXRhQ29udGVudC5sYXN0SW5kZXhPZihcIn1cIik7XG4gICAgICAgICAgY29uc3QgbWV0YWRhdGFKc29uU3RyaW5nID0gbWV0YWRhdGFDb250ZW50LnN1YnN0cmluZyhzdGFydEpzb25NZXRhZGF0YUluZGV4LCBlbmRKc29uTWV0YWRhdGFJbmRleCArIDEpO1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnRzID0gc291cmNlLnJlcGxhY2UobWV0YWRhdGFKc29uU3RyaW5nLCBcIlwiKTsgLy8gcmVtb3ZlIHRoZSBqc29uIG1ldGFkYXRhIGZyb20gc291cmNlXG4gICAgICAgICAgLy8gY29uc3QgY29udGVudHMgPSBzb3VyY2UucmVwbGFjZShyZWdleCwgXCJcIik7IC8vIHJlbW92ZSBAQ29uc29sZVNjcmlwdCh7Li4uLn0pIGZyb20gc291cmNlXG5cbiAgICAgICAgICAvLyBjb25zdCBjb250ZW50cyA9IHNvdXJjZS5yZXBsYWNlKHJlZ2V4LCBcIlwiKTtcbiAgICAgICAgICBjb25zdCBleHRlbnNpb24gPSBhcmdzLnBhdGguc3BsaXQoXCIuXCIpLnBvcCgpO1xuXG4gICAgICAgICAgY29uc3QgbG9hZGVyID0gZXh0ZW5zaW9uID09PSBcInRzeFwiID8gXCJ0c3hcIiA6IFwidHNcIjtcblxuICAgICAgICAgIHJldHVybiB7IGNvbnRlbnRzLCBsb2FkZXIgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH0pO1xuXG4gICAgICBidWlsZC5vbkVuZChhc3luYyAocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmICghYnVpbGQuaW5pdGlhbE9wdGlvbnM/Lm91dGZpbGUgfHwgIWJ1aWxkLmluaXRpYWxPcHRpb25zPy5idW5kbGUpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFwiV3JvbmcgYnVpbGQgY29uZmlndXJhdGlvbi4gT3B0aW9ucyAnYnVuZGxlJyBtdXN0IGJlIGVuYWJsZWQgYW5kICdvdXRmaWxlJyBtdXN0IGJlIHNldC5cIik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFmb3VuZE1ldGFkYXRhKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIlNjcmlwdE1ldGFkYXRhIGRlY29yYXRvciBub3QgZm91bmQuXCIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXN1bHQuZXJyb3JzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBidWlsZGluZy4gU2NyaXB0IE1ldGFkYXRhIGNhbm5vdCBiZSBhZGRlZCB0byBmaW5hbCBzY3JpcHQuXCIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpbGVDb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlKGJ1aWxkLmluaXRpYWxPcHRpb25zLm91dGZpbGUpO1xuICAgICAgICBjb25zdCBzY3JpcHRNZXRhZGF0YVN0cmluZyA9IGdldFNjcmlwdE1ldGFkYXRhU3RyaW5nKG1ldGFkYXRhQ29udGVudCk7XG4gICAgICAgIGF3YWl0IHdyaXRlRmlsZShidWlsZC5pbml0aWFsT3B0aW9ucy5vdXRmaWxlLCBgJHtzY3JpcHRNZXRhZGF0YVN0cmluZ31cXG5cXG4ke2ZpbGVDb250ZW50cy50b1N0cmluZygpfWApO1xuICAgICAgfSk7XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NyaXB0TWV0YWRhdGFTdHJpbmcoc2NyaXB0TWV0YWRhdGFGdW5jdGlvbkNhbGxTdHJpbmc6IHN0cmluZykge1xuICBzY3JpcHRNZXRhZGF0YUZ1bmN0aW9uQ2FsbFN0cmluZyA9IHNjcmlwdE1ldGFkYXRhRnVuY3Rpb25DYWxsU3RyaW5nLnRyaW0oKTtcbiAgY29uc3Qgc3RhcnRKc29uTWV0YWRhdGFJbmRleCA9IHNjcmlwdE1ldGFkYXRhRnVuY3Rpb25DYWxsU3RyaW5nLmluZGV4T2YoXCJ7XCIpO1xuICBjb25zdCBlbmRKc29uTWV0YWRhdGFJbmRleCA9IHNjcmlwdE1ldGFkYXRhRnVuY3Rpb25DYWxsU3RyaW5nLmxhc3RJbmRleE9mKFwifVwiKTtcbiAgaWYgKHN0YXJ0SnNvbk1ldGFkYXRhSW5kZXggPCAwIHx8IGVuZEpzb25NZXRhZGF0YUluZGV4IDwgMCkge1xuICAgIHJldHVybiBcIlwiO1xuICB9XG5cbiAgY29uc3QganNvbk1ldGFkYXRhU3RyaW5nID0gc2NyaXB0TWV0YWRhdGFGdW5jdGlvbkNhbGxTdHJpbmcuc3Vic3RyaW5nKFxuICAgIHN0YXJ0SnNvbk1ldGFkYXRhSW5kZXgsXG4gICAgZW5kSnNvbk1ldGFkYXRhSW5kZXggKyAxLFxuICApO1xuXG4gIGNvbnN0IG1ldGFkYXRhT2JqZWN0ID0gSlNPTjUucGFyc2UoanNvbk1ldGFkYXRhU3RyaW5nKTtcblxuICBjb25zdCB0YWcgPSBcIi8vID09VXNlclNjcmlwdD09XCI7XG4gIGNvbnN0IHRhZ0VuZCA9IFwiLy8gPT0vVXNlclNjcmlwdD09XCI7XG4gIGNvbnN0IGhlYWRlcnNBcnIgPSBbXTtcblxuICBjb25zdCBzcGFjZXMgPSAxMztcbiAgZm9yIChjb25zdCBrZXkgaW4gbWV0YWRhdGFPYmplY3QpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhZGF0YU9iamVjdFtrZXldKSkge1xuICAgICAgbWV0YWRhdGFPYmplY3Rba2V5XS5mb3JFYWNoKChpdGVtOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGhlYWRlcnNBcnIucHVzaChgJHtrZXkucGFkRW5kKHNwYWNlcywgXCIgXCIpfSR7aXRlbX1gKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWFkZXJzQXJyLnB1c2goYCR7a2V5LnBhZEVuZChzcGFjZXMsIFwiIFwiKX0ke21ldGFkYXRhT2JqZWN0W2tleV19YCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgaGVhZGVycyA9IGhlYWRlcnNBcnIubWFwKChoKSA9PiBgLy8gJHtofWApLmpvaW4oXCJcXG5cIik7XG4gIHJldHVybiBgJHt0YWd9XFxuJHtoZWFkZXJzfVxcbiR7dGFnRW5kfWA7XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSBcImVzYnVpbGRcIjtcbmltcG9ydCB7IGFwcGVuZEZpbGUsIHJlYWRGaWxlIH0gZnJvbSBcImZzL3Byb21pc2VzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB4TW9ua2V5U3R5bGVzUGx1Z2luKCk6IFBsdWdpbiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJ4bW9ua2V5LXN0eWxlcy1wbHVnaW5cIixcbiAgICBzZXR1cChidWlsZCkge1xuICAgICAgYnVpbGQub25FbmQoYXN5bmMgKHJlc3VsdCkgPT4ge1xuICAgICAgICBpZiAoIWJ1aWxkLmluaXRpYWxPcHRpb25zPy5vdXRmaWxlIHx8ICFidWlsZC5pbml0aWFsT3B0aW9ucz8uYnVuZGxlKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIldyb25nIGJ1aWxkIGNvbmZpZ3VyYXRpb24uIE9wdGlvbnMgJ2J1bmRsZScgbXVzdCBiZSBlbmFibGVkIGFuZCAnb3V0ZmlsZScgbXVzdCBiZSBzZXQuXCIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcmVzdWx0Lm1ldGFmaWxlKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFwiRVNCdWlsZCBtZXRhZmlsZSBub3QgZW5hYmxlZC4gU3R5bGUgYnVuZGxlIHNraXBwZWQuXCIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvdXRwdXRzID0gcmVzdWx0Lm1ldGFmaWxlLm91dHB1dHM7XG4gICAgICAgIGxldCBjc3NGaWxlUGF0aCA9IFwiXCI7XG4gICAgICAgIGZvciAoY29uc3QgZmlsZSBpbiBvdXRwdXRzKSB7XG4gICAgICAgICAgY29uc3QgZXh0ID0gZmlsZS5zcGxpdChcIi5cIikucG9wKCk7XG4gICAgICAgICAgaWYgKGV4dCA9PT0gXCJjc3NcIikge1xuICAgICAgICAgICAgY3NzRmlsZVBhdGggPSBmaWxlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjc3NGaWxlUGF0aC5sZW5ndGgpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXCJbLV0gU3R5bGVTaGVldCBvdXRwdXQgc2tpcHBlZC5cIik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QganNPdXRGaWxlID0gYnVpbGQuaW5pdGlhbE9wdGlvbnMub3V0ZmlsZTtcblxuICAgICAgICBjb25zdCBjc3NDb250ZW50cyA9IChhd2FpdCByZWFkRmlsZShjc3NGaWxlUGF0aCkpLnRvU3RyaW5nKCk7XG4gICAgICAgIGFwcGVuZEZpbGUoanNPdXRGaWxlLCBgXFxuR00uYWRkU3R5bGUoXCJcXFxcXFxuJHtjc3NDb250ZW50cy50cmltKCl9XFxcXFxcblwiKTtgKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSBcImVzYnVpbGRcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHhNb25rZXlPdXRwdXRTdGF0c1BsdWdpbigpOiBQbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IFwieG1vbmtleS1vdXRwdXQtc3RhdHMtcGx1Z2luXCIsXG4gICAgc2V0dXAoYnVpbGQpIHtcbiAgICAgIGJ1aWxkLm9uRW5kKGFzeW5jIChyZXN1bHQpID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgY29uc3Qgb3V0cHV0cyA9IHJlc3VsdC5tZXRhZmlsZT8ub3V0cHV0cyBhcyBhbnk7XG4gICAgICAgIGNvbnN0IG91dHB1dFRvdGFsID0gT2JqZWN0LmtleXMob3V0cHV0cykucmVkdWNlKChwcmV2LCBjdXIpID0+IHByZXYgKyBvdXRwdXRzW2N1cl0uYnl0ZXMsIDApO1xuICAgICAgICBjb25zdCBidW5kbGVUb3RhbCA9IGh1bWFuRmlsZVNpemUob3V0cHV0VG90YWwpO1xuICAgICAgICBjb25zb2xlLmxvZyhcIlsqXSBCdW5kbGUgdG90YWw6XCIsIGJ1bmRsZVRvdGFsKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGh1bWFuRmlsZVNpemUoc2l6ZTogbnVtYmVyKSB7XG4gIGNvbnN0IGkgPSBzaXplID09IDAgPyAwIDogTWF0aC5mbG9vcihNYXRoLmxvZyhzaXplKSAvIE1hdGgubG9nKDEwMjQpKTtcbiAgcmV0dXJuIChzaXplIC8gTWF0aC5wb3coMTAyNCwgaSkpLnRvRml4ZWQoMSkgKyBcIlwiICsgW1wiYlwiLCBcImtCXCIsIFwiTUJcIiwgXCJHQlwiLCBcIlRCXCJdW2ldO1xufVxuIiwgImltcG9ydCB7IGJ1aWxkWG1vbmtleVNjcmlwdCB9IGZyb20gXCIuL2VzYnVpbGQvYnVpbGQuanNcIjtcblxuY29uc3QgZW50cnlGaWxlID0gcHJvY2Vzcy5hcmd2WzJdO1xuXG5pZiAoIWVudHJ5RmlsZSkge1xuICBjb25zb2xlLmVycm9yKGBObyBlbnRyeWZpbGUgc3BlY2lmaWVkLiBUcnkgYWRkaW5nIHRoZSBzY3JpcHQgdG8gYnVpbGQgaW4gdGhlIGFyZ3VtZW50LmApO1xuICBjb25zb2xlLmVycm9yKGBFeGFtcGxlOiBucG0gcnVuIGJ1aWxkIHNyYy9leGFtcGxlLXNjcmlwdC50c2ApO1xuICBwcm9jZXNzLmV4aXQoMSk7XG59XG5cbmJ1aWxkWG1vbmtleVNjcmlwdChlbnRyeUZpbGUpO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsY0FBeUI7QUFDekIsaUNBQTJCOzs7QUNBM0Isc0JBQW9DO0FBQ3BDLG1CQUFrQjtBQUVYLFNBQVMsNkJBQXFDO0FBQ25ELFNBQU87QUFBQSxJQUNMLE1BQU07QUFBQSxJQUNOLE1BQU1BLFFBQU87QUFDWCxVQUFJLGdCQUFnQjtBQUNwQixVQUFJLGtCQUFrQjtBQUV0QixNQUFBQSxPQUFNLE9BQU8sRUFBRSxRQUFRLGFBQWEsV0FBVyxPQUFPLEdBQUcsT0FBTyxTQUFTO0FBQ3ZFLFlBQUk7QUFBZTtBQUNuQixjQUFNLFNBQVMsVUFBTSwwQkFBUyxLQUFLLE1BQU0sTUFBTTtBQUMvQyxjQUFNLHNCQUFzQixPQUFPLE1BQU0sNkJBQTZCLEdBQUc7QUFFekUsWUFBSSxDQUFDLHVCQUF1QixzQkFBc0I7QUFBRztB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QU8sS0FBSyxJQUFJLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFLLE1BQU0sTUFBTSxNQUFNLElBQUksRUFBRSxDQUFDO0FBQ3JGOzs7QUhkQSxlQUFzQixtQkFBbUIsZ0JBQXdCO0FBRS9ELFFBQU1DLGFBQVk7QUFDbEIsVUFBUSxLQUFLLG1CQUFtQkEsVUFBUyxHQUFHO0FBRTVDLFFBQWMsY0FBTTtBQUFBLElBQ2xCLGFBQWEsQ0FBQ0EsVUFBUztBQUFBLElBQ3ZCLFNBQVM7QUFBQSxJQUNULFFBQVE7QUFBQSxJQUNSLGFBQWE7QUFBQSxJQUNiLFFBQVEsUUFBUSxJQUFJLFFBQVEsUUFBUTtBQUFBLElBQ3BDLFVBQVU7QUFBQSxJQUNWLFFBQVE7QUFBQTtBQUFBLElBRVIsV0FBVztBQUFBLElBQ1gsV0FBVztBQUFBLElBQ1gsVUFBVTtBQUFBLElBQ1YsVUFBVTtBQUFBLElBQ1YsU0FBUztBQUFBLE1BQ1AsMkJBQTJCO0FBQUE7QUFBQSxVQUUzQix1Q0FBVyxFQUFFLE9BQU8sYUFBYSxDQUFDO0FBQUEsTUFDbEMsb0JBQW9CO0FBQUEsTUFDcEIseUJBQXlCO0FBQUEsSUFDM0I7QUFBQSxFQUNGLENBQUM7QUFDSDs7O0FJOUJBLElBQU0sWUFBWSxRQUFRLEtBQUssQ0FBQztBQUVoQyxJQUFJLENBQUMsV0FBVztBQUNkLFVBQVEsTUFBTSx5RUFBeUU7QUFDdkYsVUFBUSxNQUFNLDhDQUE4QztBQUM1RCxVQUFRLEtBQUssQ0FBQztBQUNoQjtBQUVBLG1CQUFtQixTQUFTOyIsCiAgIm5hbWVzIjogWyJidWlsZCIsICJKU09ONSIsICJpbXBvcnRfcHJvbWlzZXMiLCAiYnVpbGQiLCAiYnVpbGQiLCAiZW50cnlGaWxlIl0KfQo=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildXmonkeyScript(scriptBasePath: string): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as esbuild from "esbuild";
|
|
2
|
+
import { sassPlugin } from "esbuild-sass-plugin";
|
|
3
|
+
import { xMonkeyStripMetadataPlugin } from "./plugins/xmonkey-strip-metadata-plugin.js";
|
|
4
|
+
import { xMonkeyStylesPlugin } from "./plugins/xmonkey-styles-plugin.js";
|
|
5
|
+
import { xMonkeyOutputStatsPlugin } from "./plugins/xmonkey-output-stats-plugin.js";
|
|
6
|
+
export async function buildXmonkeyScript(scriptBasePath) {
|
|
7
|
+
const entryFile = scriptBasePath;
|
|
8
|
+
console.info(`Building file: '${entryFile}'`);
|
|
9
|
+
await esbuild.build({
|
|
10
|
+
entryPoints: [entryFile],
|
|
11
|
+
outfile: "dist/index.js",
|
|
12
|
+
bundle: true,
|
|
13
|
+
treeShaking: true,
|
|
14
|
+
minify: process.env.DEBUG ? false : true,
|
|
15
|
+
platform: "browser",
|
|
16
|
+
format: "iife",
|
|
17
|
+
sourcemap: false,
|
|
18
|
+
keepNames: true,
|
|
19
|
+
logLevel: "info",
|
|
20
|
+
metafile: true,
|
|
21
|
+
plugins: [
|
|
22
|
+
xMonkeyStripMetadataPlugin(),
|
|
23
|
+
sassPlugin({ style: "compressed" }),
|
|
24
|
+
xMonkeyStylesPlugin(),
|
|
25
|
+
xMonkeyOutputStatsPlugin(),
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function xMonkeyOutputStatsPlugin() {
|
|
2
|
+
return {
|
|
3
|
+
name: "xmonkey-output-stats-plugin",
|
|
4
|
+
setup(build) {
|
|
5
|
+
build.onEnd(async (result) => {
|
|
6
|
+
const outputs = result.metafile?.outputs;
|
|
7
|
+
const outputTotal = Object.keys(outputs).reduce((prev, cur) => prev + outputs[cur].bytes, 0);
|
|
8
|
+
const bundleTotal = humanFileSize(outputTotal);
|
|
9
|
+
console.log("[*] Bundle total:", bundleTotal);
|
|
10
|
+
});
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function humanFileSize(size) {
|
|
15
|
+
const i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
|
|
16
|
+
return (size / Math.pow(1024, i)).toFixed(1) + "" + ["b", "kB", "MB", "GB", "TB"][i];
|
|
17
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { readFile, writeFile } from "fs/promises";
|
|
2
|
+
import JSON5 from "json5";
|
|
3
|
+
export function xMonkeyStripMetadataPlugin() {
|
|
4
|
+
return {
|
|
5
|
+
name: "xmonkey-strip-metadata-plugin",
|
|
6
|
+
setup(build) {
|
|
7
|
+
let foundMetadata = false;
|
|
8
|
+
let metadataContent = "";
|
|
9
|
+
build.onLoad({ filter: /.(ts|tsx)/, namespace: "file" }, async (args) => {
|
|
10
|
+
if (foundMetadata)
|
|
11
|
+
return;
|
|
12
|
+
const source = await readFile(args.path, "utf8");
|
|
13
|
+
const scriptMetadataIndex = source.match(/@(ConsoleScript|UiScript)\(/)?.index;
|
|
14
|
+
if (!scriptMetadataIndex || scriptMetadataIndex < 0)
|
|
15
|
+
return;
|
|
16
|
+
foundMetadata = true;
|
|
17
|
+
const regex = /\@(ConsoleScript|UiScript)\([^\)]*\)(\.[^\)]*\))?/gi;
|
|
18
|
+
const metadataDecoratorMatcher = source.match(regex);
|
|
19
|
+
if (metadataDecoratorMatcher) {
|
|
20
|
+
metadataContent = metadataDecoratorMatcher.at(0);
|
|
21
|
+
const startJsonMetadataIndex = metadataContent.indexOf("{");
|
|
22
|
+
const endJsonMetadataIndex = metadataContent.lastIndexOf("}");
|
|
23
|
+
const metadataJsonString = metadataContent.substring(startJsonMetadataIndex, endJsonMetadataIndex + 1);
|
|
24
|
+
const contents = source.replace(metadataJsonString, "");
|
|
25
|
+
const extension = args.path.split(".").pop();
|
|
26
|
+
const loader = extension === "tsx" ? "tsx" : "ts";
|
|
27
|
+
return { contents, loader };
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
});
|
|
31
|
+
build.onEnd(async (result) => {
|
|
32
|
+
if (!build.initialOptions?.outfile || !build.initialOptions?.bundle) {
|
|
33
|
+
console.error("Wrong build configuration. Options 'bundle' must be enabled and 'outfile' must be set.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!foundMetadata) {
|
|
37
|
+
console.error("ScriptMetadata decorator not found.");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (result.errors.length) {
|
|
41
|
+
console.error("Error building. Script Metadata cannot be added to final script.");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const fileContents = await readFile(build.initialOptions.outfile);
|
|
45
|
+
const scriptMetadataString = getScriptMetadataString(metadataContent);
|
|
46
|
+
await writeFile(build.initialOptions.outfile, `${scriptMetadataString}\n\n${fileContents.toString()}`);
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function getScriptMetadataString(scriptMetadataFunctionCallString) {
|
|
52
|
+
scriptMetadataFunctionCallString = scriptMetadataFunctionCallString.trim();
|
|
53
|
+
const startJsonMetadataIndex = scriptMetadataFunctionCallString.indexOf("{");
|
|
54
|
+
const endJsonMetadataIndex = scriptMetadataFunctionCallString.lastIndexOf("}");
|
|
55
|
+
if (startJsonMetadataIndex < 0 || endJsonMetadataIndex < 0) {
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
const jsonMetadataString = scriptMetadataFunctionCallString.substring(startJsonMetadataIndex, endJsonMetadataIndex + 1);
|
|
59
|
+
const metadataObject = JSON5.parse(jsonMetadataString);
|
|
60
|
+
const tag = "// ==UserScript==";
|
|
61
|
+
const tagEnd = "// ==/UserScript==";
|
|
62
|
+
const headersArr = [];
|
|
63
|
+
const spaces = 13;
|
|
64
|
+
for (const key in metadataObject) {
|
|
65
|
+
if (Array.isArray(metadataObject[key])) {
|
|
66
|
+
metadataObject[key].forEach((item) => {
|
|
67
|
+
headersArr.push(`${key.padEnd(spaces, " ")}${item}`);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
headersArr.push(`${key.padEnd(spaces, " ")}${metadataObject[key]}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const headers = headersArr.map((h) => `// ${h}`).join("\n");
|
|
75
|
+
return `${tag}\n${headers}\n${tagEnd}`;
|
|
76
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { appendFile, readFile } from "fs/promises";
|
|
2
|
+
export function xMonkeyStylesPlugin() {
|
|
3
|
+
return {
|
|
4
|
+
name: "xmonkey-styles-plugin",
|
|
5
|
+
setup(build) {
|
|
6
|
+
build.onEnd(async (result) => {
|
|
7
|
+
if (!build.initialOptions?.outfile || !build.initialOptions?.bundle) {
|
|
8
|
+
console.error("Wrong build configuration. Options 'bundle' must be enabled and 'outfile' must be set.");
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (!result.metafile) {
|
|
12
|
+
console.warn("ESBuild metafile not enabled. Style bundle skipped.");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const outputs = result.metafile.outputs;
|
|
16
|
+
let cssFilePath = "";
|
|
17
|
+
for (const file in outputs) {
|
|
18
|
+
const ext = file.split(".").pop();
|
|
19
|
+
if (ext === "css") {
|
|
20
|
+
cssFilePath = file;
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!cssFilePath.length) {
|
|
25
|
+
console.warn("[-] StyleSheet output skipped.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const jsOutFile = build.initialOptions.outfile;
|
|
29
|
+
const cssContents = (await readFile(cssFilePath)).toString();
|
|
30
|
+
appendFile(jsOutFile, `\nGM.addStyle("\\\n${cssContents.trim()}\\\n");`);
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCallback, useState, useEffect } from "preact/hooks";
|
|
2
|
+
export function useLocalStorage(key, defaultValue) {
|
|
3
|
+
return useStorage(key, defaultValue, window.localStorage);
|
|
4
|
+
}
|
|
5
|
+
export function useSessionStorage(key, defaultValue) {
|
|
6
|
+
return useStorage(key, defaultValue, window.sessionStorage);
|
|
7
|
+
}
|
|
8
|
+
function useStorage(key, defaultValue, storageObject) {
|
|
9
|
+
const [value, setValue] = useState(() => {
|
|
10
|
+
const jsonValue = storageObject.getItem(key);
|
|
11
|
+
if (jsonValue != null)
|
|
12
|
+
return JSON.parse(jsonValue);
|
|
13
|
+
if (typeof defaultValue === "function") {
|
|
14
|
+
return defaultValue();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
return defaultValue;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (value === undefined)
|
|
22
|
+
return storageObject.removeItem(key);
|
|
23
|
+
storageObject.setItem(key, JSON.stringify(value));
|
|
24
|
+
}, [key, value, storageObject]);
|
|
25
|
+
const remove = useCallback(() => {
|
|
26
|
+
setValue(undefined);
|
|
27
|
+
}, []);
|
|
28
|
+
return [value, setValue, remove];
|
|
29
|
+
}
|
package/dist/index.d.ts
ADDED
|
File without changes
|
package/dist/index.js
ADDED
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* https://gist.github.com/jonsuh/b2347347480105874cda110b2afc53f4 */
|
|
2
|
+
/* Flexbox
|
|
3
|
+
// ================================================== */
|
|
4
|
+
|
|
5
|
+
@use "variables" as vars;
|
|
6
|
+
##{vars.$xmonkey-wrapper} {
|
|
7
|
+
.d-f { display: flex !important; flex-direction: column; }
|
|
8
|
+
.d-if { display: inline-flex !important; flex-direction: column; }
|
|
9
|
+
|
|
10
|
+
/* Flex direction */
|
|
11
|
+
.fd-r { flex-direction: row; } /* Default */
|
|
12
|
+
.fd-rr { flex-direction: row-reverse; }
|
|
13
|
+
.fd-c { flex-direction: column; }
|
|
14
|
+
.fd-cr { flex-direction: column-reverse; }
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/* Flex wrap */
|
|
18
|
+
.fw-n { flex-wrap: nowrap; } /* Default */
|
|
19
|
+
.fw-w { flex-wrap: wrap; }
|
|
20
|
+
.fw-wr { flex-wrap: wrap-reverse; }
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/* Justify content */
|
|
24
|
+
.jc-fe { justify-content: flex-end; }
|
|
25
|
+
.jc-fs { justify-content: flex-start; } /* Default */
|
|
26
|
+
.jc-c { justify-content: center; }
|
|
27
|
+
.jc-sa { justify-content: space-around; }
|
|
28
|
+
.jc-sb { justify-content: space-between; }
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/* Align items */
|
|
32
|
+
.ai-fs { align-items: flex-start; }
|
|
33
|
+
.ai-c { align-items: center; }
|
|
34
|
+
.ai-fe { align-items: flex-end; }
|
|
35
|
+
.ai-s { align-items: stretch; } /* Default */
|
|
36
|
+
.ai-b { align-items: baseline; }
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
/* Flex grow */
|
|
40
|
+
.fg-0 { flex-grow: 0; } /* Default */
|
|
41
|
+
.fg-1 { flex-grow: 1; }
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/* Flex shrink */
|
|
45
|
+
.fs-0 { flex-shrink: 0; }
|
|
46
|
+
.fs-1 { flex-shrink: 1; } /* Default */
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/* Flex basis */
|
|
50
|
+
.fb-a { flex-basis: auto; } /* Default */
|
|
51
|
+
.fb-0 { flex-basis: 0; }
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
/* Align self */
|
|
55
|
+
.as-a { align-self: auto; } /* Default */
|
|
56
|
+
.as-fs { align-self: flex-start; }
|
|
57
|
+
.as-c { align-self: center; }
|
|
58
|
+
.as-fe { align-self: flex-end; }
|
|
59
|
+
.as-s { align-self: stretch; }
|
|
60
|
+
.as-b { align-self: baseline }
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
.noselect {
|
|
64
|
+
-webkit-touch-callout: none; /* iOS Safari */
|
|
65
|
+
-webkit-user-select: none; /* Safari */
|
|
66
|
+
-khtml-user-select: none; /* Konqueror HTML */
|
|
67
|
+
-moz-user-select: none; /* Old versions of Firefox */
|
|
68
|
+
-ms-user-select: none; /* Internet Explorer/Edge */
|
|
69
|
+
user-select: none; /* Non-prefixed version, currently
|
|
70
|
+
supported by Chrome, Edge, Opera and Firefox */
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.hidden {display: none !important;}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
.w-10 { width: 10% }
|
|
78
|
+
.w-25 { width: 25% }
|
|
79
|
+
.w-50 { width: 50% }
|
|
80
|
+
.w-75 { width: 75% }
|
|
81
|
+
.w-100 { width: 100% }
|
|
82
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
@use "variables" as vars;
|
|
2
|
+
@use "colors";
|
|
3
|
+
|
|
4
|
+
##{vars.$xmonkey-wrapper} {
|
|
5
|
+
min-width: 200px;
|
|
6
|
+
width: 200px;
|
|
7
|
+
position: absolute;
|
|
8
|
+
top: 10px;
|
|
9
|
+
left: 10px;
|
|
10
|
+
background-color: rgba(colors.$bg, 0.99);
|
|
11
|
+
border-radius: vars.$border-radius;
|
|
12
|
+
z-index: 999999;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
|
|
15
|
+
font-family: vars.$font-family;
|
|
16
|
+
font-size: 12px;
|
|
17
|
+
* {
|
|
18
|
+
box-sizing: initial !important;
|
|
19
|
+
font-size: 12px;
|
|
20
|
+
font-family: vars.$font-family;
|
|
21
|
+
color: colors.$white;
|
|
22
|
+
button {
|
|
23
|
+
color: colors.$black;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
pre {
|
|
27
|
+
overflow: auto;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
input,
|
|
31
|
+
select,
|
|
32
|
+
option,
|
|
33
|
+
textarea {
|
|
34
|
+
color: colors.$bg;
|
|
35
|
+
background-color: colors.$white !important;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
input[type="checkbox"] {
|
|
39
|
+
margin-left: 2px;
|
|
40
|
+
margin-right: 2px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
transition:
|
|
44
|
+
height 100ms ease-in-out,
|
|
45
|
+
width 100ms ease-in-out,
|
|
46
|
+
min-width 100ms ease-in-out,
|
|
47
|
+
min-height 100ms ease-in-out,
|
|
48
|
+
max-height 100ms ease-in-out,
|
|
49
|
+
max-width 100ms ease-in-out;
|
|
50
|
+
|
|
51
|
+
&:has(.minim) {
|
|
52
|
+
min-height: 15px !important;
|
|
53
|
+
min-width: 15px !important;
|
|
54
|
+
width: 15px !important;
|
|
55
|
+
height: 15px !important;
|
|
56
|
+
overflow: hidden !important;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.#{vars.$xmonkey-container} {
|
|
60
|
+
max-height: 1000px;
|
|
61
|
+
&:has(.#{vars.$xmonkey-header}) {
|
|
62
|
+
margin-top: 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.#{vars.$xmonkey-body} {
|
|
67
|
+
padding: 3px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.#{vars.$xmonkey-header} {
|
|
71
|
+
height: 15px;
|
|
72
|
+
line-height: 15px !important;
|
|
73
|
+
background-color: colors.$primary;
|
|
74
|
+
width: 100%;
|
|
75
|
+
// border-top-left-radius: vars.$border-radius;
|
|
76
|
+
// border-top-right-radius: vars.$border-radius;
|
|
77
|
+
.xmwr-x {
|
|
78
|
+
font-family: monospace !important;
|
|
79
|
+
cursor: pointer;
|
|
80
|
+
position: absolute;
|
|
81
|
+
right: 0px;
|
|
82
|
+
top: 0px;
|
|
83
|
+
font-weight: bold;
|
|
84
|
+
background-color: colors.$black;
|
|
85
|
+
padding: 0 5px;
|
|
86
|
+
height: 15px;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type ScriptInfo = {
|
|
2
|
+
"@name": string;
|
|
3
|
+
"@namespace": string;
|
|
4
|
+
"@match": string | string[];
|
|
5
|
+
"@version": string;
|
|
6
|
+
"@author": string;
|
|
7
|
+
"@description": string;
|
|
8
|
+
"@grant"?: string[];
|
|
9
|
+
[k: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
export type NonFunctionPropertyNames<T> = {
|
|
12
|
+
[K in keyof T]: T[K] extends Function ? never : K;
|
|
13
|
+
}[keyof T];
|
|
14
|
+
export type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;
|
|
15
|
+
export type FunctionPropertyNames<T> = {
|
|
16
|
+
[K in keyof T]: T[K] extends Function ? K : never;
|
|
17
|
+
}[keyof T];
|
|
18
|
+
export type ClassConstructor<T> = {
|
|
19
|
+
new (..._: any[]): T;
|
|
20
|
+
};
|
|
21
|
+
export type Self<T> = ClassConstructor<T>;
|
|
22
|
+
export type AnyObject = {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
};
|
|
25
|
+
export type AnyType = string | number | boolean | AnyObject;
|
|
26
|
+
export type WithRequired<T, K extends keyof T> = T & {
|
|
27
|
+
[P in K]-?: T[P];
|
|
28
|
+
};
|
|
29
|
+
export type Complete<T> = {
|
|
30
|
+
[P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : T[P] | undefined;
|
|
31
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { h, render } from "preact";
|
|
2
|
+
import { XMonkeyWindowComponent } from "../x-monkey-window-component.js";
|
|
3
|
+
export function UiScript(_metadata) {
|
|
4
|
+
return function (_target) {
|
|
5
|
+
const scriptObject = new _target();
|
|
6
|
+
const rootComponent = xMonkeyWrapperElement();
|
|
7
|
+
render(h(XMonkeyWindowComponent, { title: scriptObject.title ?? "" }, scriptObject.render()), rootComponent);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function xMonkeyWrapperElement() {
|
|
11
|
+
const ID = "__xmwr";
|
|
12
|
+
let div = document.getElementById(ID);
|
|
13
|
+
if (div)
|
|
14
|
+
return div;
|
|
15
|
+
div = document.createElement("div");
|
|
16
|
+
div.id = ID;
|
|
17
|
+
document.body.appendChild(div);
|
|
18
|
+
return div;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getStorageKeyIdFromString(data: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { useSessionStorage } from "./hooks";
|
|
3
|
+
import { useMemo } from "preact/hooks";
|
|
4
|
+
import { getStorageKeyIdFromString } from "./utils/get-storage-key-id-from-string";
|
|
5
|
+
export function XMonkeyWindowComponent(props) {
|
|
6
|
+
const storageKey = useMemo(() => getStorageKeyIdFromString(props.title), [props.title]);
|
|
7
|
+
const [minimized, setMinimized] = useSessionStorage(storageKey, false);
|
|
8
|
+
function toggleMinimize() {
|
|
9
|
+
setMinimized(!minimized);
|
|
10
|
+
}
|
|
11
|
+
return (_jsxs("div", { className: `xmwr_c d-f fd-c ai-c jc-sb` + (minimized ? " minim" : ""), children: [_jsxs("div", { className: "xmwr-h w-100 m0 d-f fd-r jc-c bg-primary noselect", children: [_jsx("div", { className: "xmwr-title m0", children: props.title }), _jsx(MinimizeButton, { toggleMinimize: toggleMinimize, minimized: minimized })] }), _jsx("div", { className: "xmwr-b w-100 d-f jc-c", children: props.children })] }));
|
|
12
|
+
}
|
|
13
|
+
function MinimizeButton({ minimized, toggleMinimize }) {
|
|
14
|
+
const minimizeChar = minimized ? "+" : "-";
|
|
15
|
+
return (_jsx("div", { className: "xmwr-x m0", onClick: () => toggleMinimize(), children: minimizeChar }));
|
|
16
|
+
}
|