steam-theming-utils 1.3.1 → 1.5.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 ADDED
@@ -0,0 +1,23 @@
1
+ # steam-theming-utils
2
+
3
+ A collection of scripts for easier Steam theming.
4
+
5
+ ## Usage
6
+
7
+ ```sh
8
+ $ npm i
9
+ $ npx steam-theming-utils <script>
10
+ ```
11
+
12
+ Note that running any script requires Steam running with `-cef-enable-debugging`.
13
+
14
+ ## Script list
15
+
16
+ | Name | Description |
17
+ | --------------------- | --------------------------------------------------------------------------------- |
18
+ | build_class_modules | Generates a `class_map.json` file for usage with other scripts. |
19
+ | build_theme | Builds the theme. Requires a [specific directory structure][template]. |
20
+ | make_readable_classes | Adds readable versions of classes to the focused window. |
21
+ | replace_old_classes | Replaces old classes with new ones for themes not using the [template][template]. |
22
+
23
+ [template]: https://github.com/ricewind012/more-advanced-theme-template
@@ -1,20 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import postcss from "postcss";
4
- import { CLASS_MAP_FILE, readFile, readScript } from "../shared.js";
3
+ import { CLASS_MAP_FILE, readFile, readScript, usePostcss } from "../shared.js";
5
4
 
6
5
  const cwd = process.cwd();
7
6
  const DIST_DIR = path.join(cwd, "dist");
8
7
  const EXTENSION = ".css";
9
8
  const SRC_DIR = path.join(cwd, "src");
10
9
 
