vite-userscript-plugin 0.6.1 → 0.8.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/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # vite-userscript-plugin
2
2
 
3
- ![ci](https://img.shields.io/github/workflow/status/crashmax-dev/vite-userscript-plugin/npm-publish)
4
3
  ![npm](https://img.shields.io/npm/v/vite-userscript-plugin)
5
4
  ![license](https://img.shields.io/github/license/crashmax-dev/vite-userscript-plugin)
6
5
 
@@ -85,11 +84,6 @@ export interface UserscriptPluginConfig {
85
84
  * @default true
86
85
  */
87
86
  autoGrants?: boolean
88
-
89
- /**
90
- * Server config (used in development mode for hot reloading).
91
- */
92
- server?: ServerConfig
93
87
  }
94
88
  ```
95
89
 
@@ -0,0 +1 @@
1
+ "use strict";async function n(){let o=new WebSocket("ws://localhost:__PORT__");o.addEventListener("open",()=>{let{script:e}=GM_info;console.group(`${e.name}@${e.version}`),console.log(GM_info),console.groupEnd()}),o.addEventListener("close",()=>{setTimeout(n,1e3)}),o.addEventListener("error",()=>{o.close()}),o.addEventListener("message",()=>{location.reload()})}n().then(()=>console.info("Connection to ws..."));
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ async function n(){let o=new WebSocket("ws://localhost:__PORT__");o.addEventListener("open",()=>{let{script:e}=GM_info;console.group(`${e.name}@${e.version}`),console.log(GM_info),console.groupEnd()}),o.addEventListener("close",()=>{setTimeout(n,1e3)}),o.addEventListener("error",()=>{o.close()}),o.addEventListener("message",()=>{location.reload()})}n().then(()=>console.info("Connection to ws..."));
package/dist/index.cjs CHANGED
@@ -1,316 +1,5 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ "use strict";var W=Object.create;var h=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var J=(e,t)=>{for(var r in t)h(e,r,{get:t[r],enumerable:!0})},R=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of K(t))!I.call(e,o)&&o!==r&&h(e,o,{get:()=>t[o],enumerable:!(n=N(t,o))||n.enumerable});return e};var C=(e,t,r)=>(r=e!=null?W(z(e)):{},R(t||!e||!e.__esModule?h(r,"default",{value:e,enumerable:!0}):r,e)),H=e=>R(h({},"__esModule",{value:!0}),e);var X={};J(X,{UserscriptPlugin:()=>V,default:()=>Q});module.exports=H(X);var k=C(require("get-port"),1),c=require("fs"),q=require("http"),d=require("path"),v=require("url"),F=C(require("sanitize-filename"),1),L=require("websocket");function j(e){let t=[],r=Object.keys(e),n=Math.max(...r.map(a=>a.length))+1,o=a=>" ".repeat(n-a.length),g=(a,i)=>{let s=typeof i=="boolean";s&&!i||(i=s?"":o(a)+i.toString(),t.push(`// @${a}${i}`))};for(let[a,i]of Object.entries(e))if(Array.isArray(i))i.forEach(s=>g(a,s));else{if(i===void 0)continue;g(a,i)}return["// ==UserScript==",...t,"// ==/UserScript=="].join(`
2
+ `)}var T=new RegExp(/\.(tsx?|jsx?)$/),$=new RegExp(/\.(s?css|sass)$/),S='console.warn("__TEMPLATE__")',x=["unsafeWindow","window.onurlchange","window.focus","window.close","GM_setValue","GM_getValue","GM_deleteValue","GM_listValues","GM_setClipboard","GM_addStyle","GM_addElement","GM_addValueChangeListener","GM_removeValueChangeListener","GM_registerMenuCommand","GM_unregisterMenuCommand","GM_download","GM_getTab","GM_getTabs","GM_saveTab","GM_openInTab","GM_notification","GM_getResourceURL","GM_getResourceText","GM_xmlhttpRequest","GM_webRequest","GM_log","GM_info"];var O=require("vite");function u(e){return[...new Set(Array.isArray(e)?e:e?[e]:[])]}async function G({file:e,name:t,loader:r}){let{code:n}=await(0,O.transformWithEsbuild)(e,t,{loader:r,minify:!0});return n}function E(e){let t=[];for(let r of x)e.indexOf(r)!==-1&&t.push(r);return t}var P=class{styles=new Map;async add(t,r){let n=await G({file:t,name:r,loader:"css"});return this.styles.set(r,n.replace(`
3
+ `,"")),""}inject(){let t=[...this.styles.values()].join("");if(!!t)return`GM_addStyle(\`${t}\`)`}merge(t){let r=[];for(let n of t){let o=this.styles.get(n);!o||r.push([n,o])}this.styles.clear(),r.forEach(n=>this.styles.set(...n))}},w=new P;var U={};function V(e){let t,r,n=null,o=null,g=(0,q.createServer)(),a=L.server;return new a({httpServer:g}).on("request",s=>{o=s.accept(null,s.origin)}),{name:"vite-userscript-plugin",apply:"build",config(){return{build:{lib:{entry:e.entry,name:e.metadata.name,formats:["iife"],fileName:()=>`${e.metadata.name}.js`}}}},configResolved(s){t=s,r=s.build.watch??!1;let{name:l,match:y,require:p,include:f,exclude:_,resource:M,connect:b}=e.metadata;e.metadata.name=(0,F.default)(l),e.metadata.match=u(y),e.metadata.require=u(p),e.metadata.include=u(f),e.metadata.exclude=u(_),e.metadata.resource=u(M),e.metadata.connect=u(b)},async transform(s,l){return $.test(l)?{code:await w.add(s,l)}:l.includes(e.entry)?{code:s+S}:null},generateBundle(s,l){for(let[y,p]of Object.entries(l)){let f=Object.keys(p.modules);w.merge(f)}},async writeBundle(s,l){!n&&r&&(n=await(0,k.default)(),g.listen(n));for(let[y]of Object.entries(l))if(T.test(y)){let p=t.root,f=t.build.outDir||"dist",_=(0,d.resolve)(p,f,y),M=(0,d.resolve)((0,d.dirname)((0,v.fileURLToPath)(U.url)),`hot-reload-${e.metadata.name}.js`),b=(0,d.resolve)(p,f,`${e.metadata.name}.proxy.user.js`),A=(0,d.resolve)(p,f,`${e.metadata.name}.user.js`);try{let m=(0,c.readFileSync)(_,"utf8");if(e.metadata.grant=u(r?x:e.autoGrants??!0?E(m):[...e.metadata.grant??[],"GM_addStyle","GM_info"]),r){let D=(0,c.readFileSync)((0,d.resolve)((0,d.dirname)((0,v.fileURLToPath)(U.url)),"hot-reload.js"),"utf8"),B=await G({file:D.replace("__PORT__",n.toString()),name:M,loader:"js"});(0,c.writeFileSync)(M,B),(0,c.writeFileSync)(b,j({...e.metadata,require:[...e.metadata.require,"file://"+M,"file://"+_]}))}m=m.replace(S,`${w.inject()}`),m=await G({file:m,name:y,loader:"js"}),(0,c.writeFileSync)(_,m),(0,c.writeFileSync)(A,`${j(e.metadata)}
19
4
 
20
- // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- UserscriptPlugin: () => UserscriptPlugin,
24
- default: () => src_default
25
- });
26
- module.exports = __toCommonJS(src_exports);
27
- var import_node_fs = require("fs");
28
- var import_node_http = require("http");
29
- var import_node_path = require("path");
30
- var import_node_url = require("url");
31
- var import_websocket = require("websocket");
32
-
33
- // src/banner.ts
34
- function banner(config) {
35
- const metadata = [];
36
- const configKeys = Object.keys(config);
37
- const maxKeyLength = Math.max(...configKeys.map((key) => key.length)) + 1;
38
- const addSpaces = (str) => {
39
- return " ".repeat(maxKeyLength - str.length);
40
- };
41
- const addMetadata = (key, value) => {
42
- const isBoolean = typeof value === "boolean";
43
- if (isBoolean && !value)
44
- return;
45
- value = !isBoolean ? addSpaces(key) + value.toString() : "";
46
- metadata.push(`// @${key}${value}`);
47
- };
48
- for (const [key, value] of Object.entries(config)) {
49
- if (Array.isArray(value)) {
50
- value.forEach((value2) => addMetadata(key, value2));
51
- } else {
52
- if (value === void 0)
53
- continue;
54
- addMetadata(key, value);
55
- }
56
- }
57
- return [
58
- "// ==UserScript==",
59
- ...metadata,
60
- "// ==/UserScript=="
61
- ].join("\n");
62
- }
63
-
64
- // src/constants.ts
65
- var regexpScripts = new RegExp(/\.(tsx?|jsx?)$/);
66
- var regexpStyles = new RegExp(/\.(s?css|sass)$/);
67
- var template = `console.warn("__TEMPLATE__")`;
68
- var grants = [
69
- "unsafeWindow",
70
- "window.onurlchange",
71
- "window.focus",
72
- "window.close",
73
- "GM_setValue",
74
- "GM_getValue",
75
- "GM_deleteValue",
76
- "GM_listValues",
77
- "GM_setClipboard",
78
- "GM_addStyle",
79
- "GM_addElement",
80
- "GM_addValueChangeListener",
81
- "GM_removeValueChangeListener",
82
- "GM_registerMenuCommand",
83
- "GM_unregisterMenuCommand",
84
- "GM_download",
85
- "GM_getTab",
86
- "GM_getTabs",
87
- "GM_saveTab",
88
- "GM_openInTab",
89
- "GM_notification",
90
- "GM_getResourceURL",
91
- "GM_getResourceText",
92
- "GM_xmlhttpRequest",
93
- "GM_webRequest",
94
- "GM_log",
95
- "GM_info"
96
- ];
97
-
98
- // src/helpers.ts
99
- var import_vite = require("vite");
100
- function removeDuplicates(arr) {
101
- return [...new Set(Array.isArray(arr) ? arr : arr ? [arr] : [])];
102
- }
103
- async function transform({
104
- file,
105
- name,
106
- loader
107
- }) {
108
- const { code } = await (0, import_vite.transformWithEsbuild)(file, name, {
109
- loader,
110
- minify: true
111
- });
112
- return code;
113
- }
114
- function defineGrants(code) {
115
- const definedGrants = [];
116
- for (const grant of grants) {
117
- if (code.indexOf(grant) !== -1) {
118
- definedGrants.push(grant);
119
- }
120
- }
121
- return definedGrants;
122
- }
123
-
124
- // src/css.ts
125
- var CSS = class {
126
- styles = /* @__PURE__ */ new Map();
127
- add(entry, code, path) {
128
- if (regexpStyles.test(path)) {
129
- this.styles.set(path, code);
130
- return {
131
- code: ""
132
- };
133
- }
134
- if (path.includes(entry)) {
135
- return {
136
- code: code + template
137
- };
138
- }
139
- return null;
140
- }
141
- async minify(file, name) {
142
- return await transform({
143
- file,
144
- name,
145
- loader: "css"
146
- });
147
- }
148
- inject() {
149
- const styles = [...this.styles.values()].join("");
150
- if (!styles)
151
- return;
152
- return `GM_addStyle(\`${styles}\`)`;
153
- }
154
- merge(modules) {
155
- const styleModules = [];
156
- for (const module2 of modules) {
157
- const style = this.styles.get(module2);
158
- if (!style)
159
- continue;
160
- styleModules.push([module2, style]);
161
- }
162
- this.styles.clear();
163
- styleModules.forEach((value) => this.styles.set(...value));
164
- }
165
- };
166
- var css_default = new CSS();
167
-
168
- // src/index.ts
169
- var import_meta = {};
170
- function UserscriptPlugin(config) {
171
- var _a;
172
- let pluginConfig;
173
- let isBuildWatch;
174
- let socketConnection = null;
175
- const port = ((_a = config.server) == null ? void 0 : _a.port) || 8e3;
176
- const httpServer = (0, import_node_http.createServer)();
177
- httpServer.listen(port);
178
- const WebSocketServer = import_websocket.server;
179
- const ws = new WebSocketServer({ httpServer });
180
- ws.on("request", (request) => {
181
- socketConnection = request.accept(null, request.origin);
182
- });
183
- return {
184
- name: "vite-userscript-plugin",
185
- apply: "build",
186
- config() {
187
- return {
188
- build: {
189
- lib: {
190
- entry: config.entry,
191
- name: config.metadata.name,
192
- formats: ["iife"],
193
- fileName: () => `${config.metadata.name}.js`
194
- },
195
- rollupOptions: {
196
- output: {
197
- exports: "none",
198
- extend: true
199
- }
200
- }
201
- }
202
- };
203
- },
204
- configResolved(cfg) {
205
- pluginConfig = cfg;
206
- isBuildWatch = cfg.build.watch ?? false;
207
- const { match, require: require2, include, exclude, resource, connect } = config.metadata;
208
- config.metadata.match = removeDuplicates(match);
209
- config.metadata.require = removeDuplicates(require2);
210
- config.metadata.include = removeDuplicates(include);
211
- config.metadata.exclude = removeDuplicates(exclude);
212
- config.metadata.resource = removeDuplicates(resource);
213
- config.metadata.connect = removeDuplicates(connect);
214
- },
215
- async transform(code, path) {
216
- const style = await css_default.minify(code, path);
217
- return css_default.add(config.entry, style.replace("\n", ""), path);
218
- },
219
- generateBundle(_, bundle) {
220
- for (const [_2, file] of Object.entries(bundle)) {
221
- const styleModules = Object.keys(
222
- file.modules
223
- );
224
- css_default.merge(styleModules);
225
- }
226
- },
227
- async writeBundle(_, bundle) {
228
- for (const [fileName] of Object.entries(bundle)) {
229
- if (regexpScripts.test(fileName)) {
230
- const rootDir = pluginConfig.root;
231
- const outDir = pluginConfig.build.outDir || "dist";
232
- const outPath = (0, import_node_path.resolve)(rootDir, outDir, fileName);
233
- const hotReloadPath = (0, import_node_path.resolve)(
234
- (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url)),
235
- "__hot-reload__.js"
236
- );
237
- const proxyFilePath = (0, import_node_path.resolve)(
238
- rootDir,
239
- outDir,
240
- `${config.metadata.name}.proxy.user.js`
241
- );
242
- const userFilePath = (0, import_node_path.resolve)(
243
- rootDir,
244
- outDir,
245
- `${config.metadata.name}.user.js`
246
- );
247
- try {
248
- let source = (0, import_node_fs.readFileSync)(outPath, "utf8");
249
- config.metadata.grant = removeDuplicates(
250
- isBuildWatch ? grants : config.autoGrants ?? true ? defineGrants(source) : [...config.metadata.grant ?? [], "GM_addStyle", "GM_info"]
251
- );
252
- if (isBuildWatch) {
253
- const hotReloadFile = (0, import_node_fs.readFileSync)(
254
- (0, import_node_path.resolve)(
255
- (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url)),
256
- "hot-reload.js"
257
- ),
258
- "utf8"
259
- );
260
- const hotReloadScript = await transform({
261
- file: hotReloadFile.replace("__PORT__", port.toString()),
262
- name: hotReloadPath,
263
- loader: "js"
264
- });
265
- (0, import_node_fs.writeFileSync)(hotReloadPath, hotReloadScript);
266
- (0, import_node_fs.writeFileSync)(
267
- proxyFilePath,
268
- banner({
269
- ...config.metadata,
270
- require: [
271
- ...config.metadata.require,
272
- "file://" + hotReloadPath,
273
- "file://" + outPath
274
- ]
275
- })
276
- );
277
- }
278
- source = source.replace(template, `${css_default.inject()}`);
279
- source = await transform({
280
- file: source,
281
- name: fileName,
282
- loader: "js"
283
- });
284
- (0, import_node_fs.writeFileSync)(outPath, source);
285
- (0, import_node_fs.writeFileSync)(
286
- userFilePath,
287
- `${banner(config.metadata)}
288
-
289
- ${source}`
290
- );
291
- } catch (err) {
292
- console.log(err);
293
- }
294
- }
295
- }
296
- if (!isBuildWatch) {
297
- httpServer.close();
298
- process.exit(0);
299
- }
300
- },
301
- buildEnd() {
302
- if (socketConnection) {
303
- socketConnection.sendUTF(
304
- JSON.stringify({
305
- message: "reload"
306
- })
307
- );
308
- }
309
- }
310
- };
311
- }
312
- var src_default = UserscriptPlugin;
313
- // Annotate the CommonJS export names for ESM import in node:
314
- 0 && (module.exports = {
315
- UserscriptPlugin
316
- });
5
+ ${m}`)}catch(m){console.log(m)}}r||(g.close(),process.exit(0))},buildEnd(){o&&o.sendUTF(JSON.stringify({message:"reload"}))}}}var Q=V;0&&(module.exports={UserscriptPlugin});
package/dist/index.d.ts CHANGED
@@ -187,13 +187,6 @@ declare type MetadataConfig = {
187
187
  */
188
188
  'run-at'?: RunAt;
189
189
  };
190
- interface ServerConfig {
191
- /**
192
- * Server port.
193
- * @default 8000
194
- */
195
- port?: number;
196
- }
197
190
  interface UserscriptPluginConfig {
198
191
  /**
199
192
  * Path of userscript entry.
@@ -208,10 +201,6 @@ interface UserscriptPluginConfig {
208
201
  * @default true
209
202
  */
210
203
  autoGrants?: boolean;
211
- /**
212
- * Server config (used in development mode for hot reloading).
213
- */
214
- server?: ServerConfig;
215
204
  }
216
205
 
217
206
  declare function UserscriptPlugin(config: UserscriptPluginConfig): PluginOption;
package/dist/index.js CHANGED
@@ -1,290 +1,5 @@
1
- // src/index.ts
2
- import { readFileSync, writeFileSync } from "fs";
3
- import { createServer } from "http";
4
- import { dirname, resolve } from "path";
5
- import { fileURLToPath } from "url";
6
- import { server } from "websocket";
1
+ import q from"get-port";import{readFileSync as C,writeFileSync as x}from"fs";import{createServer as F}from"http";import{dirname as T,resolve as M}from"path";import{fileURLToPath as $}from"url";import L from"sanitize-filename";import{server as V}from"websocket";function b(e){let t=[],r=Object.keys(e),n=Math.max(...r.map(o=>o.length))+1,m=o=>" ".repeat(n-o.length),p=(o,a)=>{let s=typeof a=="boolean";s&&!a||(a=s?"":m(o)+a.toString(),t.push(`// @${o}${a}`))};for(let[o,a]of Object.entries(e))if(Array.isArray(a))a.forEach(s=>p(o,s));else{if(a===void 0)continue;p(o,a)}return["// ==UserScript==",...t,"// ==/UserScript=="].join(`
2
+ `)}var P=new RegExp(/\.(tsx?|jsx?)$/),v=new RegExp(/\.(s?css|sass)$/),j='console.warn("__TEMPLATE__")',G=["unsafeWindow","window.onurlchange","window.focus","window.close","GM_setValue","GM_getValue","GM_deleteValue","GM_listValues","GM_setClipboard","GM_addStyle","GM_addElement","GM_addValueChangeListener","GM_removeValueChangeListener","GM_registerMenuCommand","GM_unregisterMenuCommand","GM_download","GM_getTab","GM_getTabs","GM_saveTab","GM_openInTab","GM_notification","GM_getResourceURL","GM_getResourceText","GM_xmlhttpRequest","GM_webRequest","GM_log","GM_info"];import{transformWithEsbuild as k}from"vite";function d(e){return[...new Set(Array.isArray(e)?e:e?[e]:[])]}async function _({file:e,name:t,loader:r}){let{code:n}=await k(e,t,{loader:r,minify:!0});return n}function R(e){let t=[];for(let r of G)e.indexOf(r)!==-1&&t.push(r);return t}var S=class{styles=new Map;async add(t,r){let n=await _({file:t,name:r,loader:"css"});return this.styles.set(r,n.replace(`
3
+ `,"")),""}inject(){let t=[...this.styles.values()].join("");if(!!t)return`GM_addStyle(\`${t}\`)`}merge(t){let r=[];for(let n of t){let m=this.styles.get(n);!m||r.push([n,m])}this.styles.clear(),r.forEach(n=>this.styles.set(...n))}},h=new S;function A(e){let t,r,n=null,m=null,p=F(),o=V;return new o({httpServer:p}).on("request",s=>{m=s.accept(null,s.origin)}),{name:"vite-userscript-plugin",apply:"build",config(){return{build:{lib:{entry:e.entry,name:e.metadata.name,formats:["iife"],fileName:()=>`${e.metadata.name}.js`}}}},configResolved(s){t=s,r=s.build.watch??!1;let{name:i,match:f,require:u,include:c,exclude:g,resource:y,connect:w}=e.metadata;e.metadata.name=L(i),e.metadata.match=d(f),e.metadata.require=d(u),e.metadata.include=d(c),e.metadata.exclude=d(g),e.metadata.resource=d(y),e.metadata.connect=d(w)},async transform(s,i){return v.test(i)?{code:await h.add(s,i)}:i.includes(e.entry)?{code:s+j}:null},generateBundle(s,i){for(let[f,u]of Object.entries(i)){let c=Object.keys(u.modules);h.merge(c)}},async writeBundle(s,i){!n&&r&&(n=await q(),p.listen(n));for(let[f]of Object.entries(i))if(P.test(f)){let u=t.root,c=t.build.outDir||"dist",g=M(u,c,f),y=M(T($(import.meta.url)),`hot-reload-${e.metadata.name}.js`),w=M(u,c,`${e.metadata.name}.proxy.user.js`),O=M(u,c,`${e.metadata.name}.user.js`);try{let l=C(g,"utf8");if(e.metadata.grant=d(r?G:e.autoGrants??!0?R(l):[...e.metadata.grant??[],"GM_addStyle","GM_info"]),r){let E=C(M(T($(import.meta.url)),"hot-reload.js"),"utf8"),U=await _({file:E.replace("__PORT__",n.toString()),name:y,loader:"js"});x(y,U),x(w,b({...e.metadata,require:[...e.metadata.require,"file://"+y,"file://"+g]}))}l=l.replace(j,`${h.inject()}`),l=await _({file:l,name:f,loader:"js"}),x(g,l),x(O,`${b(e.metadata)}
7
4
 
8
- // src/banner.ts
9
- function banner(config) {
10
- const metadata = [];
11
- const configKeys = Object.keys(config);
12
- const maxKeyLength = Math.max(...configKeys.map((key) => key.length)) + 1;
13
- const addSpaces = (str) => {
14
- return " ".repeat(maxKeyLength - str.length);
15
- };
16
- const addMetadata = (key, value) => {
17
- const isBoolean = typeof value === "boolean";
18
- if (isBoolean && !value)
19
- return;
20
- value = !isBoolean ? addSpaces(key) + value.toString() : "";
21
- metadata.push(`// @${key}${value}`);
22
- };
23
- for (const [key, value] of Object.entries(config)) {
24
- if (Array.isArray(value)) {
25
- value.forEach((value2) => addMetadata(key, value2));
26
- } else {
27
- if (value === void 0)
28
- continue;
29
- addMetadata(key, value);
30
- }
31
- }
32
- return [
33
- "// ==UserScript==",
34
- ...metadata,
35
- "// ==/UserScript=="
36
- ].join("\n");
37
- }
38
-
39
- // src/constants.ts
40
- var regexpScripts = new RegExp(/\.(tsx?|jsx?)$/);
41
- var regexpStyles = new RegExp(/\.(s?css|sass)$/);
42
- var template = `console.warn("__TEMPLATE__")`;
43
- var grants = [
44
- "unsafeWindow",
45
- "window.onurlchange",
46
- "window.focus",
47
- "window.close",
48
- "GM_setValue",
49
- "GM_getValue",
50
- "GM_deleteValue",
51
- "GM_listValues",
52
- "GM_setClipboard",
53
- "GM_addStyle",
54
- "GM_addElement",
55
- "GM_addValueChangeListener",
56
- "GM_removeValueChangeListener",
57
- "GM_registerMenuCommand",
58
- "GM_unregisterMenuCommand",
59
- "GM_download",
60
- "GM_getTab",
61
- "GM_getTabs",
62
- "GM_saveTab",
63
- "GM_openInTab",
64
- "GM_notification",
65
- "GM_getResourceURL",
66
- "GM_getResourceText",
67
- "GM_xmlhttpRequest",
68
- "GM_webRequest",
69
- "GM_log",
70
- "GM_info"
71
- ];
72
-
73
- // src/helpers.ts
74
- import { transformWithEsbuild } from "vite";
75
- function removeDuplicates(arr) {
76
- return [...new Set(Array.isArray(arr) ? arr : arr ? [arr] : [])];
77
- }
78
- async function transform({
79
- file,
80
- name,
81
- loader
82
- }) {
83
- const { code } = await transformWithEsbuild(file, name, {
84
- loader,
85
- minify: true
86
- });
87
- return code;
88
- }
89
- function defineGrants(code) {
90
- const definedGrants = [];
91
- for (const grant of grants) {
92
- if (code.indexOf(grant) !== -1) {
93
- definedGrants.push(grant);
94
- }
95
- }
96
- return definedGrants;
97
- }
98
-
99
- // src/css.ts
100
- var CSS = class {
101
- styles = /* @__PURE__ */ new Map();
102
- add(entry, code, path) {
103
- if (regexpStyles.test(path)) {
104
- this.styles.set(path, code);
105
- return {
106
- code: ""
107
- };
108
- }
109
- if (path.includes(entry)) {
110
- return {
111
- code: code + template
112
- };
113
- }
114
- return null;
115
- }
116
- async minify(file, name) {
117
- return await transform({
118
- file,
119
- name,
120
- loader: "css"
121
- });
122
- }
123
- inject() {
124
- const styles = [...this.styles.values()].join("");
125
- if (!styles)
126
- return;
127
- return `GM_addStyle(\`${styles}\`)`;
128
- }
129
- merge(modules) {
130
- const styleModules = [];
131
- for (const module of modules) {
132
- const style = this.styles.get(module);
133
- if (!style)
134
- continue;
135
- styleModules.push([module, style]);
136
- }
137
- this.styles.clear();
138
- styleModules.forEach((value) => this.styles.set(...value));
139
- }
140
- };
141
- var css_default = new CSS();
142
-
143
- // src/index.ts
144
- function UserscriptPlugin(config) {
145
- var _a;
146
- let pluginConfig;
147
- let isBuildWatch;
148
- let socketConnection = null;
149
- const port = ((_a = config.server) == null ? void 0 : _a.port) || 8e3;
150
- const httpServer = createServer();
151
- httpServer.listen(port);
152
- const WebSocketServer = server;
153
- const ws = new WebSocketServer({ httpServer });
154
- ws.on("request", (request) => {
155
- socketConnection = request.accept(null, request.origin);
156
- });
157
- return {
158
- name: "vite-userscript-plugin",
159
- apply: "build",
160
- config() {
161
- return {
162
- build: {
163
- lib: {
164
- entry: config.entry,
165
- name: config.metadata.name,
166
- formats: ["iife"],
167
- fileName: () => `${config.metadata.name}.js`
168
- },
169
- rollupOptions: {
170
- output: {
171
- exports: "none",
172
- extend: true
173
- }
174
- }
175
- }
176
- };
177
- },
178
- configResolved(cfg) {
179
- pluginConfig = cfg;
180
- isBuildWatch = cfg.build.watch ?? false;
181
- const { match, require: require2, include, exclude, resource, connect } = config.metadata;
182
- config.metadata.match = removeDuplicates(match);
183
- config.metadata.require = removeDuplicates(require2);
184
- config.metadata.include = removeDuplicates(include);
185
- config.metadata.exclude = removeDuplicates(exclude);
186
- config.metadata.resource = removeDuplicates(resource);
187
- config.metadata.connect = removeDuplicates(connect);
188
- },
189
- async transform(code, path) {
190
- const style = await css_default.minify(code, path);
191
- return css_default.add(config.entry, style.replace("\n", ""), path);
192
- },
193
- generateBundle(_, bundle) {
194
- for (const [_2, file] of Object.entries(bundle)) {
195
- const styleModules = Object.keys(
196
- file.modules
197
- );
198
- css_default.merge(styleModules);
199
- }
200
- },
201
- async writeBundle(_, bundle) {
202
- for (const [fileName] of Object.entries(bundle)) {
203
- if (regexpScripts.test(fileName)) {
204
- const rootDir = pluginConfig.root;
205
- const outDir = pluginConfig.build.outDir || "dist";
206
- const outPath = resolve(rootDir, outDir, fileName);
207
- const hotReloadPath = resolve(
208
- dirname(fileURLToPath(import.meta.url)),
209
- "__hot-reload__.js"
210
- );
211
- const proxyFilePath = resolve(
212
- rootDir,
213
- outDir,
214
- `${config.metadata.name}.proxy.user.js`
215
- );
216
- const userFilePath = resolve(
217
- rootDir,
218
- outDir,
219
- `${config.metadata.name}.user.js`
220
- );
221
- try {
222
- let source = readFileSync(outPath, "utf8");
223
- config.metadata.grant = removeDuplicates(
224
- isBuildWatch ? grants : config.autoGrants ?? true ? defineGrants(source) : [...config.metadata.grant ?? [], "GM_addStyle", "GM_info"]
225
- );
226
- if (isBuildWatch) {
227
- const hotReloadFile = readFileSync(
228
- resolve(
229
- dirname(fileURLToPath(import.meta.url)),
230
- "hot-reload.js"
231
- ),
232
- "utf8"
233
- );
234
- const hotReloadScript = await transform({
235
- file: hotReloadFile.replace("__PORT__", port.toString()),
236
- name: hotReloadPath,
237
- loader: "js"
238
- });
239
- writeFileSync(hotReloadPath, hotReloadScript);
240
- writeFileSync(
241
- proxyFilePath,
242
- banner({
243
- ...config.metadata,
244
- require: [
245
- ...config.metadata.require,
246
- "file://" + hotReloadPath,
247
- "file://" + outPath
248
- ]
249
- })
250
- );
251
- }
252
- source = source.replace(template, `${css_default.inject()}`);
253
- source = await transform({
254
- file: source,
255
- name: fileName,
256
- loader: "js"
257
- });
258
- writeFileSync(outPath, source);
259
- writeFileSync(
260
- userFilePath,
261
- `${banner(config.metadata)}
262
-
263
- ${source}`
264
- );
265
- } catch (err) {
266
- console.log(err);
267
- }
268
- }
269
- }
270
- if (!isBuildWatch) {
271
- httpServer.close();
272
- process.exit(0);
273
- }
274
- },
275
- buildEnd() {
276
- if (socketConnection) {
277
- socketConnection.sendUTF(
278
- JSON.stringify({
279
- message: "reload"
280
- })
281
- );
282
- }
283
- }
284
- };
285
- }
286
- var src_default = UserscriptPlugin;
287
- export {
288
- UserscriptPlugin,
289
- src_default as default
290
- };
5
+ ${l}`)}catch(l){console.log(l)}}r||(p.close(),process.exit(0))},buildEnd(){m&&m.sendUTF(JSON.stringify({message:"reload"}))}}}var oe=A;export{A as UserscriptPlugin,oe as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-userscript-plugin",
3
- "version": "0.6.1",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.cjs",
@@ -32,6 +32,8 @@
32
32
  "url": "https://github.com/crashmax-dev/vite-userscript-plugin/issues"
33
33
  },
34
34
  "dependencies": {
35
+ "get-port": "^6.1.2",
36
+ "sanitize-filename": "^1.6.3",
35
37
  "websocket": "^1.0.34"
36
38
  },
37
39
  "devDependencies": {