@lordbex/thelounge 4.4.4-blowfish → 4.5.0-blowfish-pre

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.
Files changed (140) hide show
  1. package/README.md +2 -2
  2. package/dist/defaults/config.js +31 -2
  3. package/dist/package.json +93 -91
  4. package/dist/server/client.js +188 -194
  5. package/dist/server/clientManager.js +65 -63
  6. package/dist/server/command-line/index.js +44 -43
  7. package/dist/server/command-line/install.js +37 -70
  8. package/dist/server/command-line/outdated.js +12 -17
  9. package/dist/server/command-line/start.js +25 -26
  10. package/dist/server/command-line/storage.js +26 -31
  11. package/dist/server/command-line/uninstall.js +16 -23
  12. package/dist/server/command-line/upgrade.js +20 -26
  13. package/dist/server/command-line/users/add.js +33 -40
  14. package/dist/server/command-line/users/edit.js +18 -24
  15. package/dist/server/command-line/users/index.js +12 -16
  16. package/dist/server/command-line/users/list.js +11 -39
  17. package/dist/server/command-line/users/remove.js +16 -22
  18. package/dist/server/command-line/users/reset.js +34 -35
  19. package/dist/server/command-line/utils.js +231 -87
  20. package/dist/server/config.js +61 -52
  21. package/dist/server/helper.js +29 -28
  22. package/dist/server/identification.js +39 -34
  23. package/dist/server/index.js +1 -3
  24. package/dist/server/log.js +19 -16
  25. package/dist/server/models/chan.js +36 -33
  26. package/dist/server/models/msg.js +15 -19
  27. package/dist/server/models/network.js +88 -86
  28. package/dist/server/models/prefix.js +4 -7
  29. package/dist/server/models/user.js +5 -10
  30. package/dist/server/path-helper.js +8 -0
  31. package/dist/server/plugins/auth/ldap.js +177 -112
  32. package/dist/server/plugins/auth/local.js +10 -15
  33. package/dist/server/plugins/auth.js +6 -35
  34. package/dist/server/plugins/changelog.js +30 -27
  35. package/dist/server/plugins/clientCertificate.js +33 -37
  36. package/dist/server/plugins/dev-server.js +15 -21
  37. package/dist/server/plugins/inputs/action.js +9 -14
  38. package/dist/server/plugins/inputs/away.js +1 -3
  39. package/dist/server/plugins/inputs/ban.js +9 -14
  40. package/dist/server/plugins/inputs/blow.js +9 -14
  41. package/dist/server/plugins/inputs/connect.js +5 -10
  42. package/dist/server/plugins/inputs/ctcp.js +7 -12
  43. package/dist/server/plugins/inputs/disconnect.js +1 -3
  44. package/dist/server/plugins/inputs/ignore.js +23 -29
  45. package/dist/server/plugins/inputs/ignorelist.js +12 -18
  46. package/dist/server/plugins/inputs/index.js +8 -34
  47. package/dist/server/plugins/inputs/invite.js +7 -12
  48. package/dist/server/plugins/inputs/kick.js +7 -12
  49. package/dist/server/plugins/inputs/kill.js +1 -3
  50. package/dist/server/plugins/inputs/list.js +1 -3
  51. package/dist/server/plugins/inputs/mode.js +10 -15
  52. package/dist/server/plugins/inputs/msg.js +13 -18
  53. package/dist/server/plugins/inputs/mute.js +9 -15
  54. package/dist/server/plugins/inputs/nick.js +9 -14
  55. package/dist/server/plugins/inputs/notice.js +5 -7
  56. package/dist/server/plugins/inputs/part.js +11 -16
  57. package/dist/server/plugins/inputs/quit.js +7 -13
  58. package/dist/server/plugins/inputs/rainbow.js +55 -0
  59. package/dist/server/plugins/inputs/raw.js +1 -3
  60. package/dist/server/plugins/inputs/rejoin.js +7 -12
  61. package/dist/server/plugins/inputs/topic.js +7 -12
  62. package/dist/server/plugins/inputs/whois.js +1 -3
  63. package/dist/server/plugins/irc-events/away.js +14 -20
  64. package/dist/server/plugins/irc-events/cap.js +16 -22
  65. package/dist/server/plugins/irc-events/chghost.js +14 -13
  66. package/dist/server/plugins/irc-events/connection.js +61 -63
  67. package/dist/server/plugins/irc-events/ctcp.js +22 -28
  68. package/dist/server/plugins/irc-events/error.js +20 -26
  69. package/dist/server/plugins/irc-events/help.js +7 -13
  70. package/dist/server/plugins/irc-events/info.js +7 -13
  71. package/dist/server/plugins/irc-events/invite.js +7 -13
  72. package/dist/server/plugins/irc-events/join.js +30 -27
  73. package/dist/server/plugins/irc-events/kick.js +21 -17
  74. package/dist/server/plugins/irc-events/link.js +75 -96
  75. package/dist/server/plugins/irc-events/list.js +23 -26
  76. package/dist/server/plugins/irc-events/message.js +46 -52
  77. package/dist/server/plugins/irc-events/mode.js +66 -63
  78. package/dist/server/plugins/irc-events/modelist.js +29 -35
  79. package/dist/server/plugins/irc-events/motd.js +10 -16
  80. package/dist/server/plugins/irc-events/names.js +3 -6
  81. package/dist/server/plugins/irc-events/nick.js +26 -23
  82. package/dist/server/plugins/irc-events/part.js +19 -15
  83. package/dist/server/plugins/irc-events/quit.js +17 -14
  84. package/dist/server/plugins/irc-events/sasl.js +9 -15
  85. package/dist/server/plugins/irc-events/spgroups.js +38 -0
  86. package/dist/server/plugins/irc-events/spjoin.js +52 -0
  87. package/dist/server/plugins/irc-events/topic.js +12 -18
  88. package/dist/server/plugins/irc-events/unhandled.js +12 -12
  89. package/dist/server/plugins/irc-events/welcome.js +7 -13
  90. package/dist/server/plugins/irc-events/whois.js +20 -24
  91. package/dist/server/plugins/massEventAggregator.js +214 -0
  92. package/dist/server/plugins/messageStorage/sqlite.js +322 -141
  93. package/dist/server/plugins/messageStorage/text.js +21 -26
  94. package/dist/server/plugins/packages/index.js +105 -74
  95. package/dist/server/plugins/packages/publicClient.js +7 -16
  96. package/dist/server/plugins/packages/themes.js +11 -16
  97. package/dist/server/plugins/storage.js +28 -33
  98. package/dist/server/plugins/sts.js +12 -17
  99. package/dist/server/plugins/uploader.js +40 -43
  100. package/dist/server/plugins/webpush.js +23 -51
  101. package/dist/server/server.js +318 -271
  102. package/dist/server/storageCleaner.js +29 -37
  103. package/dist/server/utils/fish.js +7 -14
  104. package/dist/shared/irc.js +3 -6
  105. package/dist/shared/linkify.js +7 -14
  106. package/dist/shared/types/chan.js +6 -9
  107. package/dist/shared/types/changelog.js +1 -2
  108. package/dist/shared/types/config.js +1 -2
  109. package/dist/shared/types/mention.js +1 -2
  110. package/dist/shared/types/msg.js +3 -5
  111. package/dist/shared/types/network.js +1 -2
  112. package/dist/shared/types/storage.js +1 -2
  113. package/dist/shared/types/user.js +1 -2
  114. package/index.js +14 -10
  115. package/package.json +93 -91
  116. package/public/css/style.css +9 -6
  117. package/public/css/style.css.map +1 -1
  118. package/public/fonts/font-awesome/fa-brands-400.ttf +0 -0
  119. package/public/fonts/font-awesome/fa-brands-400.woff2 +0 -0
  120. package/public/fonts/font-awesome/fa-duotone-900.ttf +0 -0
  121. package/public/fonts/font-awesome/fa-duotone-900.woff2 +0 -0
  122. package/public/fonts/font-awesome/fa-light-300.ttf +0 -0
  123. package/public/fonts/font-awesome/fa-light-300.woff2 +0 -0
  124. package/public/fonts/font-awesome/fa-regular-400.ttf +0 -0
  125. package/public/fonts/font-awesome/fa-regular-400.woff2 +0 -0
  126. package/public/fonts/font-awesome/fa-solid-900.ttf +0 -0
  127. package/public/fonts/font-awesome/fa-solid-900.woff2 +0 -0
  128. package/public/fonts/font-awesome/fa-thin-100.ttf +0 -0
  129. package/public/fonts/font-awesome/fa-thin-100.woff2 +0 -0
  130. package/public/fonts/font-awesome/fa-v4compatibility.ttf +0 -0
  131. package/public/fonts/font-awesome/fa-v4compatibility.woff2 +0 -0
  132. package/public/js/bundle.js +1 -1
  133. package/public/js/bundle.js.map +1 -1
  134. package/public/js/bundle.vendor.js +1 -1
  135. package/public/js/bundle.vendor.js.LICENSE.txt +24 -6
  136. package/public/js/bundle.vendor.js.map +1 -1
  137. package/public/service-worker.js +1 -1
  138. package/public/themes/default.css +1 -1
  139. package/public/themes/morning.css +1 -1
  140. package/dist/webpack.config.js +0 -224
