vite-plugin-millennium-skin 1.0.0 → 1.0.2

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.
@@ -0,0 +1,6 @@
1
+ export * from './src/ts/index'
2
+ export {}
3
+ import VitePluginMillenniumSkin from './src/ts/index'
4
+ export default VitePluginMillenniumSkin
5
+ export * from './src/ts/index'
6
+ export {}
package/dist/index.js ADDED
@@ -0,0 +1,547 @@
1
+ import t from "@babel/types";
2
+ import { parse } from "@babel/parser";
3
+ import traverse from "@babel/traverse";
4
+ import { generate } from "@babel/generator";
5
+ import path, { join } from "path/posix";
6
+ import { existsSync } from "fs";
7
+ import fsp from "fs/promises";
8
+ import { loadConfigFromFile } from "vite";
9
+ import chalk from "chalk";
10
+ const defaultPatches = [
11
+ {
12
+ Match: "https://.*.steampowered.com",
13
+ TargetCss: "webkit.css",
14
+ TargetJs: "webkit.js"
15
+ },
16
+ {
17
+ Match: "https://steamcommunity.com",
18
+ TargetCss: "webkit.css",
19
+ TargetJs: "webkit.js"
20
+ },
21
+ {
22
+ Match: "^Steam$",
23
+ TargetCss: "libraryroot.custom.css",
24
+ TargetJs: "libraryroot.custom.js"
25
+ },
26
+ {
27
+ Match: "^OverlayBrowser_Browser$",
28
+ TargetCss: "libraryroot.custom.css",
29
+ TargetJs: "libraryroot.custom.js"
30
+ },
31
+ {
32
+ Match: "^SP Overlay:",
33
+ TargetCss: "libraryroot.custom.css",
34
+ TargetJs: "libraryroot.custom.js"
35
+ },
36
+ {
37
+ Match: "Supernav$",
38
+ TargetCss: "libraryroot.custom.css",
39
+ TargetJs: "libraryroot.custom.js"
40
+ },
41
+ {
42
+ Match: "^notificationtoasts_",
43
+ TargetCss: "notifications.custom.css",
44
+ TargetJs: "notifications.custom.js"
45
+ },
46
+ {
47
+ Match: "^SteamBrowser_Find$",
48
+ TargetCss: "libraryroot.custom.css",
49
+ TargetJs: "libraryroot.custom.js"
50
+ },
51
+ {
52
+ Match: "^OverlayTab\\d+_Find$",
53
+ TargetCss: "libraryroot.custom.css",
54
+ TargetJs: "libraryroot.custom.js"
55
+ },
56
+ {
57
+ Match: "^Steam Big Picture Mode$",
58
+ TargetCss: "bigpicture.custom.css",
59
+ TargetJs: "bigpicture.custom.js"
60
+ },
61
+ {
62
+ Match: "^QuickAccess_",
63
+ TargetCss: "bigpicture.custom.css",
64
+ TargetJs: "bigpicture.custom.js"
65
+ },
66
+ {
67
+ Match: "^MainMenu_",
68
+ TargetCss: "bigpicture.custom.css",
69
+ TargetJs: "bigpicture.custom.js"
70
+ },
71
+ {
72
+ Match: ".friendsui-container",
73
+ TargetCss: "friends.custom.css",
74
+ TargetJs: "friends.custom.js"
75
+ },
76
+ {
77
+ Match: "Menu$",
78
+ TargetCss: "libraryroot.custom.css",
79
+ TargetJs: "libraryroot.custom.js"
80
+ },
81
+ {
82
+ Match: ".ModalDialogPopup",
83
+ TargetCss: "libraryroot.custom.css",
84
+ TargetJs: "libraryroot.custom.js"
85
+ },
86
+ {
87
+ Match: ".FullModalOverlay",
88
+ TargetCss: "libraryroot.custom.css",
89
+ TargetJs: "libraryroot.custom.js"
90
+ }
91
+ ];
92
+ const __DIRECT__ = 0;
93
+ const __RUNTIME__ = 1;
94
+ const aliasModules = [
95
+ {
96
+ method: __DIRECT__,
97
+ module: /^react$/g,
98
+ links: ["window", "opener", "SP_REACT"]
99
+ },
100
+ {
101
+ method: __DIRECT__,
102
+ module: /^react-dom$/g,
103
+ links: ["window", "opener", "SP_REACTDOM"]
104
+ }
105
+ ];
106
+ const __AUTO__ = 0;
107
+ const __PACKAGE__ = 1;
108
+ const Root = /^SharedJSContext$/;
109
+ const LibraryRoot = /^Steam$/;
110
+ const MenuView = /^View Root Menu$/;
111
+ const MenuSteam = /^Steam Root Menu$/;
112
+ const MenuFriends = /^Friends Root Menu$/;
113
+ const MenuGames = /^Games Root Menu$/;
114
+ const MenuHelp = /^Help Root Menu$/;
115
+ const MenuNotifications = /^Notifications Menu$/;
116
+ const MenuAccount = /^Account Menu$/;
117
+ const traver = traverse.default;
118
+ const SEMANTIC_VERSIONING_REGEXP = /(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<preRelease>(?:[a-zA-Z1-9][a-zA-Z\d]*|0\d*[a-zA-Z][a-zA-Z\d]*|0)(?:\.(?:[a-zA-Z1-9][a-zA-Z\d]*|0\d*[a-zA-Z][a-zA-Z\d]*|0))*))?(?:\+(?<metadata>(?:[a-zA-Z\d-]*)(?:\.(?:[a-zA-Z\d-]*))*))?/;
119
+ const SEMANTIC_TAGS_REGEXP = /(?:\.)?(?<tag>[a-zA-Z]+)\.(?<number>(?:[1-9]\d*|0\d*|0))/g;
120
+ let logger;
121
+ function millenniumSkin() {
122
+ const jsMap = [];
123
+ const cssMap = [];
124
+ let skinConfig;
125
+ let skinConfigResult;
126
+ let viteConfig;
127
+ return {
128
+ name: "vite-plugin-millennium-skin",
129
+ enforce: "pre",
130
+ async config(config) {
131
+ const res = await loadConfigFromFile(
132
+ { command: "build", mode: "profuction" },
133
+ "skin.config.ts",
134
+ config.root
135
+ );
136
+ skinConfig = res?.config;
137
+ if (skinConfig.Patches === void 0) {
138
+ if (!skinConfig.UseDefaultPatches)
139
+ throw new Error("haven't any patch in skin.config.ts");
140
+ skinConfig.Patches = defaultPatches;
141
+ }
142
+ skinConfig.Patches.forEach((patch) => {
143
+ if (patch.TargetJs)
144
+ jsMap.push(join(skinConfig.srcJs, patch.TargetJs));
145
+ if (patch.TargetCss)
146
+ cssMap.push(
147
+ findCssModule(join(skinConfig.srcCss, patch.TargetCss))
148
+ );
149
+ });
150
+ if (skinConfig.RootColors !== void 0)
151
+ cssMap.push(
152
+ findCssModule(
153
+ join(skinConfig.srcCss, skinConfig.RootColors)
154
+ )
155
+ );
156
+ return {
157
+ build: {
158
+ rollupOptions: {
159
+ input: [...jsMap, ...cssMap],
160
+ output: {
161
+ entryFileNames: "assets/js/[name].js",
162
+ assetFileNames: (info2) => {
163
+ const name = info2.names[0];
164
+ const file = path.parse(name);
165
+ if (file.ext === ".css")
166
+ return `assets/css/${name}`;
167
+ if (/\.(png|jpg|jpeg|gif|svg|webp|bmp|heic)/i.test(
168
+ file.ext
169
+ ))
170
+ return `assets/images/${name}`;
171
+ return `assets/css/${name}`;
172
+ }
173
+ }
174
+ },
175
+ assetsInlineLimit: 0,
176
+ cssCodeSplit: true
177
+ }
178
+ };
179
+ },
180
+ configResolved(config) {
181
+ viteConfig = config;
182
+ logger = config.logger;
183
+ },
184
+ generateBundle(_, bundles) {
185
+ if (skinConfig.Patches === void 0)
186
+ throw new Error("haven't any patch in building");
187
+ const root = viteConfig.root;
188
+ const patches = structuredClone(
189
+ skinConfig.Patches
190
+ ).map((e) => {
191
+ if (e.Match instanceof RegExp) e.Match = e.Match.source;
192
+ if (e.TargetJs) {
193
+ const parsed = path.parse(e.TargetJs);
194
+ e.TargetJs = join(
195
+ root,
196
+ skinConfig.srcJs,
197
+ parsed.dir,
198
+ parsed.name
199
+ );
200
+ }
201
+ if (e.TargetCss) {
202
+ const parsed = path.parse(e.TargetCss);
203
+ e.TargetCss = join(
204
+ root,
205
+ skinConfig.srcCss,
206
+ parsed.dir,
207
+ parsed.name
208
+ );
209
+ }
210
+ return {
211
+ MatchRegexString: e.Match,
212
+ TargetJs: e.TargetJs,
213
+ TargetCss: e.TargetCss
214
+ };
215
+ });
216
+ Object.entries(bundles).forEach(([, bundle]) => {
217
+ const { type } = bundle;
218
+ const compileLib = bundle.fileName;
219
+ if (type === "chunk") {
220
+ const compileParsed = path.parse(
221
+ bundle.facadeModuleId
222
+ );
223
+ const compilePath = join(
224
+ compileParsed.dir,
225
+ compileParsed.name
226
+ );
227
+ patches.forEach((patch) => {
228
+ if (compilePath !== patch.TargetJs) return;
229
+ patch.TargetJs = compileLib;
230
+ });
231
+ } else {
232
+ const compileParsed = path.parse(
233
+ join(root, bundle.originalFileNames[0])
234
+ );
235
+ const compilePath = join(
236
+ compileParsed.dir,
237
+ compileParsed.name
238
+ );
239
+ patches.forEach((patch) => {
240
+ if (compilePath !== patch.TargetCss) return;
241
+ patch.TargetCss = compileLib;
242
+ });
243
+ if (skinConfig.RootColors && compilePath === join(
244
+ viteConfig.root,
245
+ skinConfig.srcCss,
246
+ skinConfig.RootColors
247
+ ))
248
+ skinConfig.RootColors = compileLib;
249
+ return;
250
+ }
251
+ });
252
+ skinConfigResult = {
253
+ ...skinConfig,
254
+ Patches: patches,
255
+ version: ""
256
+ };
257
+ },
258
+ async writeBundle() {
259
+ const root = viteConfig.root;
260
+ const pkgPath = join(root, "package.json");
261
+ try {
262
+ const pkg = JSON.parse(
263
+ await fsp.readFile(pkgPath, {
264
+ flag: "r",
265
+ encoding: "utf-8"
266
+ })
267
+ );
268
+ if (skinConfig.version === __AUTO__ || skinConfig.version === void 0) {
269
+ const versions = await bump_version(
270
+ pkg.version,
271
+ process.env.RELEASE
272
+ );
273
+ if (versions) {
274
+ const newVersion = versionObjToString(versions.new);
275
+ skinConfigResult.version = newVersion;
276
+ pkg.version = newVersion;
277
+ await fsp.writeFile(
278
+ pkgPath,
279
+ JSON.stringify(pkg, null, 4)
280
+ );
281
+ info(
282
+ `${versionObjToString(versions.native)} -> ${newVersion}`
283
+ );
284
+ }
285
+ } else if (skinConfig.version === __PACKAGE__) {
286
+ skinConfigResult.version = pkg.version;
287
+ }
288
+ } catch (e) {
289
+ warn(`can't use package.json: ${e}`);
290
+ }
291
+ try {
292
+ await fsp.writeFile(
293
+ join(root, viteConfig.build.outDir, "skin.json"),
294
+ JSON.stringify(skinConfigResult, null, 4)
295
+ );
296
+ } catch (e) {
297
+ throw new Error(`can't write skin.json: ${e}`);
298
+ }
299
+ },
300
+ transform(code, id) {
301
+ if (!/.+\.(js|ts|tsx)$/g.test(id)) return;
302
+ const ast = parse(code, {
303
+ sourceType: "module",
304
+ plugins: ["typescript"]
305
+ });
306
+ traver(ast, {
307
+ Program(path2) {
308
+ const body = path2.node.body;
309
+ const runtimeLinks = {};
310
+ for (let i = body.length - 1; i >= 0; i--) {
311
+ let node = body[i];
312
+ if (!t.isImportDeclaration(node)) continue;
313
+ const moduleName = node.source.value;
314
+ const match = [];
315
+ for (const aliasMod of aliasModules) {
316
+ if (!aliasMod.module.test(moduleName)) continue;
317
+ const { method } = aliasMod;
318
+ for (const local of node.specifiers) {
319
+ const exportLocal = local.local.name;
320
+ let links;
321
+ if (local.type === "ImportDefaultSpecifier")
322
+ links = aliasMod.links;
323
+ else
324
+ links = [
325
+ ...aliasMod.links,
326
+ local.imported.name
327
+ ];
328
+ switch (method) {
329
+ case __RUNTIME__:
330
+ runtimeLinks[exportLocal] = aliasMod.links;
331
+ break;
332
+ case __DIRECT__:
333
+ match.push(
334
+ generateConstDeclaration(
335
+ exportLocal,
336
+ links
337
+ )
338
+ );
339
+ break;
340
+ }
341
+ }
342
+ }
343
+ body.splice(i, 1, ...match);
344
+ }
345
+ Object.entries(runtimeLinks).forEach(
346
+ ([localName, runtimeLink]) => {
347
+ const binding = path2.scope.getBinding(localName);
348
+ if (binding === void 0) return;
349
+ binding.referencePaths.forEach((refPath) => {
350
+ replaceRef(refPath, localName, runtimeLink);
351
+ });
352
+ binding.scope.removeOwnBinding(localName);
353
+ }
354
+ );
355
+ }
356
+ });
357
+ const result = generate(ast);
358
+ return { code: result.code };
359
+ }
360
+ };
361
+ }
362
+ function defineConfig(SkinConfig) {
363
+ return SkinConfig;
364
+ }
365
+ function generateConstDeclaration(moduleName, links) {
366
+ let expression = t.identifier(links[0]);
367
+ for (let i = 1; i < links.length; i++) {
368
+ expression = t.memberExpression(expression, t.identifier(links[i]));
369
+ }
370
+ const declarator = t.variableDeclarator(
371
+ t.identifier(moduleName),
372
+ expression
373
+ );
374
+ return t.variableDeclaration("const", [declarator]);
375
+ }
376
+ function findCssModule(cssPath) {
377
+ const parsed = path.parse(cssPath);
378
+ if (parsed.ext !== "") return cssPath;
379
+ for (const ext of ["scss", "sass", "css"]) {
380
+ const newPath = `${cssPath}.${ext}`;
381
+ if (!existsSync(join(process.cwd(), newPath))) continue;
382
+ return newPath;
383
+ }
384
+ throw new Error(`can't find css module: ${cssPath}`);
385
+ }
386
+ function replaceRef(refPath, localName, globalObj) {
387
+ const parent = refPath.parent;
388
+ if (t.isMemberExpression(parent) && parent.object === refPath.node) {
389
+ const prop = parent.property;
390
+ if (t.isIdentifier(prop)) {
391
+ const globalMember = createNestedMemberExpression(globalObj);
392
+ if (!refPath.parentPath) return;
393
+ refPath.parentPath.replaceWith(
394
+ t.memberExpression(globalMember, t.identifier(prop.name))
395
+ );
396
+ }
397
+ return;
398
+ }
399
+ if (refPath.isIdentifier()) {
400
+ const globalMember = createNestedMemberExpression(globalObj);
401
+ refPath.replaceWith(
402
+ t.memberExpression(globalMember, t.identifier(localName))
403
+ );
404
+ }
405
+ }
406
+ function createNestedMemberExpression(globalObj) {
407
+ if (globalObj.length === 0) {
408
+ throw new Error("globalObj must not be empty");
409
+ }
410
+ let node = t.identifier(globalObj[0]);
411
+ for (let i = 1; i < globalObj.length; i++) {
412
+ node = t.memberExpression(node, t.identifier(globalObj[i]));
413
+ }
414
+ return node;
415
+ }
416
+ async function bump_version(nativeVersion, tag = "snapshot") {
417
+ try {
418
+ const match = SEMANTIC_VERSIONING_REGEXP.exec(nativeVersion);
419
+ if (!match?.groups) {
420
+ warn(`can't understand version: ${nativeVersion}`);
421
+ return;
422
+ }
423
+ let version = {
424
+ major: parseInt(match.groups.major),
425
+ minor: parseInt(match.groups.minor),
426
+ patch: parseInt(match.groups.patch)
427
+ };
428
+ if (match.groups.preRelease) {
429
+ const tagsMatch = [
430
+ ...match.groups.preRelease.matchAll(SEMANTIC_TAGS_REGEXP)
431
+ ];
432
+ tagsMatch.forEach((e) => {
433
+ if (!e.groups) return;
434
+ version[e.groups.tag] = parseInt(e.groups.number);
435
+ });
436
+ }
437
+ const nativeVersionObj = { ...version };
438
+ switch (tag) {
439
+ case null:
440
+ break;
441
+ case void 0:
442
+ break;
443
+ case "major":
444
+ version = {
445
+ major: version.major + 1,
446
+ minor: 0,
447
+ patch: 0
448
+ };
449
+ break;
450
+ case "minor":
451
+ version = {
452
+ major: version.major,
453
+ minor: version.minor + 1,
454
+ patch: 0
455
+ };
456
+ break;
457
+ case "patch":
458
+ version = {
459
+ major: version.major,
460
+ minor: version.minor,
461
+ patch: version.patch + 1
462
+ };
463
+ break;
464
+ case "rc":
465
+ version.rc = (version.rc ?? 0) + 1;
466
+ delete version.gamma;
467
+ delete version.beta;
468
+ delete version.preview;
469
+ delete version.alpha;
470
+ delete version.snapshot;
471
+ break;
472
+ case "gamma":
473
+ version.gamma = (version.gamma ?? 0) + 1;
474
+ delete version.beta;
475
+ delete version.preview;
476
+ delete version.alpha;
477
+ delete version.snapshot;
478
+ break;
479
+ case "beta":
480
+ version.beta = (version.beta ?? 0) + 1;
481
+ delete version.preview;
482
+ delete version.alpha;
483
+ delete version.snapshot;
484
+ break;
485
+ case "preview":
486
+ version.preview = (version.preview ?? 0) + 1;
487
+ delete version.alpha;
488
+ delete version.snapshot;
489
+ break;
490
+ case "alpha":
491
+ version.alpha = (version.alpha ?? 0) + 1;
492
+ delete version.snapshot;
493
+ break;
494
+ case "snapshot":
495
+ version.snapshot = (version.snapshot ?? 0) + 1;
496
+ break;
497
+ }
498
+ return {
499
+ native: nativeVersionObj,
500
+ new: version
501
+ };
502
+ } catch (e) {
503
+ warn(`can't bump version: ${e}`);
504
+ }
505
+ return void 0;
506
+ }
507
+ function versionObjToString(version) {
508
+ let versionString = `${version.major}.${version.minor}.${version.patch}`;
509
+ const optionalFields = ["rc", "gamma", "beta", "preview", "alpha", "snapshot"];
510
+ let first = false;
511
+ for (const field of optionalFields) {
512
+ const value = version[field];
513
+ if (value !== void 0 && value !== null) {
514
+ if (!first) {
515
+ versionString += `-${field}.${value}`;
516
+ first = true;
517
+ } else versionString += `.${field}.${value}`;
518
+ }
519
+ }
520
+ return versionString;
521
+ }
522
+ function warn(msg, options) {
523
+ if (logger) logger.warn(chalk.yellow(`[MillenniumSkin] ${msg}`), options);
524
+ else console.warn(chalk.yellow(`[MillenniumSkin] ${msg}`));
525
+ }
526
+ function info(msg, options) {
527
+ if (logger)
528
+ logger.info(chalk.greenBright(`[MillenniumSkin] ${msg}`), options);
529
+ else console.log(chalk.greenBright(`[MillenniumSkin] ${msg}`));
530
+ }
531
+ export {
532
+ LibraryRoot,
533
+ MenuAccount,
534
+ MenuFriends,
535
+ MenuGames,
536
+ MenuHelp,
537
+ MenuNotifications,
538
+ MenuSteam,
539
+ MenuView,
540
+ Root,
541
+ __AUTO__,
542
+ __DIRECT__,
543
+ __PACKAGE__,
544
+ __RUNTIME__,
545
+ millenniumSkin as default,
546
+ defineConfig
547
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: import('./src/types').SkinConfig;
2
+ export default _default;
@@ -0,0 +1,8 @@
1
+ export declare const __DIRECT__ = 0;
2
+ export declare const __RUNTIME__ = 1;
3
+ declare const _default: {
4
+ method: number;
5
+ module: RegExp;
6
+ links: string[];
7
+ }[];
8
+ export default _default;
@@ -0,0 +1,9 @@
1
+ export declare const Root: RegExp;
2
+ export declare const LibraryRoot: RegExp;
3
+ export declare const MenuView: RegExp;
4
+ export declare const MenuSteam: RegExp;
5
+ export declare const MenuFriends: RegExp;
6
+ export declare const MenuGames: RegExp;
7
+ export declare const MenuHelp: RegExp;
8
+ export declare const MenuNotifications: RegExp;
9
+ export declare const MenuAccount: RegExp;
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ Match: string;
3
+ TargetCss: string;
4
+ TargetJs: string;
5
+ }[];
6
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { Plugin } from 'vite';
2
+ import { SkinConfig } from '../types/index';
3
+ export * from './aliasModules';
4
+ export * from './defaultMatch';
5
+ export * from './versionConfig';
6
+ export * from '../types/index';
7
+ export * from '../types/index';
8
+ export default function millenniumSkin(): Plugin;
9
+ export declare function defineConfig(SkinConfig: SkinConfig): SkinConfig;
@@ -0,0 +1,2 @@
1
+ export declare const __AUTO__ = 0;
2
+ export declare const __PACKAGE__ = 1;
@@ -0,0 +1 @@
1
+ export type * from './skin.config';
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vite').UserConfig;
2
+ export default _default;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-millennium-skin",
3
- "version": "1.0.0",
4
- "main": "index.js",
3
+ "version": "1.0.2",
4
+ "main": "./dist/index.js",
5
5
  "type": "module",
