@neonwilderness/moveskins 1.3.0 → 1.4.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/CHANGELOG.md CHANGED
@@ -1,8 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.1 (11.05.2026)
4
+
5
+ - Integrate .oxlint and .oxfmt configs into vite.config.js file
6
+ - Run vp check:fix to finally apply formatting rules
7
+
8
+ ## 1.4.0 (07.05.2026)
9
+
10
+ - Add --layout CLI param string to address different Twoday layouts for up-/downloads
11
+
3
12
  ## 1.3.0 (02.05.2026)
4
13
 
5
- - Add --toolbar CLI switch to additionally download 3 related modToolbar skins
14
+ - Add --toolbar CLI switch to additionally download 3 related modToolbar skins
6
15
 
7
16
  ## 1.2.0 (25.04.2026)
8
17
 
package/dist/index.js CHANGED
@@ -61354,7 +61354,10 @@ var E_ = A(process.cwd(), "skins"), D_ = A(process.cwd(), "backup"), O_ = A(E_,
61354
61354
  try {
61355
61355
  await e.login();
61356
61356
  for (let r of t) {
61357
- console.log(Fi.green(`\nNow processing alias "${r}"...`));
61357
+ if (console.log(Fi.green(`\nNow processing alias "${r}"...`)), n.layout) {
61358
+ let t = await e.useLayout(r, n.layout);
61359
+ console.log(Fi.green(`Switching to layout "${t.activeLayoutName} of alias "${r}".`));
61360
+ }
61358
61361
  let t = A_(r, n.backup), i = await e.getModifiedSkins(r), a = {};
61359
61362
  i.length && !v(t) && y(t), console.log(Fi.yellow(`${r} has ${i.length} modified skin${i.length === 1 ? "" : "s"}`)), n.skin && console.log(Fi.yellow(`Filtering skins for ${n.skin}.`));
61360
61363
  for (let t of i) {
@@ -61406,7 +61409,10 @@ var E_ = A(process.cwd(), "skins"), D_ = A(process.cwd(), "backup"), O_ = A(E_,
61406
61409
  try {
61407
61410
  await e.login();
61408
61411
  for (let r of t) {
61409
- console.log(Fi.green(`\nNow processing alias "${r}"...`));
61412
+ if (console.log(Fi.green(`\nNow processing alias "${r}"...`)), n.layout) {
61413
+ let t = await e.useLayout(r, n.layout);
61414
+ console.log(Fi.green(`Switching to layout "${t.activeLayoutName} of alias "${r}".`));
61415
+ }
61410
61416
  let t = M_(r, n.backup);
61411
61417
  console.log(Fi.yellow(`${r} has ${t.length} local skins. `) + Fi.red(`${t.length === 0 ? "Got nothing to do!" : ""}`)), n.skin && console.log(Fi.yellow(`Filtering skins for ${n.skin}.`));
61412
61418
  let i = await e.getModifiedSkins(r), a = new Set(i.map((e) => e.name)), o = A_(r, n.backup);
@@ -61576,6 +61582,12 @@ Make sure to add them to ${t} or directly to the environment.`, o = e ? "" : "If
61576
61582
  description: "Skin selection string (regex) to filter the skins to upload",
61577
61583
  type: "string"
61578
61584
  },
61585
+ layout: {
61586
+ alias: "l",
61587
+ description: "Uses this layout name for all subsequent actions",
61588
+ default: "",
61589
+ type: "string"
61590
+ },
61579
61591
  modules: {
61580
61592
  alias: "m",
61581
61593
  description: "Download sidebar module skins/freetext as well",
@@ -61621,6 +61633,7 @@ else {
61621
61633
  e === "down" && W_.clean && (j_(q_, W_.backup), console.log(Fi.yellow(`Cleaning target download folder/s for "${q_}".`))), console.log(`Start ${e}loading modified skins of alias${q_.length > 1 ? "es" : ""} ${Fi.yellow(q_.join(", "))} ${t} remote ${Fi.green(K_.fullDomain)}...`), n(K_, q_, {
61622
61634
  backup: W_.backup,
61623
61635
  debug: W_.debug,
61636
+ layout: W_.layout,
61624
61637
  modules: W_.modules,
61625
61638
  skin: W_.skin ? new RegExp(W_.skin) : null,
61626
61639
  toolbar: W_.toolbar
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neonwilderness/moveskins",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "Download/Upload/Compare modified skins for selected aliases on Twoday",
5
5
  "keywords": [
6
6
  "antville",
package/src/_compare.js CHANGED
@@ -1,18 +1,20 @@
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
1
4
  /**
2
5
  * Compare
3
6
  * =======
4
7
  *
5
8
  */
6
- import chalk from "chalk";
7
- import { readFileSync, writeFileSync } from "node:fs";
8
- import { resolve } from "node:path";
9
- import { aliasSkinFolder, getLocalSkins, skinRegister, splitAliases } from "./_utils.js";
9
+ import chalk from 'chalk';
10
+
11
+ import { aliasSkinFolder, getLocalSkins, skinRegister, splitAliases } from './_utils.js';
10
12
 
11
13
  const classToColor = {
12
- different: "cyan",
13
- identical: "grey",
14
- new: "green",
15
- untouched: "grey",
14
+ different: 'cyan',
15
+ identical: 'grey',
16
+ new: 'green',
17
+ untouched: 'grey'
16
18
  };
17
19
 
18
20
  /**
@@ -36,28 +38,24 @@ const skinsByName = (skinA, skinB) => {
36
38
  const compareLocalToRemoteSkins = async (td, aliases) => {
37
39
  const alpineView = { aliases: [] };
38
40
  try {
39
- if (typeof aliases === "string") aliases = [aliases];
41
+ if (typeof aliases === 'string') aliases = [aliases];
40
42
 
41
43
  await td.login();
42
44
 
43
45
  for (let alias of aliases) {
44
- let aliasView = { header: "", skins: [] };
46
+ let aliasView = { header: '', skins: [] };
45
47
  let localAlias = alias;
46
48
  let remoteAlias = alias;
47
- if (alias.includes(":")) [localAlias, remoteAlias] = splitAliases(alias, ":");
49
+ if (alias.includes(':')) [localAlias, remoteAlias] = splitAliases(alias, ':');
48
50
  aliasView.header = `Now comparing local alias "${localAlias}" to remote ${td.platform.toUpperCase()} alias "${remoteAlias}@${td.fullDomain}" [${new Date().toLocaleString()}] ...`;
49
51
  console.log(chalk.green(`\n${aliasView.header}`));
50
- aliasView.header = aliasView.header
51
- .replace("local", "<ins>local</ins>")
52
- .replace("remote", "<del>remote</del>");
52
+ aliasView.header = aliasView.header.replace('local', '<ins>local</ins>').replace('remote', '<del>remote</del>');
53
53
 
54
54
  const aliasSkinDir = aliasSkinFolder(localAlias, false);
55
55
  const localSkinData = getLocalSkins(localAlias, false)
56
56
  .map((skinFile) => {
57
57
  const localSkin = skinRegister.getData(skinFile);
58
- localSkin.skin = readFileSync(resolve(aliasSkinDir, skinFile))
59
- .toString()
60
- .replace(/\r\n/g, "\n");
58
+ localSkin.skin = readFileSync(resolve(aliasSkinDir, skinFile)).toString().replace(/\r\n/g, '\n');
61
59
  return localSkin;
62
60
  })
63
61
  .sort(skinsByName);
@@ -85,7 +83,7 @@ const compareLocalToRemoteSkins = async (td, aliases) => {
85
83
  if (lName === rName) {
86
84
  console.log(chalk.white(`Processing skin ${chalk.italic(lName)}`));
87
85
  let skinDiff = td.diffSkin(lName, remoteSkinData[r], localSkinData[l]);
88
- skinView.class = skinDiff.skinChanged ? "different" : "identical";
86
+ skinView.class = skinDiff.skinChanged ? 'different' : 'identical';
89
87
  skinView.open = skinDiff.skinChanged;
90
88
  skinView.text = `${skinDiff.skinName} is ${skinView.class}.`;
91
89
  skinView.results = skinDiff.results;
@@ -94,12 +92,12 @@ const compareLocalToRemoteSkins = async (td, aliases) => {
94
92
  } else {
95
93
  if (lName < rName) {
96
94
  skinView.text = `Local skin ${lName} missing on remote. Will be created upon update!`;
97
- skinView.class = "new";
95
+ skinView.class = 'new';
98
96
  l++;
99
97
  } else {
100
98
  // lName > rName
101
99
  skinView.text = `Remote skin ${rName} without local counterpart. Will remain untouched upon update!`;
102
- skinView.class = "untouched";
100
+ skinView.class = 'untouched';
103
101
  r++;
104
102
  }
105
103
  console.log(chalk[classToColor[skinView.class]](skinView.text));
@@ -109,21 +107,16 @@ const compareLocalToRemoteSkins = async (td, aliases) => {
109
107
  alpineView.aliases.push(aliasView);
110
108
  }
111
109
 
110
+ writeFileSync(resolve(process.cwd(), './src/template.json'), JSON.stringify(alpineView, null, 2));
111
+ const alpineTemplate = readFileSync(resolve(process.cwd(), './src/template.html')).toString().trim();
112
112
  writeFileSync(
113
- resolve(process.cwd(), "./src/template.json"),
114
- JSON.stringify(alpineView, null, 2),
115
- );
116
- const alpineTemplate = readFileSync(resolve(process.cwd(), "./src/template.html"))
117
- .toString()
118
- .trim();
119
- writeFileSync(
120
- resolve(process.cwd(), "./report.html"),
121
- alpineTemplate.replace("$$templateJSON", `(${JSON.stringify(alpineView, null, 2)})`),
113
+ resolve(process.cwd(), './report.html'),
114
+ alpineTemplate.replace('$$templateJSON', `(${JSON.stringify(alpineView, null, 2)})`)
122
115
  );
123
116
 
124
- console.log(chalk.green("Local/Remote comparison completed."));
117
+ console.log(chalk.green('Local/Remote comparison completed.'));
125
118
  } catch (e) {
126
- console.log(chalk.red(`Error while comparing skins: ${e}`));
119
+ console.log(chalk.red(`Error while comparing skins: ${e.toString()}`));
127
120
  }
128
121
  };
129
122
 
package/src/_download.js CHANGED
@@ -1,12 +1,14 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
1
4
  /**
2
5
  * Download
3
6
  * ========
4
7
  *
5
8
  */
6
- import chalk from "chalk";
7
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
8
- import { resolve } from "node:path";
9
- import { aliasSkinFolder, skinRegister } from "./_utils.js";
9
+ import chalk from 'chalk';
10
+
11
+ import { aliasSkinFolder, skinRegister } from './_utils.js';
10
12
 
11
13
  const capitalize = (text) => text.charAt(0).toUpperCase() + text.slice(1);
12
14
 
@@ -21,7 +23,7 @@ const findEmbeddedSkinMacros = async (td, alias, skinContent, skinContainer) =>
21
23
  const layoutUrl = await td.getActiveLayoutUrl(alias);
22
24
  const { skin } = await td.getSkin({
23
25
  name: skinName,
24
- url: `${layoutUrl}/skins/edit?key=${skinName}`,
26
+ url: `${layoutUrl}/skins/edit?key=${skinName}`
25
27
  });
26
28
  skinContainer[skinName] = skin;
27
29
  skinContainer = await findEmbeddedSkinMacros(td, alias, skin, skinContainer);
@@ -42,15 +44,19 @@ const downloadModifiedSkins = async (td, aliases, options) => {
42
44
 
43
45
  for (let alias of aliases) {
44
46
  console.log(chalk.green(`\nNow processing alias "${alias}"...`));
47
+
48
+ if (options.layout) {
49
+ const layout = await td.useLayout(alias, options.layout);
50
+ console.log(chalk.green(`Switching to layout "${layout.activeLayoutName} of alias "${alias}".`));
51
+ }
52
+
45
53
  const aliasSkinDir = aliasSkinFolder(alias, options.backup);
46
54
  const modifiedSkins = await td.getModifiedSkins(alias);
47
55
  let skinContainer = {};
48
56
 
49
57
  if (modifiedSkins.length && !existsSync(aliasSkinDir)) mkdirSync(aliasSkinDir);
50
58
  console.log(
51
- chalk.yellow(
52
- `${alias} has ${modifiedSkins.length} modified skin${modifiedSkins.length !== 1 ? "s" : ""}`,
53
- ),
59
+ chalk.yellow(`${alias} has ${modifiedSkins.length} modified skin${modifiedSkins.length !== 1 ? 's' : ''}`)
54
60
  );
55
61
  if (options.skin) console.log(chalk.yellow(`Filtering skins for ${options.skin}.`));
56
62
 
@@ -86,12 +92,12 @@ const downloadModifiedSkins = async (td, aliases, options) => {
86
92
 
87
93
  if (options.toolbar) {
88
94
  const layoutUrl = await td.getActiveLayoutUrl(alias);
89
- for (const s of ["Main", "DropDowns", "Closed"]) {
95
+ for (const s of ['Main', 'DropDowns', 'Closed']) {
90
96
  const name = `Site.modToolbar${s}`;
91
97
  console.log(chalk.gray(`Reading "${name}".`));
92
98
  const { title, description, skin } = await td.getSkin({
93
99
  name,
94
- url: `${layoutUrl}/skins/edit?key=${name}`,
100
+ url: `${layoutUrl}/skins/edit?key=${name}`
95
101
  });
96
102
  skinRegister.setData(name, title, description);
97
103
  skinContainer[name] = skin;
@@ -102,9 +108,9 @@ const downloadModifiedSkins = async (td, aliases, options) => {
102
108
  writeFileSync(resolve(aliasSkinDir, `${name}.skin`), content);
103
109
  }
104
110
  }
105
- console.log(chalk.green("Download completed."));
111
+ console.log(chalk.green('Download completed.'));
106
112
  } catch (e) {
107
- console.log(chalk.red(`Error while downloading skins: ${e}`));
113
+ console.log(chalk.red(`Error while downloading skins: ${e.toString()}`));
108
114
  } finally {
109
115
  skinRegister.store();
110
116
  }
package/src/_upload.js CHANGED
@@ -1,12 +1,14 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
1
4
  /**
2
5
  * Upload
3
6
  * ======
4
7
  *
5
8
  */
6
- import chalk from "chalk";
7
- import { readFileSync } from "node:fs";
8
- import { resolve } from "node:path";
9
- import { aliasSkinFolder, getLocalSkins, skinRegister } from "./_utils.js";
9
+ import chalk from 'chalk';
10
+
11
+ import { aliasSkinFolder, getLocalSkins, skinRegister } from './_utils.js';
10
12
 
11
13
  /**
12
14
  * Uploads all local skins of selected aliases to the target platform
@@ -20,10 +22,16 @@ const uploadModifiedSkins = async (td, aliases, options) => {
20
22
 
21
23
  for (let alias of aliases) {
22
24
  console.log(chalk.green(`\nNow processing alias "${alias}"...`));
25
+
26
+ if (options.layout) {
27
+ const layout = await td.useLayout(alias, options.layout);
28
+ console.log(chalk.green(`Switching to layout "${layout.activeLayoutName} of alias "${alias}".`));
29
+ }
30
+
23
31
  const localSkinFiles = getLocalSkins(alias, options.backup);
24
32
  console.log(
25
33
  chalk.yellow(`${alias} has ${localSkinFiles.length} local skins. `) +
26
- chalk.red(`${localSkinFiles.length === 0 ? "Got nothing to do!" : ""}`),
34
+ chalk.red(`${localSkinFiles.length === 0 ? 'Got nothing to do!' : ''}`)
27
35
  );
28
36
  if (options.skin) console.log(chalk.yellow(`Filtering skins for ${options.skin}.`));
29
37
 
@@ -32,15 +40,13 @@ const uploadModifiedSkins = async (td, aliases, options) => {
32
40
  const aliasSkinDir = aliasSkinFolder(alias, options.backup);
33
41
 
34
42
  for (let skinFile of localSkinFiles) {
35
- if (!skinFile.endsWith(".skin")) continue;
43
+ if (!skinFile.endsWith('.skin')) continue;
36
44
  if (options.skin && !options.skin.test(skinFile)) continue;
37
45
 
38
- const [hoptype, name] = skinFile.split(".");
39
- if (hoptype === "Sidebar") {
40
- const module = readFileSync(resolve(aliasSkinDir, skinFile))
41
- .toString()
42
- .replace(/\r\n/g, "\n");
43
- let splitAt = module.indexOf("\n");
46
+ const [hoptype, name] = skinFile.split('.');
47
+ if (hoptype === 'Sidebar') {
48
+ const module = readFileSync(resolve(aliasSkinDir, skinFile)).toString().replace(/\r\n/g, '\n');
49
+ let splitAt = module.indexOf('\n');
44
50
  const heading = module.slice(0, splitAt);
45
51
  const content = module.slice(++splitAt);
46
52
  console.log(chalk.blue(`Now updating sidebar module ${name} (len=${content.length}).`));
@@ -49,24 +55,18 @@ const uploadModifiedSkins = async (td, aliases, options) => {
49
55
  } else {
50
56
  const { isValid, prototype } = td.isValidHoptype(skinFile.slice(0, -5));
51
57
  if (!isValid) {
52
- console.log(
53
- chalk.red(
54
- `Skipping upload for invalid skin hoptype "${prototype}" (Skin file ${skinFile}).`,
55
- ),
56
- );
58
+ console.log(chalk.red(`Skipping upload for invalid skin hoptype "${prototype}" (Skin file ${skinFile}).`));
57
59
  continue;
58
60
  }
59
61
  const skin = skinRegister.getData(skinFile);
60
- skin.content = readFileSync(resolve(aliasSkinDir, skinFile))
61
- .toString()
62
- .replace(/\r\n/g, "\n");
62
+ skin.content = readFileSync(resolve(aliasSkinDir, skinFile)).toString().replace(/\r\n/g, '\n');
63
63
 
64
64
  console.log(chalk.blue(`Now updating skin ${skin.name} (len=${skin.content.length}).`));
65
65
  await td.updateSkin(alias, skin.name, {
66
66
  title: skin.title,
67
67
  description: skin.description,
68
68
  skin: skin.content,
69
- diff: options.debug,
69
+ diff: options.debug
70
70
  });
71
71
  console.log(chalk.green(`Update request completed for skin: ${skin.name}`));
72
72
  }
@@ -75,15 +75,13 @@ const uploadModifiedSkins = async (td, aliases, options) => {
75
75
  }
76
76
 
77
77
  if (currentSkins.size > 0) {
78
- console.log(
79
- chalk.blue(`\nFollowing skins exist on "${alias}" and were not touched by this upload:`),
80
- );
78
+ console.log(chalk.blue(`\nFollowing skins exist on "${alias}" and were not touched by this upload:`));
81
79
  currentSkins.forEach((skinName) => console.log(`--> ${chalk.blue(skinName)}`));
82
80
  }
83
81
  }
84
- console.log(chalk.green("Upload completed."));
82
+ console.log(chalk.green('Upload completed.'));
85
83
  } catch (e) {
86
- console.log(chalk.red(`Error while uploading skins: ${e}`));
84
+ console.log(chalk.red(`Error while uploading skins: ${e.toString()}`));
87
85
  }
88
86
  };
89
87
 
package/src/_utils.js CHANGED
@@ -1,23 +1,22 @@
1
+ import { existsSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
1
4
  /**
2
5
  * Utility functions
3
6
  * =================
4
7
  *
5
8
  */
6
- import { deleteSync } from "del";
7
- import { existsSync, readFileSync, writeFileSync, readdirSync } from "node:fs";
8
- import { resolve } from "node:path";
9
+ import { deleteSync } from 'del';
9
10
 
10
11
  // Read centrally stored skin header data (name => title, description)
11
- const skinsFolder = resolve(process.cwd(), "skins");
12
- const backupFolder = resolve(process.cwd(), "backup");
13
- const pathToRegister = resolve(skinsFolder, "skinRegister.json");
12
+ const skinsFolder = resolve(process.cwd(), 'skins');
13
+ const backupFolder = resolve(process.cwd(), 'backup');
14
+ const pathToRegister = resolve(skinsFolder, 'skinRegister.json');
14
15
  const skinRegister = {
15
16
  data: undefined,
16
17
  hasChanged: false,
17
18
  load() {
18
- this.data = existsSync(pathToRegister)
19
- ? JSON.parse(readFileSync(pathToRegister).toString())
20
- : {};
19
+ this.data = existsSync(pathToRegister) ? JSON.parse(readFileSync(pathToRegister).toString()) : {};
21
20
  return this.data;
22
21
  },
23
22
  store() {
@@ -27,17 +26,17 @@ const skinRegister = {
27
26
  }
28
27
  },
29
28
  hasData(skinName) {
30
- if (typeof this.data === "undefined") this.load();
29
+ if (typeof this.data === 'undefined') this.load();
31
30
  return this.data.hasOwnProperty(skinName);
32
31
  },
33
32
  getData(skinFileOrName) {
34
- const name = skinFileOrName.endsWith(".skin")
33
+ const name = skinFileOrName.endsWith('.skin')
35
34
  ? skinFileOrName.substr(0, skinFileOrName.length - 5)
36
35
  : skinFileOrName;
37
36
  if (this.hasData(name)) {
38
37
  const { title, description } = this.data[name];
39
38
  return { name, title, description };
40
- } else return { name, title: name, description: "" };
39
+ } else return { name, title: name, description: '' };
41
40
  },
42
41
  setData(skinName, title, description) {
43
42
  if (!this.hasData(skinName)) {
@@ -47,7 +46,7 @@ const skinRegister = {
47
46
  },
48
47
  deleteData(skinName) {
49
48
  if (this.hasData(skinName)) delete this.data[skinName];
50
- },
49
+ }
51
50
  };
52
51
 
53
52
  /**
@@ -65,7 +64,7 @@ const aliasSkinFolder = (alias, isBackup) => resolve(isBackup ? backupFolder : s
65
64
  */
66
65
  const cleanupAliasFolder = (aliases, isBackup) => {
67
66
  try {
68
- deleteSync(aliases.map((alias) => resolve(aliasSkinFolder(alias, isBackup), "*.skin")));
67
+ deleteSync(aliases.map((alias) => resolve(aliasSkinFolder(alias, isBackup), '*.skin')));
69
68
  } catch (err) {
70
69
  console.log(`cleanupAliasFolder ended with error: ${err.toString()}.`);
71
70
  process.exit(1);
@@ -79,9 +78,7 @@ const cleanupAliasFolder = (aliases, isBackup) => {
79
78
  */
80
79
  const getLocalSkins = (alias, isBackup) => {
81
80
  const aliasSkinDir = aliasSkinFolder(alias, isBackup);
82
- return existsSync(aliasSkinDir)
83
- ? readdirSync(aliasSkinDir).filter((file) => file.endsWith(".skin"))
84
- : [];
81
+ return existsSync(aliasSkinDir) ? readdirSync(aliasSkinDir).filter((file) => file.endsWith('.skin')) : [];
85
82
  };
86
83
 
87
84
  /**
@@ -97,11 +94,4 @@ const splitAliases = (aliases, delimiter) => {
97
94
  .map((alias) => alias.toLowerCase());
98
95
  };
99
96
 
100
- export {
101
- pathToRegister,
102
- skinRegister,
103
- aliasSkinFolder,
104
- cleanupAliasFolder,
105
- getLocalSkins,
106
- splitAliases,
107
- };
97
+ export { pathToRegister, skinRegister, aliasSkinFolder, cleanupAliasFolder, getLocalSkins, splitAliases };
package/src/create.js CHANGED
@@ -1,65 +1,63 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import * as Twoday from '@neonwilderness/twoday';
5
+ import chalk from 'chalk';
1
6
  /**
2
7
  * Creates a new skin locally
3
8
  */
4
- import yargs from "yargs/yargs";
5
- import chalk from "chalk";
6
- import fs from "node:fs";
7
- import path from "node:path";
8
- import * as Twoday from "@neonwilderness/twoday";
9
- import { skinRegister } from "./_utils.js";
9
+ import yargs from 'yargs/yargs';
10
+
11
+ import { skinRegister } from './_utils.js';
10
12
  const argv = yargs(process.argv.slice(2)).argv;
11
13
 
12
14
  // Validates script param --alias (blog name/alias)
13
15
  if (!argv.alias) {
14
- console.log(chalk.red("Error: You must specify a blogname alias with --alias={alias} !!"));
16
+ console.log(chalk.red('Error: You must specify a blogname alias with --alias={alias} !!'));
15
17
  process.exit(1);
16
18
  }
17
19
  const alias = argv.alias.trim().toLowerCase();
18
20
 
19
21
  // Validates script param --skin (skin name to be created)
20
22
  if (!argv.skin) {
21
- console.log(
22
- chalk.red("Error: You must specify a skin name to be created with --skin={skinname} !!"),
23
- );
24
- console.log(chalk.blue("Example: node ./src/create --alias=info --skin=Site.mynewskin"));
23
+ console.log(chalk.red('Error: You must specify a skin name to be created with --skin={skinname} !!'));
24
+ console.log(chalk.blue('Example: node ./src/create --alias=info --skin=Site.mynewskin'));
25
25
  process.exit(1);
26
26
  }
27
27
  const skinName = argv.skin;
28
28
 
29
29
  // Validates skin name syntax (must have 2 strings around a dot)
30
- const nameParts = skinName.split(".").reduce((all, part) => {
30
+ const nameParts = skinName.split('.').reduce((all, part) => {
31
31
  if (part.trim().length) all.push(part);
32
32
  return all;
33
33
  }, []);
34
34
  if (nameParts.length !== 2) {
35
35
  console.log(chalk.red(`Error: Wrong skin name syntax "${skinName}" !!`));
36
- console.log(chalk.blue("Use skin name syntax: --skin={hoptype}.{name}"));
36
+ console.log(chalk.blue('Use skin name syntax: --skin={hoptype}.{name}'));
37
37
  process.exit(1);
38
38
  }
39
39
 
40
40
  // Main async function to validate hoptype, register the skin and create the physical skin file
41
41
  (async () => {
42
42
  try {
43
- const td = new Twoday.Twoday("prod");
43
+ const td = new Twoday.Twoday('prod');
44
44
  const { valid, prototype, _name } = await td.isValidHoptype(skinName);
45
45
 
46
46
  if (!valid) {
47
- console.log(
48
- chalk.red(`Error: Sorry, there is no Hoptype "${prototype}" in the Twoday code base!!`),
49
- );
47
+ console.log(chalk.red(`Error: Sorry, there is no Hoptype "${prototype}" in the Twoday code base!!`));
50
48
  process.exit(1);
51
49
  }
52
50
 
53
51
  skinRegister.load();
54
- const newSkin = "(new skin)";
52
+ const newSkin = '(new skin)';
55
53
  skinRegister.setData(skinName, `${skinName} ${newSkin}`, `${newSkin}`);
56
54
  skinRegister.store();
57
55
 
58
- const dir = path.resolve(process.cwd(), "skins", alias);
56
+ const dir = path.resolve(process.cwd(), 'skins', alias);
59
57
  if (!fs.existsSync(dir)) fs.mkdirSync(dir);
60
58
  fs.writeFileSync(path.resolve(dir, `${skinName}.skin`), `<p><!-- ${newSkin} --></p>\n`);
61
59
  console.log(chalk.green(`New skin "${skinName}" successfully established in /skins/${alias}.`));
62
60
  } catch (e) {
63
- console.log(chalk.red(`An error occured while creating the new skin "${skinName}": ${e}`));
61
+ console.log(chalk.red(`An error occured while creating the new skin "${skinName}": ${e.toString()}`));
64
62
  }
65
63
  })();
package/src/images.js CHANGED
@@ -1,24 +1,25 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import * as Twoday from '@neonwilderness/twoday';
5
+ import chalk from 'chalk';
6
+ import { config } from 'dotenv-safe';
1
7
  /**
2
8
  * Upload /skins/{alias}/images items to create layout images
3
9
  */
4
- import yargs from "yargs/yargs";
5
- import chalk from "chalk";
6
- import fs from "node:fs";
7
- import path from "node:path";
8
- import * as Twoday from "@neonwilderness/twoday";
9
- import { config } from "dotenv-safe";
10
+ import yargs from 'yargs/yargs';
10
11
  config();
11
12
  const argv = yargs(process.argv.slice(2)).argv;
12
13
 
13
14
  // Validates script param --alias (blog name/alias)
14
15
  if (!argv.alias) {
15
- console.log(chalk.red("Error: You must specify a blogname alias with --alias={alias} !!"));
16
+ console.log(chalk.red('Error: You must specify a blogname alias with --alias={alias} !!'));
16
17
  process.exit(1);
17
18
  }
18
19
  const alias = argv.alias.trim().toLowerCase();
19
20
 
20
- if (!argv.to || (argv.to !== "dev" && argv.to !== "prod")) {
21
- console.log("Error: You must specify a target platform with --to=dev|prod");
21
+ if (!argv.to || (argv.to !== 'dev' && argv.to !== 'prod')) {
22
+ console.log('Error: You must specify a target platform with --to=dev|prod');
22
23
  process.exit(1);
23
24
  }
24
25
  const platform = argv.to.toLowerCase();
@@ -28,7 +29,7 @@ const platform = argv.to.toLowerCase();
28
29
  const td = new Twoday.Twoday(platform);
29
30
  await td.login();
30
31
 
31
- const imageFolder = path.resolve(process.cwd(), "skins", alias, "images");
32
+ const imageFolder = path.resolve(process.cwd(), 'skins', alias, 'images');
32
33
  if (!fs.existsSync(imageFolder)) {
33
34
  console.log(chalk.red(`Error: image folder for alias ${alias} does not exist!!`));
34
35
  process.exit(1);
@@ -37,18 +38,18 @@ const platform = argv.to.toLowerCase();
37
38
  const images = fs.readdirSync(imageFolder);
38
39
  let uploaded = 0;
39
40
  for (const image of images) {
40
- const [name, _ext] = image.split(".");
41
- if (name.startsWith("_")) continue;
41
+ const [name, _ext] = image.split('.');
42
+ if (name.startsWith('_')) continue;
42
43
  const imgID = await td.createImage(alias, {
43
44
  alias: name,
44
- path: path.resolve(imageFolder, image),
45
+ path: path.resolve(imageFolder, image)
45
46
  });
46
47
  uploaded++;
47
48
  console.log(chalk.green(`New image "${image}" =>${imgID} saved.`));
48
49
  }
49
50
  console.log(chalk.blue(`${uploaded} images uploaded to alias "${alias}".`));
50
51
  } catch (e) {
51
- console.log(chalk.red(`Error while creating images for alias "${alias}": ${e}`));
52
+ console.log(chalk.red(`Error while creating images for alias "${alias}": ${e.toString()}`));
52
53
  } finally {
53
54
  await td.logout();
54
55
  }
package/src/index.js CHANGED
@@ -11,120 +11,127 @@
11
11
  * An Alias of * is equal to the core Twoday blogs: www,info,help,top
12
12
  * User/Psw in .env file needs to have admin rights on the selected alias(es) or it won't work!
13
13
  */
14
- import yargs from "yargs/yargs";
14
+ import yargs from 'yargs/yargs';
15
15
  const argv = yargs(process.argv.slice(2)).options({
16
16
  from: {
17
- alias: "f",
17
+ alias: 'f',
18
18
  description: 'Platform where to download the skins from: "dev" or "prod"',
19
- type: "string",
19
+ type: 'string'
20
20
  },
21
21
  to: {
22
- alias: "t",
22
+ alias: 't',
23
23
  description: 'Platform where to compare or upload the skins to: "dev" or "prod"',
24
- type: "string",
24
+ type: 'string'
25
25
  },
26
26
  alias: {
27
- alias: "a",
28
- description: "One or more alias blog name/s delimited by comma (no space)",
29
- type: "string",
27
+ alias: 'a',
28
+ description: 'One or more alias blog name/s delimited by comma (no space)',
29
+ type: 'string'
30
30
  },
31
31
  skin: {
32
- alias: "s",
33
- description: "Skin selection string (regex) to filter the skins to upload",
34
- type: "string",
32
+ alias: 's',
33
+ description: 'Skin selection string (regex) to filter the skins to upload',
34
+ type: 'string'
35
+ },
36
+ layout: {
37
+ alias: 'l',
38
+ description: 'Uses this layout name for all subsequent actions',
39
+ default: '',
40
+ type: 'string'
35
41
  },
36
42
  modules: {
37
- alias: "m",
38
- description: "Download sidebar module skins/freetext as well",
43
+ alias: 'm',
44
+ description: 'Download sidebar module skins/freetext as well',
39
45
  default: false,
40
- type: "boolean",
46
+ type: 'boolean'
41
47
  },
42
48
  toolbar: {
43
- description: "Download modToolbar skins, too",
49
+ description: 'Download modToolbar skins, too',
44
50
  default: false,
45
- type: "boolean",
51
+ type: 'boolean'
46
52
  },
47
53
  backup: {
48
- alias: "b",
49
- description: "Backup skins to the local /backup folder to preserve their former status",
50
- type: "boolean",
54
+ alias: 'b',
55
+ description: 'Backup skins to the local /backup folder to preserve their former status',
56
+ type: 'boolean'
51
57
  },
52
58
  clean: {
53
59
  default: false,
54
- description:
55
- "Cleanup (delete) the alias local skin directory to remove potential old files before new download",
56
- type: "boolean",
60
+ description: 'Cleanup (delete) the alias local skin directory to remove potential old files before new download',
61
+ type: 'boolean'
57
62
  },
58
63
  compare: {
59
64
  default: false,
60
- description: "Compare the local alias skin directory to a remote location (prod/dev)",
61
- type: "boolean",
65
+ description: 'Compare the local alias skin directory to a remote location (prod/dev)',
66
+ type: 'boolean'
62
67
  },
63
68
  debug: {
64
69
  default: false,
65
- description: "Issue more logging messages and diff analysis (for upload function)",
66
- type: "boolean",
67
- },
70
+ description: 'Issue more logging messages and diff analysis (for upload function)',
71
+ type: 'boolean'
72
+ }
68
73
  }).argv;
69
- import chalk from "chalk";
70
- import * as Twoday from "@neonwilderness/twoday";
71
- import { cleanupAliasFolder, splitAliases } from "./_utils.js";
72
- import { downloadModifiedSkins } from "./_download.js";
73
- import { uploadModifiedSkins } from "./_upload.js";
74
- import { compareLocalToRemoteSkins } from "./_compare.js";
75
- import { config } from "dotenv-safe";
74
+ import * as Twoday from '@neonwilderness/twoday';
75
+ import chalk from 'chalk';
76
+ import { config } from 'dotenv-safe';
77
+
78
+ import { compareLocalToRemoteSkins } from './_compare.js';
79
+ import { downloadModifiedSkins } from './_download.js';
80
+ import { uploadModifiedSkins } from './_upload.js';
81
+ import { cleanupAliasFolder, splitAliases } from './_utils.js';
76
82
  config();
77
83
 
78
84
  if (!argv.from && !argv.to) {
79
- console.log("Desired action must be specified with --from=dev|prod or --to=dev|prod");
85
+ console.log('Desired action must be specified with --from=dev|prod or --to=dev|prod');
80
86
  process.exit(1);
81
87
  }
82
88
  if (argv.from && argv.to) {
83
- console.log("You cannot specify --from=dev|prod AND --to=dev|prod in one run");
89
+ console.log('You cannot specify --from=dev|prod AND --to=dev|prod in one run');
84
90
  process.exit(1);
85
91
  }
86
92
  if (argv.compare && !argv.to) {
87
- console.log("You must specify a target platform with --to=dev|prod when comparing skins");
93
+ console.log('You must specify a target platform with --to=dev|prod when comparing skins');
88
94
  process.exit(1);
89
95
  }
90
96
  if (!argv.alias) {
91
- console.log("You must specify the desired alias(es) with --alias=name1[,name2,...] OR --alias=*");
97
+ console.log('You must specify the desired alias(es) with --alias=name1[,name2,...] OR --alias=*');
92
98
  process.exit(1);
93
99
  }
94
100
  const platform = (argv.from || argv.to).toLowerCase();
95
101
  const td = new Twoday.Twoday(platform, { delay: 100 });
96
102
 
97
- const core = ["www", "info", "help", "top"];
98
- const aliases = argv.alias === "*" ? core : splitAliases(argv.alias, ",");
103
+ const core = ['www', 'info', 'help', 'top'];
104
+ const aliases = argv.alias === '*' ? core : splitAliases(argv.alias, ',');
99
105
 
100
106
  if (argv.compare) {
101
- if (aliases.length === 1 && aliases[0].includes(":"))
107
+ if (aliases.length === 1 && aliases[0].includes(':'))
102
108
  console.log(
103
- `Start comparing local skin files of alias${aliases.length > 1 ? "es" : ""} ${chalk.yellow(
104
- aliases.join(", "),
105
- )} to ${chalk.green(td.fullDomain)}...`,
109
+ `Start comparing local skin files of alias${aliases.length > 1 ? 'es' : ''} ${chalk.yellow(
110
+ aliases.join(', ')
111
+ )} to ${chalk.green(td.fullDomain)}...`
106
112
  );
107
- compareLocalToRemoteSkins(td, aliases);
113
+ await compareLocalToRemoteSkins(td, aliases);
108
114
  } else {
109
- const action = argv.from ? "down" : "up";
110
- const direction = argv.from ? "from" : "to";
115
+ const action = argv.from ? 'down' : 'up';
116
+ const direction = argv.from ? 'from' : 'to';
111
117
  const execTask = argv.from ? downloadModifiedSkins : uploadModifiedSkins;
112
118
 
113
- if (action === "down" && argv.clean) {
119
+ if (action === 'down' && argv.clean) {
114
120
  cleanupAliasFolder(aliases, argv.backup);
115
- console.log(chalk.yellow(`Cleaning target download folder/s for "${aliases}".`));
121
+ console.log(chalk.yellow(`Cleaning target download folder/s for "${aliases.join(', ')}".`));
116
122
  }
117
123
 
118
124
  console.log(
119
- `Start ${action}loading modified skins of alias${aliases.length > 1 ? "es" : ""} ${chalk.yellow(
120
- aliases.join(", "),
121
- )} ${direction} remote ${chalk.green(td.fullDomain)}...`,
125
+ `Start ${action}loading modified skins of alias${aliases.length > 1 ? 'es' : ''} ${chalk.yellow(
126
+ aliases.join(', ')
127
+ )} ${direction} remote ${chalk.green(td.fullDomain)}...`
122
128
  );
123
- execTask(td, aliases, {
129
+ await execTask(td, aliases, {
124
130
  backup: argv.backup,
125
131
  debug: argv.debug,
132
+ layout: argv.layout,
126
133
  modules: argv.modules,
127
134
  skin: argv.skin ? new RegExp(argv.skin) : null,
128
- toolbar: argv.toolbar,
135
+ toolbar: argv.toolbar
129
136
  });
130
137
  }
package/src/template.html CHANGED
@@ -28,11 +28,11 @@
28
28
  text-align: center;
29
29
  }
30
30
  del::before {
31
- content: "";
31
+ content: '';
32
32
  background: #fdb9c1;
33
33
  }
34
34
  ins::before {
35
- content: "+";
35
+ content: '+';
36
36
  background: #abf2bc;
37
37
  }
38
38
  h3 {
@@ -50,7 +50,7 @@
50
50
  display: inline-block;
51
51
  background: #ddd;
52
52
  font-size: 11px;
53
- content: "Skin";
53
+ content: 'Skin';
54
54
  margin-right: 0.5rem;
55
55
  padding: 2px 4px;
56
56
  line-height: 1rem;
@@ -109,10 +109,7 @@
109
109
  <div class="resultbox" x-show="skin.open && skin.results.length">
110
110
  <template x-for="(result, ir) in skin.results" :key="ir">
111
111
  <div class="result">
112
- <div
113
- :style="{ color: result.itemChanged ? '#e53935' : '#bdbdbd' }"
114
- x-text="result.text"
115
- ></div>
112
+ <div :style="{ color: result.itemChanged ? '#e53935' : '#bdbdbd' }" x-text="result.text"></div>
116
113
  <div class="diffs" x-html="result.diffs.replace(/\n/g, '<br>')"></div>
117
114
  </div>
118
115
  </template>
@@ -123,8 +120,8 @@
123
120
  </template>
124
121
 
125
122
  <script>
126
- document.addEventListener("alpine:init", () => {
127
- Alpine.data("diffResults", () => $$templateJSON);
123
+ document.addEventListener('alpine:init', () => {
124
+ Alpine.data('diffResults', () => $$templateJSON);
128
125
  });
129
126
  </script>
130
127
  <script defer src="https://unpkg.com/alpinejs@latest"></script>