@@ -1,35 +1,31 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const lodash_1 = __importDefault(require("lodash"));
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const crypto_1 = __importDefault(require("crypto"));
9
- const fs_1 = __importDefault(require("fs"));
10
- const path_1 = __importDefault(require("path"));
11
- const auth_1 = __importDefault(require("./plugins/auth"));
12
- const client_1 = __importDefault(require("./client"));
13
- const config_1 = __importDefault(require("./config"));
14
- const webpush_1 = __importDefault(require("./plugins/webpush"));
15
- const log_1 = __importDefault(require("./log"));
1
+ import _ from "lodash";
2
+ import colors from "chalk";
3
+ import crypto from "crypto";
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import Auth from "./plugins/auth.js";
7
+ import Client from "./client.js";
8
+ import Config from "./config.js";
9
+ import WebPush from "./plugins/webpush.js";
10
+ import log from "./log.js";
16
11
  class ClientManager {
17
12
  clients;
18
13
  sockets;
19
14
  identHandler;
20
15
  webPush;
16
+ userWatcher = null;
21
17
  constructor() {
22
18
  this.clients = [];
23
19
  }
24
20
  init(identHandler, sockets) {
25
21
  this.sockets = sockets;
26
22
  this.identHandler = identHandler;
27
- this.webPush = new webpush_1.default();
28
- if (!config_1.default.values.public) {
23
+ this.webPush = new WebPush();
24
+ if (!Config.values.public) {
29
25
  this.loadUsers();
30
26
  // LDAP does not have user commands, and users are dynamically
31
27
  // created upon logon, so we don't need to watch for new files
32
- if (!config_1.default.values.ldap.enable) {
28
+ if (!Config.values.ldap.enable) {
33
29
  this.autoloadUsers();
34
30
  }
35
31
  }
@@ -41,14 +37,14 @@ class ClientManager {
41
37
  loadUsers() {
42
38
  let users = this.getUsers();
43
39
  if (users.length === 0) {
44
- log_1.default.info(`There are currently no users. Create one with ${chalk_1.default.bold("thelounge add <name>")}.`);
40
+ log.info(`There are currently no users. Create one with ${colors.bold("thelounge add <name>")}.`);
45
41
  return;
46
42
  }
47
43
  const alreadySeenUsers = new Set();
48
44
  users = users.filter((user) => {
49
45
  user = user.toLowerCase();
50
46
  if (alreadySeenUsers.has(user)) {
51
- log_1.default.error(`There is more than one user named "${chalk_1.default.bold(user)}". Usernames are now case insensitive, duplicate users will not load.`);
47
+ log.error(`There is more than one user named "${colors.bold(user)}". Usernames are now case insensitive, duplicate users will not load.`);
52
48
  return false;
53
49
  }
54
50
  alreadySeenUsers.add(user);
@@ -58,30 +54,36 @@ class ClientManager {
58
54
  const callbackLoadUser = (user) => {
59
55
  this.loadUser(user);
60
56
  };
61
- if (!auth_1.default.loadUsers(users, callbackLoadUser)) {
57
+ if (!Auth.loadUsers(users, callbackLoadUser)) {
62
58
  // Fallback to loading all users
63
59
  users.forEach((name) => this.loadUser(name));
64
60
  }
65
61
  }
66
62
  autoloadUsers() {
67
- fs_1.default.watch(config_1.default.getUsersPath(), (_eventType, file) => {
68
- if (!file.endsWith(".json")) {
63
+ this.userWatcher = fs.watch(Config.getUsersPath(), { persistent: false }, (_eventType, file) => {
64
+ if (!file || !file.endsWith(".json")) {
69
65
  return;
70
66
  }
71
67
  const name = file.slice(0, -5);
72
- const userPath = config_1.default.getUserConfigPath(name);
73
- if (fs_1.default.existsSync(userPath)) {
68
+ const userPath = Config.getUserConfigPath(name);
69
+ if (fs.existsSync(userPath)) {
74
70
  this.loadUser(name);
75
71
  return;
76
72
  }
77
- const client = lodash_1.default.find(this.clients, { name });
73
+ const client = _.find(this.clients, { name });
78
74
  if (client) {
79
75
  client.quit(true);
80
- this.clients = lodash_1.default.without(this.clients, client);
81
- log_1.default.info(`User ${chalk_1.default.bold(name)} disconnected and removed.`);
76
+ this.clients = _.without(this.clients, client);
77
+ log.info(`User ${colors.bold(name)} disconnected and removed.`);
82
78
  }
83
79
  });
84
80
  }
81
+ stopAutoloadUsers() {
82
+ if (this.userWatcher) {
83
+ this.userWatcher.close();
84
+ this.userWatcher = null;
85
+ }
86
+ }
85
87
  loadUser(name) {
86
88
  const userConfig = this.readUserConfig(name);
87
89
  if (!userConfig) {
@@ -98,32 +100,32 @@ class ClientManager {
98
100
  * @see https://github.com/thelounge/thelounge/issues/598
99
101
  */
100
102
  client.config.password = userConfig.password;
101
- log_1.default.info(`Password for user ${chalk_1.default.bold(name)} was reset.`);
103
+ log.info(`Password for user ${colors.bold(name)} was reset.`);
102
104
  }
103
105
  }
104
106
  else {
105
- client = new client_1.default(this, name, userConfig);
107
+ client = new Client(this, name, userConfig);
106
108
  client.connect();
107
109
  this.clients.push(client);
108
110
  }
109
111
  return client;
110
112
  }
111
113
  getUsers = function () {
112
- if (!fs_1.default.existsSync(config_1.default.getUsersPath())) {
114
+ if (!fs.existsSync(Config.getUsersPath())) {
113
115
  return [];
114
116
  }
115
- return fs_1.default
116
- .readdirSync(config_1.default.getUsersPath())
117
+ return fs
118
+ .readdirSync(Config.getUsersPath())
117
119
  .filter((file) => file.endsWith(".json"))
118
120
  .map((file) => file.slice(0, -5));
119
121
  };
120
122
  addUser(name, password, enableLog) {
121
- if (path_1.default.basename(name) !== name) {
123
+ if (path.basename(name) !== name) {
122
124
  throw new Error(`${name} is an invalid username.`);
123
125
  }
124
- const userPath = config_1.default.getUserConfigPath(name);
125
- if (fs_1.default.existsSync(userPath)) {
126
- log_1.default.error(`User ${chalk_1.default.green(name)} already exists.`);
126
+ const userPath = Config.getUserConfigPath(name);
127
+ if (fs.existsSync(userPath)) {
128
+ log.error(`User ${colors.green(name)} already exists.`);
127
129
  return false;
128
130
  }
129
131
  const user = {
@@ -132,30 +134,30 @@ class ClientManager {
132
134
  };
133
135
  try {
134
136
  const tmpPath = userPath + ".tmp";
135
- fs_1.default.writeFileSync(tmpPath, JSON.stringify(user, null, "\t"), {
137
+ fs.writeFileSync(tmpPath, JSON.stringify(user, null, "\t"), {
136
138
  mode: 0o600,
137
139
  });
138
- fs_1.default.renameSync(tmpPath, userPath);
140
+ fs.renameSync(tmpPath, userPath);
139
141
  }
140
142
  catch (e) {
141
- log_1.default.error(`Failed to create user ${chalk_1.default.green(name)} (${e})`);
143
+ log.error(`Failed to create user ${colors.green(name)} (${e instanceof Error ? e.message : String(e)})`);
142
144
  throw e;
143
145
  }
144
146
  try {
145
- const userFolderStat = fs_1.default.statSync(config_1.default.getUsersPath());
146
- const userFileStat = fs_1.default.statSync(userPath);
147
+ const userFolderStat = fs.statSync(Config.getUsersPath());
148
+ const userFileStat = fs.statSync(userPath);
147
149
  if (userFolderStat &&
148
150
  userFileStat &&
149
151
  (userFolderStat.uid !== userFileStat.uid || userFolderStat.gid !== userFileStat.gid)) {
150
- log_1.default.warn(`User ${chalk_1.default.green(name)} has been created, but with a different uid (or gid) than expected.`);
151
- log_1.default.warn("The file owner has been changed to the expected user. " +
152
+ log.warn(`User ${colors.green(name)} has been created, but with a different uid (or gid) than expected.`);
153
+ log.warn("The file owner has been changed to the expected user. " +
152
154
  "To prevent any issues, please run thelounge commands " +
153
155
  "as the correct user that owns the config folder.");
154
- log_1.default.warn("See https://thelounge.chat/docs/usage#using-the-correct-system-user for more information.");
155
- fs_1.default.chownSync(userPath, userFolderStat.uid, userFolderStat.gid);
156
+ log.warn("See https://thelounge.chat/docs/usage#using-the-correct-system-user for more information.");
157
+ fs.chownSync(userPath, userFolderStat.uid, userFolderStat.gid);
156
158
  }
157
159
  }
158
- catch (e) {
160
+ catch {
159
161
  // We're simply verifying file owner as a safe guard for users
160
162
  // that run `thelounge add` as root, so we don't care if it fails
161
163
  }
@@ -166,7 +168,7 @@ class ClientManager {
166
168
  networks: client.networks.map((n) => n.export()),
167
169
  });
168
170
  const newUser = JSON.stringify(json, null, "\t");
169
- const newHash = crypto_1.default.createHash("sha256").update(newUser).digest("hex");
171
+ const newHash = crypto.createHash("sha256").update(newUser).digest("hex");
170
172
  return { newUser, newHash };
171
173
  }
172
174
  saveUser(client, callback) {
@@ -175,47 +177,47 @@ class ClientManager {
175
177
  if (client.fileHash === newHash) {
176
178
  return;
177
179
  }
178
- const pathReal = config_1.default.getUserConfigPath(client.name);
180
+ const pathReal = Config.getUserConfigPath(client.name);
179
181
  const pathTemp = pathReal + ".tmp";
180
182
  try {
181
183
  // Write to a temp file first, in case the write fails
182
184
  // we do not lose the original file (for example when disk is full)
183
- fs_1.default.writeFileSync(pathTemp, newUser, {
185
+ fs.writeFileSync(pathTemp, newUser, {
184
186
  mode: 0o600,
185
187
  });
186
- fs_1.default.renameSync(pathTemp, pathReal);
188
+ fs.renameSync(pathTemp, pathReal);
187
189
  return callback ? callback() : true;
188
190
  }
189
191
  catch (e) {
190
- log_1.default.error(`Failed to update user ${chalk_1.default.green(client.name)} (${e})`);
192
+ log.error(`Failed to update user ${colors.green(client.name)} (${e instanceof Error ? e.message : String(e)})`);
191
193
  if (callback) {
192
- callback(e);
194
+ callback(e instanceof Error ? e : new Error(String(e)));
193
195
  }
194
196
  }
195
197
  }
196
198
  removeUser(name) {
197
- const userPath = config_1.default.getUserConfigPath(name);
198
- if (!fs_1.default.existsSync(userPath)) {
199
- log_1.default.error(`Tried to remove non-existing user ${chalk_1.default.green(name)}.`);
199
+ const userPath = Config.getUserConfigPath(name);
200
+ if (!fs.existsSync(userPath)) {
201
+ log.error(`Tried to remove non-existing user ${colors.green(name)}.`);
200
202
  return false;
201
203
  }
202
- fs_1.default.unlinkSync(userPath);
204
+ fs.unlinkSync(userPath);
203
205
  return true;
204
206
  }
205
207
  readUserConfig(name) {
206
- const userPath = config_1.default.getUserConfigPath(name);
207
- if (!fs_1.default.existsSync(userPath)) {
208
- log_1.default.error(`Tried to read non-existing user ${chalk_1.default.green(name)}`);
208
+ const userPath = Config.getUserConfigPath(name);
209
+ if (!fs.existsSync(userPath)) {
210
+ log.error(`Tried to read non-existing user ${colors.green(name)}`);
209
211
  return false;
210
212
  }
211
213
  try {
212
- const data = fs_1.default.readFileSync(userPath, "utf-8");
214
+ const data = fs.readFileSync(userPath, "utf-8");
213
215
  return JSON.parse(data);
214
216
  }
215
217
  catch (e) {
216
- log_1.default.error(`Failed to read user ${chalk_1.default.bold(name)}: ${e}`);
218
+ log.error(`Failed to read user ${colors.bold(name)}: ${e instanceof Error ? e.message : String(e)}`);
217
219
  }
218
220
  return false;
219
221
  }
220
222
  }
221
- exports.default = ClientManager;
223
+ export default ClientManager;
@@ -1,48 +1,49 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- /* eslint-disable @typescript-eslint/no-var-requires */
7
- const log_1 = __importDefault(require("../log"));
8
- const fs_1 = __importDefault(require("fs"));
9
- const path_1 = __importDefault(require("path"));
10
- const chalk_1 = __importDefault(require("chalk"));
11
- const commander_1 = require("commander");
12
- const helper_1 = __importDefault(require("../helper"));
13
- const config_1 = __importDefault(require("../config"));
14
- const utils_1 = __importDefault(require("./utils"));
15
- const program = new commander_1.Command("thelounge");
1
+ import log from "../log.js";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import colors from "chalk";
5
+ import { Command } from "commander";
6
+ import Helper from "../helper.js";
7
+ import Config from "../config.js";
8
+ import Utils from "./utils.js";
9
+ const program = new Command("thelounge");
16
10
  program
17
- .version(helper_1.default.getVersion(), "-v, --version")
18
- .option("-c, --config <key=value>", "override entries of the configuration file, must be specified for each entry that needs to be overriden", utils_1.default.parseConfigOptions)
19
- .on("--help", utils_1.default.extraHelp);
11
+ .version(Helper.getVersion(), "-v, --version")
12
+ .option("-c, --config <key=value>", "override entries of the configuration file, must be specified for each entry that needs to be overriden", Utils.parseConfigOptions)
13
+ .on("--help", Utils.extraHelp);
20
14
  // Parse options from `argv` returning `argv` void of these options.
21
15
  const argvWithoutOptions = program.parseOptions(process.argv);
22
- config_1.default.setHome(process.env.THELOUNGE_HOME || utils_1.default.defaultHome());
16
+ await Config.setHome(process.env.THELOUNGE_HOME || Utils.defaultHome());
23
17
  // Check config file owner and warn if we're running under a different user
24
18
  try {
25
19
  verifyFileOwner();
26
20
  }
27
- catch (e) {
21
+ catch {
28
22
  // We do not care about failures of these checks
29
23
  // fs.statSync will throw if config.js does not exist (e.g. first run)
30
24
  }
31
25
  // Create packages/package.json
32
26
  createPackagesFolder();
33
27
  // Merge config key-values passed as CLI options into the main config
34
- config_1.default.merge(program.opts().config);
35
- program.addCommand(require("./start").default);
36
- program.addCommand(require("./install").default);
37
- program.addCommand(require("./uninstall").default);
38
- program.addCommand(require("./upgrade").default);
39
- program.addCommand(require("./outdated").default);
40
- program.addCommand(require("./storage").default);
41
- if (!config_1.default.values.public) {
42
- require("./users").default.forEach((command) => {
43
- if (command) {
44
- program.addCommand(command);
45
- }
28
+ Config.merge(program.opts().config);
29
+ const startCmd = await import("./start.js");
30
+ const installCmd = await import("./install.js");
31
+ const uninstallCmd = await import("./uninstall.js");
32
+ const upgradeCmd = await import("./upgrade.js");
33
+ const outdatedCmd = await import("./outdated.js");
34
+ const storageCmd = await import("./storage.js");
35
+ program.addCommand(startCmd.default);
36
+ program.addCommand(installCmd.default);
37
+ program.addCommand(uninstallCmd.default);
38
+ program.addCommand(upgradeCmd.default);
39
+ program.addCommand(outdatedCmd.default);
40
+ program.addCommand(storageCmd.default);
41
+ if (!Config.values.public) {
42
+ const usersCmd = await import("./users/index.js");
43
+ usersCmd.default
44
+ .filter((command) => command !== undefined)
45
+ .forEach((command) => {
46
+ program.addCommand(command);
46
47
  });
47
48
  }
48
49
  // `parse` expects to be passed `process.argv`, but we need to remove to give it
@@ -53,13 +54,13 @@ if (!config_1.default.values.public) {
53
54
  // See https://github.com/tj/commander.js/blob/fefda77f463292/index.js#L686-L763
54
55
  program.parse(argvWithoutOptions.operands.concat(argvWithoutOptions.unknown));
55
56
  function createPackagesFolder() {
56
- const packagesPath = config_1.default.getPackagesPath();
57
- const packagesConfig = path_1.default.join(packagesPath, "package.json");
57
+ const packagesPath = Config.getPackagesPath();
58
+ const packagesConfig = path.join(packagesPath, "package.json");
58
59
  // Create node_modules folder, otherwise yarn will start walking upwards to find one
59
- fs_1.default.mkdirSync(path_1.default.join(packagesPath, "node_modules"), { recursive: true });
60
+ fs.mkdirSync(path.join(packagesPath, "node_modules"), { recursive: true });
60
61
  // Create package.json with private set to true, if it doesn't exist already
61
- if (!fs_1.default.existsSync(packagesConfig)) {
62
- fs_1.default.writeFileSync(packagesConfig, JSON.stringify({
62
+ if (!fs.existsSync(packagesConfig)) {
63
+ fs.writeFileSync(packagesConfig, JSON.stringify({
63
64
  private: true,
64
65
  description: "Packages for The Lounge. Use `thelounge install <package>` command to add a package.",
65
66
  dependencies: {},
@@ -72,14 +73,14 @@ function verifyFileOwner() {
72
73
  }
73
74
  const uid = process.getuid();
74
75
  if (uid === 0) {
75
- log_1.default.warn(`You are currently running The Lounge as root. ${chalk_1.default.bold.red("We highly discourage running as root!")}`);
76
+ log.warn(`You are currently running The Lounge as root. ${colors.bold.red("We highly discourage running as root!")}`);
76
77
  }
77
- const configStat = fs_1.default.statSync(path_1.default.join(config_1.default.getHomePath(), "config.js"));
78
+ const configStat = fs.statSync(path.join(Config.getHomePath(), "config.js"));
78
79
  if (configStat && configStat.uid !== uid) {
79
- log_1.default.warn("Config file owner does not match the user you are currently running The Lounge as.");
80
- log_1.default.warn("To prevent any issues, please run thelounge commands " +
80
+ log.warn("Config file owner does not match the user you are currently running The Lounge as.");
81
+ log.warn("To prevent any issues, please run thelounge commands " +
81
82
  "as the correct user that owns the config folder.");
82
- log_1.default.warn("See https://thelounge.chat/docs/usage#using-the-correct-system-user for more information.");
83
+ log.warn("See https://thelounge.chat/docs/usage#using-the-correct-system-user for more information.");
83
84
  }
84
85
  }
85
- exports.default = program;
86
+ export default program;
@@ -1,57 +1,28 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- /* eslint-disable @typescript-eslint/restrict-template-expressions */
30
- const log_1 = __importDefault(require("../log"));
31
- const chalk_1 = __importDefault(require("chalk"));
32
- const semver_1 = __importDefault(require("semver"));
33
- const helper_1 = __importDefault(require("../helper"));
34
- const config_1 = __importDefault(require("../config"));
35
- const utils_1 = __importDefault(require("./utils"));
36
- const commander_1 = require("commander");
37
- const program = new commander_1.Command("install");
1
+ import log from "../log.js";
2
+ import colors from "chalk";
3
+ import semver from "semver";
4
+ import Helper from "../helper.js";
5
+ import Config from "../config.js";
6
+ import Utils from "./utils.js";
7
+ import { Command } from "commander";
8
+ import packageJsonImport from "package-json";
9
+ import fs from "node:fs";
10
+ import fspromises from "node:fs/promises";
11
+ import path from "node:path";
12
+ const program = new Command("install");
38
13
  program
39
14
  .argument("<package>", "package to install. Use `file:$path_to_package_dir` to install a local package")
40
15
  .description("Install a theme or a package")
41
- .on("--help", utils_1.default.extraHelp)
42
- .action(async function (packageName) {
43
- const fs = await Promise.resolve().then(() => __importStar(require("fs")));
44
- const fspromises = fs.promises;
45
- const path = await Promise.resolve().then(() => __importStar(require("path")));
46
- const packageJson = await Promise.resolve().then(() => __importStar(require("package-json")));
47
- if (!fs.existsSync(config_1.default.getConfigPath())) {
48
- log_1.default.error(`${config_1.default.getConfigPath()} does not exist.`);
16
+ .on("--help", Utils.extraHelp)
17
+ .action(function (packageName) {
18
+ if (!fs.existsSync(Config.getConfigPath())) {
19
+ log.error(`${Config.getConfigPath()} does not exist.`);
49
20
  return;
50
21
  }
51
- log_1.default.info("Retrieving information about the package...");
52
- // TODO: type
53
- let readFile = null;
22
+ log.info("Retrieving information about the package...");
23
+ let readFile;
54
24
  let isLocalFile = false;
25
+ let packageVersion = "latest";
55
26
  if (packageName.startsWith("file:")) {
56
27
  isLocalFile = true;
57
28
  // our yarn invocation sets $HOME to the cachedir, so we must expand ~ now
@@ -64,60 +35,56 @@ program
64
35
  else {
65
36
  // properly split scoped and non-scoped npm packages
66
37
  // into their name and version
67
- let packageVersion = "latest";
68
38
  const atIndex = packageName.indexOf("@", 1);
69
39
  if (atIndex !== -1) {
70
40
  packageVersion = packageName.slice(atIndex + 1);
71
41
  packageName = packageName.slice(0, atIndex);
72
42
  }
73
- readFile = packageJson.default(packageName, {
43
+ readFile = packageJsonImport(packageName, {
74
44
  fullMetadata: true,
75
45
  version: packageVersion,
76
46
  });
77
47
  }
78
- if (!readFile) {
79
- // no-op, error should've been thrown before this point
80
- return;
81
- }
82
48
  readFile
83
49
  .then((json) => {
84
- const humanVersion = isLocalFile ? packageName : `${json.name} v${json.version}`;
85
- if (!("thelounge" in json)) {
86
- log_1.default.error(`${chalk_1.default.red(humanVersion)} does not have The Lounge metadata.`);
50
+ const version = json.version || packageVersion;
51
+ const humanVersion = isLocalFile ? packageName : `${json.name} v${version}`;
52
+ if (!json.thelounge) {
53
+ log.error(`${colors.red(humanVersion)} does not have The Lounge metadata.`);
87
54
  process.exit(1);
88
55
  }
89
56
  if (json.thelounge.supports &&
90
- !semver_1.default.satisfies(helper_1.default.getVersionNumber(), json.thelounge.supports, {
57
+ !semver.satisfies(Helper.getVersionNumber(), json.thelounge.supports, {
91
58
  includePrerelease: true,
92
59
  })) {
93
- log_1.default.error(`${chalk_1.default.red(humanVersion)} does not support The Lounge v${helper_1.default.getVersionNumber()}. Supported version(s): ${json.thelounge.supports}`);
60
+ log.error(`${colors.red(humanVersion)} does not support The Lounge v${Helper.getVersionNumber()}. Supported version(s): ${json.thelounge.supports}`);
94
61
  process.exit(2);
95
62
  }
96
- log_1.default.info(`Installing ${chalk_1.default.green(humanVersion)}...`);
97
- const yarnVersion = isLocalFile ? packageName : `${json.name}@${json.version}`;
98
- return utils_1.default.executeYarnCommand("add", "--exact", yarnVersion)
63
+ log.info(`Installing ${colors.green(humanVersion)}...`);
64
+ const yarnVersion = isLocalFile ? packageName : `${json.name}@${version}`;
65
+ return Utils.executeYarnCommand("add", "--exact", yarnVersion)
99
66
  .then(() => {
100
- log_1.default.info(`${chalk_1.default.green(humanVersion)} has been successfully installed.`);
67
+ log.info(`${colors.green(humanVersion)} has been successfully installed.`);
101
68
  if (isLocalFile) {
102
69
  // yarn v1 is buggy if a local filepath is used and doesn't update
103
70
  // the lockfile properly. We need to run an install in that case
104
71
  // even though that's supposed to be done by the add subcommand
105
- return utils_1.default.executeYarnCommand("install").catch((err) => {
106
- throw `Failed to update lockfile after package install ${err}`;
72
+ return Utils.executeYarnCommand("install").catch((err) => {
73
+ throw new Error(`Failed to update lockfile after package install ${err}`);
107
74
  });
108
75
  }
109
76
  })
110
77
  .catch((code) => {
111
- throw `Failed to install ${chalk_1.default.red(humanVersion)}. Exit code: ${code}`;
78
+ throw new Error(`Failed to install ${colors.red(humanVersion)}. Exit code: ${code}`);
112
79
  });
113
80
  })
114
81
  .catch((e) => {
115
- log_1.default.error(`${e}`);
82
+ log.error(`${e}`);
116
83
  process.exit(1);
117
84
  });
118
85
  });
119
86
  function expandTildeInLocalPath(packageName) {
120
- const path = packageName.substring("file:".length);
121
- return "file:" + helper_1.default.expandHome(path);
87
+ const localPath = packageName.substring("file:".length);
88
+ return "file:" + Helper.expandHome(localPath);
122
89
  }
123
- exports.default = program;
90
+ export default program;
@@ -1,30 +1,25 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const commander_1 = require("commander");
7
- const utils_1 = __importDefault(require("./utils"));
8
- const packages_1 = __importDefault(require("../plugins/packages"));
9
- const log_1 = __importDefault(require("../log"));
10
- const program = new commander_1.Command("outdated");
1
+ import { Command } from "commander";
2
+ import Utils from "./utils.js";
3
+ import packageManager from "../plugins/packages/index.js";
4
+ import log from "../log.js";
5
+ const program = new Command("outdated");
11
6
  program
12
7
  .description("Check for any outdated packages")
13
- .on("--help", utils_1.default.extraHelp)
8
+ .on("--help", Utils.extraHelp)
14
9
  .action(async () => {
15
- log_1.default.info("Checking for outdated packages");
16
- await packages_1.default
10
+ log.info("Checking for outdated packages");
11
+ await packageManager
17
12
  .outdated(0)
18
13
  .then((outdated) => {
19
14
  if (outdated) {
20
- log_1.default.info("There are outdated packages");
15
+ log.info("There are outdated packages");
21
16
  }
22
17
  else {
23
- log_1.default.info("No outdated packages");
18
+ log.info("No outdated packages");
24
19
  }
25
20
  })
26
21
  .catch(() => {
27
- log_1.default.error("Error finding outdated packages.");
22
+ log.error("Error finding outdated packages.");
28
23
  });
29
24
  });
30
- exports.default = program;
25
+ export default program;