6
6
  "directories": {
7
7
  "test": "test"
@@ -26,6 +26,7 @@
26
26
  "@babel/preset-typescript": "^7.28.5",
27
27
  "@types/babel__core": "^7.20.5",
28
28
  "bestzip": "^2.2.1",
29
+ "cross-env": "^10.1.0",
29
30
  "eslint": "^9.39.2",
30
31
  "globals": "^16.5.0",
31
32
  "prettier": "^3.7.3",
@@ -51,7 +52,6 @@
51
52
  "@typescript-eslint/eslint-plugin": "^8.50.1",
52
53
  "babel-plugin-transform-typescript": "^7.0.0-alpha.19",
53
54
  "chalk": "^5.6.2",
54
- "cross-env": "^10.1.0",
55
55
  "vite-plugin-dts": "^4.5.4"
56
56
  }
57
57
  }
package/src/ts/index.ts CHANGED
@@ -24,6 +24,7 @@ import { __AUTO__, __PACKAGE__ } from "./versionConfig";
24
24
  export * from "./aliasModules";
25
25
  export * from "./defaultMatch";
26
26
  export * from "./versionConfig";
27
+ export * from "../types/index";
27
28
 
28
29
  const traver = (traverse as any).default as typeof traverse;
29
30
  const SEMANTIC_VERSIONING_REGEXP =