vite-userscript-plugin 2.2.0 → 2.3.0
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/README.md +1 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.js +54 -24
- package/package.json +4 -7
package/README.md
CHANGED
|
@@ -135,7 +135,7 @@ See [examples/sourcemap](./examples/sourcemap).
|
|
|
135
135
|
| `entry` | — | Userscript entry. Required. |
|
|
136
136
|
| `header` | — | Metablock. Required: `name`, `version`, `match`. Relative `icon` / `require` / `resource` / `supportURL` / `updateURL` / `downloadURL` join `homepage` (`homepageURL` / `website` / `source`). Absolute `http(s):` URLs stay as-is. |
|
|
137
137
|
| `fileName` | sanitized `header.name` | Output base name (`{fileName}.user.js`). |
|
|
138
|
-
| `server.open` | `false` | Open the install target when Vite starts. HMR: `.dev.user.js`. `file`: `.user.js` URL. |
|
|
138
|
+
| `server.open` | `false` | Open the install target when Vite starts (`true`, `'user'`, `'proxy'`). HMR: `.dev.user.js`. `file`: `.user.js` or `.proxy.user.js`. Vite opens one URL. |
|
|
139
139
|
| `server.prefix` | `'server:'` | Prefix for `@name` in serve mode. `false` disables it. |
|
|
140
140
|
| `server.file` | `false` | Watch-build `{fileName}.user.js` + `{fileName}.js` + `{fileName}.proxy.user.js`. Install `.user.js` (or the proxy if `file://` `@require` works). No HMR. |
|
|
141
141
|
| `headerAlign` | `1` | Extra spaces after the longest `@key`. `false` — one space. |
|
package/dist/index.d.ts
CHANGED
|
@@ -144,14 +144,17 @@ type HeaderConfig = {
|
|
|
144
144
|
*/
|
|
145
145
|
'unwrap'?: boolean;
|
|
146
146
|
};
|
|
147
|
+
type ServerOpen = boolean | 'user' | 'proxy';
|
|
148
|
+
type ResolvedServerOpen = false | 'dev' | 'user' | 'proxy';
|
|
147
149
|
interface ServerConfig {
|
|
148
150
|
/**
|
|
149
151
|
* Open the install target when Vite starts.
|
|
150
|
-
* HMR
|
|
152
|
+
* `true`: HMR → `.dev.user.js`; `file` → `{fileName}.user.js`.
|
|
153
|
+
* `'user'` / `'proxy'`: file-mode install URL. Vite opens one path.
|
|
151
154
|
*
|
|
152
155
|
* @default false
|
|
153
156
|
*/
|
|
154
|
-
open?:
|
|
157
|
+
open?: ServerOpen;
|
|
155
158
|
/**
|
|
156
159
|
* Prefix applied to `@name` in serve mode.
|
|
157
160
|
* Set `false` to disable.
|
|
@@ -229,7 +232,7 @@ interface ResolvedScript {
|
|
|
229
232
|
iifeName: string;
|
|
230
233
|
header: HeaderConfig;
|
|
231
234
|
server: {
|
|
232
|
-
open:
|
|
235
|
+
open: ResolvedServerOpen;
|
|
233
236
|
prefix: string | false;
|
|
234
237
|
file: boolean;
|
|
235
238
|
};
|
|
@@ -242,4 +245,4 @@ interface ResolvedScript {
|
|
|
242
245
|
//#region src/plugin.d.ts
|
|
243
246
|
declare function UserscriptPlugin(config: UserscriptPluginConfig): Plugin[];
|
|
244
247
|
//#endregion
|
|
245
|
-
export { type HeaderConfig, type HeaderGenerateContext, type ResolvedScript, type ServerConfig, type UserscriptConfig, type UserscriptPluginConfig, UserscriptPlugin as default };
|
|
248
|
+
export { type HeaderConfig, type HeaderGenerateContext, type ResolvedScript, type ResolvedServerOpen, type ServerConfig, type ServerOpen, type UserscriptConfig, type UserscriptPluginConfig, UserscriptPlugin as default };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import { Buffer } from "node:buffer";
|
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
6
6
|
import { styleText } from "node:util";
|
|
7
|
-
import openLink from "open";
|
|
8
7
|
//#region src/grants/catalog.ts
|
|
9
8
|
const GM = [
|
|
10
9
|
"setValue",
|
|
@@ -639,19 +638,25 @@ function assertHeader(header, label) {
|
|
|
639
638
|
"match"
|
|
640
639
|
]) if (isEmptyHeaderField(header[field])) throw new Error(`[${PLUGIN_NAME}] ${label} is missing required header.${field}`);
|
|
641
640
|
}
|
|
641
|
+
function resolveServerOpen(open, file) {
|
|
642
|
+
if (!open) return false;
|
|
643
|
+
if (open === true) return file ? "user" : "dev";
|
|
644
|
+
return file ? open : "dev";
|
|
645
|
+
}
|
|
642
646
|
function toResolvedScript(config) {
|
|
643
647
|
if (!config.entry) throw new Error(`[${PLUGIN_NAME}] Provide an "entry" for each userscript`);
|
|
644
648
|
assertHeader(config.header ?? {}, config.entry);
|
|
645
649
|
const fileName = sanitizeFileName(config.fileName ?? config.header.name);
|
|
650
|
+
const file = config.server?.file ?? false;
|
|
646
651
|
return {
|
|
647
652
|
entry: config.entry,
|
|
648
653
|
fileName,
|
|
649
654
|
iifeName: toIdentifier(fileName),
|
|
650
655
|
header: config.header,
|
|
651
656
|
server: {
|
|
652
|
-
open: config.server?.open
|
|
657
|
+
open: resolveServerOpen(config.server?.open, file),
|
|
653
658
|
prefix: config.server?.prefix ?? "server:",
|
|
654
|
-
file
|
|
659
|
+
file
|
|
655
660
|
},
|
|
656
661
|
headerAlign: config.headerAlign ?? 1,
|
|
657
662
|
generate: config.generate,
|
|
@@ -678,8 +683,23 @@ function collectHomepageRelativeUrlWarnings(config) {
|
|
|
678
683
|
}
|
|
679
684
|
return warnings;
|
|
680
685
|
}
|
|
681
|
-
function
|
|
682
|
-
|
|
686
|
+
function collectServerOpenWarnings(config, input) {
|
|
687
|
+
const warnings = [];
|
|
688
|
+
const items = Array.isArray(input) ? input : [input];
|
|
689
|
+
for (const [index, script] of config.scripts.entries()) {
|
|
690
|
+
const open = items[index]?.server?.open;
|
|
691
|
+
if ((open === "user" || open === "proxy") && !script.server.file) warnings.push(`[${PLUGIN_NAME}] server.open: "${open}" requires server.file for "${script.fileName}" — opening .dev.user.js instead`);
|
|
692
|
+
}
|
|
693
|
+
const opened = config.scripts.filter((script) => script.server.open);
|
|
694
|
+
if (opened.length > 1) warnings.push(`[${PLUGIN_NAME}] server.open is set on multiple scripts; Vite opens only "${opened[0]?.fileName}"`);
|
|
695
|
+
return warnings;
|
|
696
|
+
}
|
|
697
|
+
function collectConfigWarnings(config, input) {
|
|
698
|
+
return [
|
|
699
|
+
...collectAutoMetaUrlsWarnings(config),
|
|
700
|
+
...collectHomepageRelativeUrlWarnings(config),
|
|
701
|
+
...collectServerOpenWarnings(config, input)
|
|
702
|
+
];
|
|
683
703
|
}
|
|
684
704
|
function resolvePluginConfig(config) {
|
|
685
705
|
const items = Array.isArray(config) ? config : [config];
|
|
@@ -717,16 +737,24 @@ function shimModule(code, id) {
|
|
|
717
737
|
}
|
|
718
738
|
//#endregion
|
|
719
739
|
//#region src/serve/logger.ts
|
|
740
|
+
const INSTALL_LABEL_WIDTH = 10;
|
|
741
|
+
function colonPadFor(label) {
|
|
742
|
+
return " ".repeat(Math.max(0, INSTALL_LABEL_WIDTH - label.length) + 1);
|
|
743
|
+
}
|
|
744
|
+
function formatLabeledLine(label, value) {
|
|
745
|
+
return ` ${styleText("green", "➜")} ${styleText("bold", label)}:${colonPadFor(label)}${value}`;
|
|
746
|
+
}
|
|
747
|
+
function alignViteUrlLine(message) {
|
|
748
|
+
return message.replace(/(Local(?:\u001B\[[0-9;]*m)*:)(\s+)/, (_match, prefix) => `${prefix}${colonPadFor("Local")}`);
|
|
749
|
+
}
|
|
720
750
|
function formatInstallLine(installUrl, label = "Userscript") {
|
|
721
|
-
|
|
722
|
-
const padded = label.padEnd(10);
|
|
723
|
-
return ` ${styleText("green", "➜")} ${styleText("bold", padded)}: ${coloredUrl}`;
|
|
751
|
+
return formatLabeledLine(label, styleText("cyan", installUrl.replace(/:(\d+)\//, (_match, port) => `:${styleText("bold", port)}/`)));
|
|
724
752
|
}
|
|
725
753
|
function formatRebuildLine(elapsedMs) {
|
|
726
754
|
return `${styleText("green", "Userscript rebuilt")} ${styleText("dim", `(${elapsedMs}ms)`)}`;
|
|
727
755
|
}
|
|
728
756
|
function formatFaqHint() {
|
|
729
|
-
return `${
|
|
757
|
+
return `${formatLabeledLine("FAQ", styleText("cyan", FAQ_URL))}\n`;
|
|
730
758
|
}
|
|
731
759
|
function stripAnsi(text) {
|
|
732
760
|
return text.replace(/\u001B\[[0-9;]*m/g, "");
|
|
@@ -744,7 +772,7 @@ function createAfterLocalLogger(info, localCount, onAfterLocal) {
|
|
|
744
772
|
};
|
|
745
773
|
return {
|
|
746
774
|
info: (msg, options) => {
|
|
747
|
-
info(msg, options);
|
|
775
|
+
info(typeof msg === "string" ? alignViteUrlLine(msg) : msg, options);
|
|
748
776
|
if (remaining > 0 && isViteLocalUrlLine(String(msg))) {
|
|
749
777
|
remaining -= 1;
|
|
750
778
|
if (remaining === 0) flush();
|
|
@@ -793,13 +821,18 @@ function matchProxyUserscript(url, fileName) {
|
|
|
793
821
|
function matchFileUserscript(url, fileName) {
|
|
794
822
|
return (url.split("?")[0] ?? "") === `/${fileName}.user.js`;
|
|
795
823
|
}
|
|
796
|
-
function
|
|
797
|
-
|
|
824
|
+
function toInstallFileName(fileName, kind) {
|
|
825
|
+
return {
|
|
798
826
|
dev: `${fileName}.dev.user.js`,
|
|
799
827
|
proxy: toProxyFileName(fileName),
|
|
800
828
|
user: `${fileName}.user.js`
|
|
801
|
-
};
|
|
802
|
-
|
|
829
|
+
}[kind];
|
|
830
|
+
}
|
|
831
|
+
function toInstallPath(fileName, kind = "dev") {
|
|
832
|
+
return `/${toInstallFileName(fileName, kind)}`;
|
|
833
|
+
}
|
|
834
|
+
function toInstallUrl(origin, fileName, kind = "dev") {
|
|
835
|
+
return `${origin.replace(/\/$/, "")}${toInstallPath(fileName, kind)}`;
|
|
803
836
|
}
|
|
804
837
|
function toServeEntryPath(root, entry) {
|
|
805
838
|
const absolute = resolve(root, entry);
|
|
@@ -959,14 +992,6 @@ function configureDevServer(server, resolved, reactPreamble) {
|
|
|
959
992
|
logger.flush();
|
|
960
993
|
}
|
|
961
994
|
};
|
|
962
|
-
server.httpServer?.once("listening", () => {
|
|
963
|
-
const toOpen = resolved.scripts.filter((script) => script.server.open);
|
|
964
|
-
if (!toOpen.length) return;
|
|
965
|
-
queueMicrotask(() => {
|
|
966
|
-
const origin = resolveServerOrigin(server.resolvedUrls);
|
|
967
|
-
for (const script of toOpen) openLink(toInstallUrl(origin, script.fileName, script.server.file ? "user" : "dev"));
|
|
968
|
-
});
|
|
969
|
-
});
|
|
970
995
|
}
|
|
971
996
|
//#endregion
|
|
972
997
|
//#region src/plugin.ts
|
|
@@ -1053,13 +1078,18 @@ function UserscriptPlugin(config) {
|
|
|
1053
1078
|
userConfig.build.rolldownOptions.input = input;
|
|
1054
1079
|
const userOutput = userConfig.build.rolldownOptions.output;
|
|
1055
1080
|
const userEntryFileNames = userOutput && !Array.isArray(userOutput) ? userOutput.entryFileNames : void 0;
|
|
1081
|
+
const openScript = resolved.scripts.find((script) => script.server.open);
|
|
1082
|
+
const openPath = openScript?.server.open ? toInstallPath(openScript.fileName, openScript.server.open) : void 0;
|
|
1056
1083
|
return {
|
|
1057
1084
|
appType: userConfig.appType ?? (hasHtml ? "spa" : "custom"),
|
|
1058
1085
|
optimizeDeps: {
|
|
1059
1086
|
entries: Object.values(input),
|
|
1060
1087
|
exclude: [VIRTUAL_MODULE_ID]
|
|
1061
1088
|
},
|
|
1062
|
-
server: {
|
|
1089
|
+
server: {
|
|
1090
|
+
cors: userConfig.server?.cors ?? true,
|
|
1091
|
+
...openPath ? { open: openPath } : {}
|
|
1092
|
+
},
|
|
1063
1093
|
build: {
|
|
1064
1094
|
minify: userConfig.build?.minify ?? false,
|
|
1065
1095
|
assetsInlineLimit: userConfig.build?.assetsInlineLimit ?? Number.MAX_SAFE_INTEGER,
|
|
@@ -1082,7 +1112,7 @@ function UserscriptPlugin(config) {
|
|
|
1082
1112
|
command = viteConfig.command;
|
|
1083
1113
|
resolved = absolutizeEntries(resolved, viteConfig.root);
|
|
1084
1114
|
reactPreamble = hasReactRefreshPlugin(viteConfig.plugins);
|
|
1085
|
-
for (const message of collectConfigWarnings(resolved)) viteConfig.logger.warn(message);
|
|
1115
|
+
for (const message of collectConfigWarnings(resolved, config)) viteConfig.logger.warn(message);
|
|
1086
1116
|
}
|
|
1087
1117
|
},
|
|
1088
1118
|
{
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-userscript-plugin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Vitalij Ryndin",
|
|
7
7
|
"url": "https://github.com/crashmax-dev"
|
|
@@ -41,9 +41,6 @@
|
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"vite": "^8.0.0"
|
|
43
43
|
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"open": "11.0.1"
|
|
46
|
-
},
|
|
47
44
|
"devDependencies": {
|
|
48
45
|
"@antfu/eslint-config": "7.2.0",
|
|
49
46
|
"@sveltejs/vite-plugin-svelte": "7.3.0",
|
|
@@ -54,13 +51,13 @@
|
|
|
54
51
|
"eslint": "9.39.2",
|
|
55
52
|
"eslint-plugin-format": "2.0.1",
|
|
56
53
|
"prettier-plugin-css-order": "2.2.0",
|
|
57
|
-
"svelte": "5.
|
|
54
|
+
"svelte": "5.57.0",
|
|
58
55
|
"tsdown": "0.22.14",
|
|
59
|
-
"turbo": "2.10.
|
|
56
|
+
"turbo": "2.10.12",
|
|
60
57
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
61
58
|
"vite": "8.2.2",
|
|
62
59
|
"vitest": "4.1.11",
|
|
63
|
-
"vue": "3.5.
|
|
60
|
+
"vue": "3.5.42"
|
|
64
61
|
},
|
|
65
62
|
"scripts": {
|
|
66
63
|
"dev": "tsdown --watch",
|