11
- const selectorReplacerPlugin = (opts) => (css) => {
12
- css.walkRules((rule) => {
13
- rule.selector = rule.selector.replace(opts.match, opts.replace);
14
- });
15
- };
16
- selectorReplacerPlugin.postcss = true;
17
-
18
10
  export async function execute() {
19
11
  if (!fs.existsSync(path.join(cwd, CLASS_MAP_FILE))) {
20
12
  const script = await readScript("build_class_modules");
@@ -25,15 +17,27 @@ export async function execute() {
25
17
  const parsedCss = fs
26
18
  .readdirSync(SRC_DIR, { recursive: true })
27
19
  .filter((e) => e.endsWith(EXTENSION))
28
- .map((e) => [
20
+ .map((e) => [e, path.basename(e, EXTENSION)])
21
+ .map(([e, name]) => [
29
22
  e,
30
- postcss(
31
- selectorReplacerPlugin({
32
- match: /#(\w+)/g,
33
- replace: (_, s) =>
34
- `.${classes[path.basename(e, EXTENSION)][s]} /* ${s} */`,
35
- }),
36
- ).process(readFile(path.join(SRC_DIR, e)), {
23
+ usePostcss({
24
+ match: /#(\w+)/g,
25
+ replace: (_, s) => {
26
+ const mod = classes[name];
27
+ if (!mod) {
28
+ console.log("[%s] no such module", name);
29
+ return;
30
+ }
31
+
32
+ const id = mod[s];
33
+ if (!id) {
34
+ console.log("[%s] %o is undefined", name, `#${s}`);
35
+ return;
36
+ }
37
+
38
+ return `.${id} /* ${s} */`;
39
+ },
40
+ }).process(readFile(path.join(SRC_DIR, e)), {
37
41
  from: path.join(SRC_DIR, e),
38
42
  }),
39
43
  ]);
@@ -42,7 +46,5 @@ export async function execute() {
42
46
  for (const [file, result] of parsedCss) {
43
47
  fs.mkdirSync(path.join(DIST_DIR, path.dirname(file)), { recursive: true });
44
48
  fs.writeFileSync(path.join(DIST_DIR, file), (await result).css);
45
-
46
- console.log("Compiled %o", file);
47
49
  }
48
50
  }
@@ -0,0 +1,69 @@
1
+ import fs from "node:fs";
2
+ import { CLASS_MAP_FILE, readFile, usePostcss } from "../shared.js";
3
+
4
+ const OLD_CLASS_MAP_FILE = `old_${CLASS_MAP_FILE}`;
5
+
6
+ if ([CLASS_MAP_FILE, OLD_CLASS_MAP_FILE].some((e) => !fs.existsSync(e))) {
7
+ console.log("Usage:");
8
+ console.log(
9
+ "1. Run %o on stable Steam.",
10
+ "npx steam-theming-utils build_class_modules",
11
+ );
12
+ console.log("2. Move %o to %o.", CLASS_MAP_FILE, OLD_CLASS_MAP_FILE);
13
+ console.log("3. Run the same command on beta Steam.");
14
+ process.exit(1);
15
+ }
16
+
17
+ const selectorReplacerPlugin = (opts) => (css) => {
18
+ css.walkRules((rule) => {
19
+ rule.selector = rule.selector.replace(opts.match, opts.replace);
20
+ });
21
+ };
22
+ selectorReplacerPlugin.postcss = true;
23
+
24
+ const cwd = process.cwd();
25
+ const oldClasses = JSON.parse(fs.readFileSync(OLD_CLASS_MAP_FILE));
26
+ const newClasses = JSON.parse(fs.readFileSync(CLASS_MAP_FILE));
27
+ const modules = Object.keys(oldClasses);
28
+ const keys = modules
29
+ .map((e) => ({ [e]: Object.keys(oldClasses[e]) }))
30
+ .reduce((a, b) => Object.assign(a, b));
31
+
32
+ function findNewClassFromOld(oldName) {
33
+ for (const mod of modules) {
34
+ const className = keys[mod].find((e) => oldClasses[mod][e] === oldName);
35
+ const newName = newClasses[mod]?.[className];
36
+ if (!newName) {
37
+ continue;
38
+ }
39
+
40
+ if (oldName !== newName) {
41
+ console.log("Changed %o to %o", oldName, newName);
42
+ }
43
+
44
+ return `.${newName}`;
45
+ }
46
+
47
+ return `.${oldName}`;
48
+ }
49
+
50
+ export async function execute() {
51
+ const parsedCss = fs
52
+ .readdirSync(cwd, { recursive: true })
53
+ .filter((e) => e.endsWith(".css"))
54
+ .map((e) => [
55
+ e,
56
+ usePostcss({
57
+ match: /\.([\w-]+)/g,
58
+ replace: (_, s) => findNewClassFromOld(s),
59
+ }).process(readFile(e), {
60
+ from: e,
61
+ }),
62
+ ]);
63
+
64
+ for (const [file, result] of parsedCss) {
65
+ fs.writeFileSync(file, (await result).css);
66
+
67
+ console.log("[%s] done", file);
68
+ }
69
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steam-theming-utils",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "description": "A collection of scripts for easier Steam theming",
5
5
  "repository": {
6
6
  "type": "git",
package/shared.js CHANGED
@@ -1,8 +1,16 @@
1
1
  import cdp from "chrome-remote-interface";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import postcss from "postcss";
4
5
  import { fileURLToPath } from "node:url";
5
6
 
7
+ const selectorReplacerPlugin = (opts) => (css) => {
8
+ css.walkRules((rule) => {
9
+ rule.selector = rule.selector.replace(opts.match, opts.replace);
10
+ });
11
+ };
12
+ selectorReplacerPlugin.postcss = true;
13
+
6
14
  export const connection = await cdp({
7
15
  host: "127.0.0.1",
8
16
  port: 8080,
@@ -24,7 +32,7 @@ export const SCRIPT_PATH = path.join(packagePath, "lib");
24
32
 
25
33
  export const readFile = (file) => fs.readFileSync(file).toString();
26
34
  export const readScript = async (name) =>
27
- await import(path.join(SCRIPT_PATH, `${name}.js`));
35
+ await import(`file://${path.join(SCRIPT_PATH, `${name}.js`)}`);
28
36
  export const run = async (expression) =>
29
37
  await connection.Runtime.evaluate({
30
38
  expression,
@@ -36,3 +44,4 @@ export const runCdpFile = async (file) =>
36
44
  export const runWithResult = async (expression) =>
37
45
  (await run(expression)).result.value;
38
46
  export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
47
+ export const usePostcss = (opts) => postcss(selectorReplacerPlugin(opts));