hackmud-script-manager 0.19.1-64ab3ba → 0.19.1-6d8d544

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Hackmud Script Manager
2
2
  Command made for [hackmud-environment](https://github.com/samualtnorman/hackmud-environment), which is a scripting environment for hackmud with minification, autocompletes / intellisense, and TypeScript support.
3
3
 
4
- Install with `npm install hackmud-script-manager -g` to make the `hsm` command available everywhere.
4
+ Install with `npm install -g hackmud-script-manager` to make the `hsm` command available everywhere.
5
5
 
6
6
  ## Features
7
7
  - Minification
package/bin/hsm.d.ts CHANGED
File without changes
package/bin/hsm.js CHANGED
@@ -3,17 +3,16 @@ import { Cache } from "@samual/lib/Cache"
3
3
  import { assert } from "@samual/lib/assert"
4
4
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
5
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
6
- import { readFile, writeFile, mkdir, rmdir } from "fs/promises"
6
+ import { writeFile, readFile } from "fs/promises"
7
7
  import { homedir } from "os"
8
- import { resolve, extname, basename, dirname, relative } from "path"
8
+ import { extname, basename, resolve, dirname, relative } from "path"
9
9
  import { supportedExtensions } from "../constants.js"
10
10
  import { generateTypeDeclaration } from "../generateTypeDeclaration.js"
11
11
  import { pull } from "../pull.js"
12
12
  import { syncMacros } from "../syncMacros.js"
13
13
  import "@samual/lib/readDirectoryWithStats"
14
14
  import "@samual/lib/copyFilePersistent"
15
- const configDirectoryPath = resolve(homedir(), ".config"),
16
- configFilePath = resolve(configDirectoryPath, "hsm.json"),
15
+ const version = "0.19.1-6d8d544",
17
16
  options = new Map(),
18
17
  commands = [],
19
18
  userColours = new Cache(user => {
@@ -21,111 +20,7 @@ const configDirectoryPath = resolve(homedir(), ".config"),
21
20
  for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
22
21
  return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
23
22
  }),
24
- logNeedHackmudPathMessage = () =>
25
- console.error(
26
- colourS(
27
- `${colourD("You need to set hackmudPath in config before you can use this command")}\n\n${colourA("To fix this:")}\nOpen hackmud and run "${colourC("#dir")}"\nThis will open a file browser and print your hackmud user's script directory\nGo up 2 directories and then copy the path\nThen in a terminal run "${colourC("hsm")} ${colourL("config set")} ${colourV("hackmudPath")} ${colourB("<the path you copied>")}"`
28
- )
29
- ),
30
- logHelp = () => {
31
- const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
32
- forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`
33
- console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-64ab3ba"))
34
- switch (commands[0]) {
35
- case "config":
36
- switch (commands[1]) {
37
- case "get":
38
- console.log(
39
- `\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
40
- )
41
- break
42
- case "set":
43
- console.log(
44
- `\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
45
- )
46
- break
47
- case "delete":
48
- console.log(
49
- `\n${colourJ("Remove a key and value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
50
- )
51
- break
52
- default:
53
- console.log(
54
- colourS(
55
- `${colourN("Config path")}: ${colourV(configFilePath)}\n\n${colourJ("Modify the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0] + " get")} ${colourB("<key>")}\n Retrieve a value from the config file\n${colourC("hsm")} ${colourL(commands[0] + " set")} ${colourB("<key> <value>")}\n Assign a value to the config file\n${colourC("hsm")} ${colourL(commands[0] + " delete")} ${colourB("<key>")}\n Remove a key and value from the config file`
56
- )
57
- )
58
- }
59
- break
60
- case "dev":
61
- case "watch":
62
- case "push":
63
- console.log(
64
- colourS(
65
- `\n${colourJ("push" == commands[0] ? pushCommandDescription : "Watch a directory and push a script when modified")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB('<directory> ["<script user>.<script name>"...]')}\n\n${colourA("Arguments:")}\n${colourB("<directory>")}\n The source directory containing your scripts\n${colourB("<script user>")}\n A user to push script(s) to. Can be set to wild card (${colourV("*")}) which will try\n and discover users to push to\n${colourB("<script name>")}\n Name of a script to push. Can be set to wild card (${colourV("*")}) to find all scripts\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${"push" == commands[0] ? "" : `${colourN("--type-declaration-path")}=${colourB("<path>")}\n Path to generate a type declaration file for the scripts\n`}\n${colourA("Examples:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")}\n\tPushes all scripts found in ${colourV("src")} folder to all users\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("bar")}\n Pushes a script named ${colourL("bar")} found in ${colourV("src")} folder to user ${userColours.get("foo")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("bar")} ${colourC("baz")}${colourV(".")}${colourL("qux")}\n Multiple can be specified.\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("*")}\n\tPushes all scripts found in ${colourV("src")} folder to user ${userColours.get("foo")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("*")}${colourV(".")}${colourL("foo")}\n\tPushes all scripts named ${colourL("foo")} found in ${colourV("src")} folder to all user\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("*")}${colourV(".")}${colourL("*")}\n\tPushes all scripts found in ${colourV("src")} folder to all users`
66
- )
67
- )
68
- break
69
- case "pull":
70
- console.log(
71
- colourS(
72
- `\n${colourJ("Pull a script a from a hackmud user's script directory")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<script user>")}${colourV(".")}${colourB("<script name>")}`
73
- )
74
- )
75
- break
76
- case "minify":
77
- case "golf":
78
- console.log(
79
- colourS(
80
- `\n${colourJ("Minify a script file on the spot")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<target> [output path]")}\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${colourN("--watch")}\n Watch for changes`
81
- )
82
- )
83
- break
84
- case "generate-type-declaration":
85
- case "gen-type-declaration":
86
- case "gen-dts":
87
- case "gen-types":
88
- console.log(
89
- colourS(
90
- `${colourJ("Generate a type declaration file for a directory of scripts")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [output path]")}`
91
- )
92
- )
93
- break
94
- case "sync-macros":
95
- console.log("\n" + colourJ("Sync macros across all hackmud users"))
96
- break
97
- default:
98
- console.log(
99
- colourS(
100
- `\n${colourJ("Hackmud Script Manager")}\n\n${colourA("Commands:")}\n${colourL("push")}\n ${pushCommandDescription}\n${colourL("dev")}\n Watch a directory and push a script when modified\n${colourL("golf")}\n Minify a script file on the spot\n${colourL("gen-dts")}\n Generate a type declaration file for a directory of scripts\n${colourL("sync-macros")}\n Sync macros across all hackmud users\n${colourL("config")}\n Modify and view the config file\n${colourL("pull")}\n Pull a script a from a hackmud user's script directory`
101
- )
102
- )
103
- }
104
- },
105
- exploreObject = (object, keys, createPath = !1) => {
106
- for (const key of keys)
107
- object =
108
- createPath ?
109
- "object" == typeof object[key] ?
110
- object[key]
111
- : (object[key] = {})
112
- : object?.[key]
113
- return object
114
- },
115
- logInfo = ({ file, users, minLength, error }, hackmudPath) => {
116
- error ?
117
- logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
118
- : console.log(
119
- `pushed ${chalk.bold(file)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(minLength + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(file, extname(file))) + ".js")}`
120
- )
121
- },
122
- log = message => {
123
- console.log(colourS(message))
124
- },
125
- logError = message => {
126
- console.error(colourD(message))
127
- process.exitCode = 1
128
- }
23
+ log = message => console.log(colourS(message))
129
24
  for (const argument of process.argv.slice(2))
130
25
  if ("-" == argument[0]) {
131
26
  const [key, valueRaw] = argument.split("=")
@@ -142,35 +37,10 @@ for (const argument of process.argv.slice(2))
142
37
  else for (const option of key.slice(1)) options.set(option, value)
143
38
  } else commands.push(argument)
144
39
  if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
145
- console.log("0.19.1-64ab3ba")
40
+ console.log(version)
146
41
  process.exit()
147
42
  }
148
- let configDidNotExist = !1
149
- const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
150
- configFile => {
151
- let temporaryConfig
152
- try {
153
- temporaryConfig = JSON.parse(configFile)
154
- } catch {
155
- log("Config file was corrupted, resetting")
156
- return {}
157
- }
158
- if (!temporaryConfig || "object" != typeof temporaryConfig) {
159
- log("Config file was corrupted, resetting")
160
- return {}
161
- }
162
- if ("hackmudPath" in temporaryConfig && "string" != typeof temporaryConfig.hackmudPath) {
163
- log('Property "hackmudPath" of config file was corrupted, removing')
164
- delete temporaryConfig.hackmudPath
165
- }
166
- return temporaryConfig
167
- },
168
- () => {
169
- configDidNotExist = !0
170
- return {}
171
- }
172
- ),
173
- pushModule = import("../push.js"),
43
+ const pushModule = import("../push.js"),
174
44
  processScriptModule = import("../processScript/index.js"),
175
45
  watchModule = import("../watch.js"),
176
46
  chokidarModule = import("chokidar"),
@@ -195,12 +65,8 @@ let autoExit = !0
195
65
  switch (commands[0]) {
196
66
  case "push":
197
67
  {
198
- const { hackmudPath } = await configPromise
199
- if (!hackmudPath) {
200
- logNeedHackmudPathMessage()
201
- break
202
- }
203
- const sourcePath = commands[1]
68
+ const hackmudPath = getHackmudPath(),
69
+ sourcePath = commands[1]
204
70
  if (!sourcePath) {
205
71
  logError("Must provide the directory to push from\n")
206
72
  logHelp()
@@ -268,12 +134,8 @@ switch (commands[0]) {
268
134
  case "dev":
269
135
  case "watch":
270
136
  {
271
- const { hackmudPath } = await configPromise
272
- if (!hackmudPath) {
273
- logNeedHackmudPathMessage()
274
- break
275
- }
276
- const sourcePath = commands[1]
137
+ const hackmudPath = getHackmudPath(),
138
+ sourcePath = commands[1]
277
139
  if (!sourcePath) {
278
140
  logError("Must provide the directory to watch\n")
279
141
  logHelp()
@@ -346,34 +208,24 @@ switch (commands[0]) {
346
208
  break
347
209
  case "pull":
348
210
  {
349
- const { hackmudPath } = await configPromise
350
- if (!hackmudPath) {
351
- logNeedHackmudPathMessage()
352
- break
353
- }
354
- const script = commands[1]
211
+ const hackmudPath = getHackmudPath(),
212
+ script = commands[1]
355
213
  if (!script) {
356
214
  logError("Must provide the script to pull\n")
357
215
  logHelp()
358
216
  break
359
217
  }
360
218
  const sourcePath = commands[2] || "."
361
- try {
362
- await pull(sourcePath, hackmudPath, script)
363
- } catch (error) {
219
+ await pull(sourcePath, hackmudPath, script).catch(error => {
364
220
  console.error(error)
365
221
  logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
366
- }
222
+ })
367
223
  }
368
224
  break
369
225
  case "sync-macros":
370
226
  {
371
- const { hackmudPath } = await configPromise
372
- if (!hackmudPath) {
373
- logNeedHackmudPathMessage()
374
- break
375
- }
376
- const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
227
+ const hackmudPath = getHackmudPath(),
228
+ { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
377
229
  log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
378
230
  }
379
231
  break
@@ -390,100 +242,17 @@ switch (commands[0]) {
390
242
  }
391
243
  const sourcePath = resolve(target),
392
244
  outputPath = commands[2] || "./player.d.ts",
393
- typeDeclaration = await generateTypeDeclaration(sourcePath, (await configPromise).hackmudPath)
245
+ typeDeclaration = await generateTypeDeclaration(sourcePath, getHackmudPath())
394
246
  let typeDeclarationPath = resolve(outputPath)
395
- try {
396
- await writeFile(typeDeclarationPath, typeDeclaration)
397
- } catch (error) {
398
- assert(error instanceof Error)
247
+ await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
248
+ assert(error instanceof Error, "src/bin/hsm.ts:327:35")
399
249
  if ("EISDIR" != error.code) throw error
400
250
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
401
- await writeFile(typeDeclarationPath, typeDeclaration)
402
- }
251
+ return writeFile(typeDeclarationPath, typeDeclaration)
252
+ })
403
253
  log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
404
254
  }
405
255
  break
406
- case "config":
407
- switch (commands[1]) {
408
- case "get":
409
- {
410
- const key = commands[2]
411
- key ? log(exploreObject(await configPromise, key.split("."))) : console.log(await configPromise)
412
- }
413
- break
414
- case "delete":
415
- {
416
- const key = commands[2]
417
- if (!key) {
418
- logError("Must provide a key to delete\n")
419
- logHelp()
420
- break
421
- }
422
- const keyParts = key.split("."),
423
- pathName = keyParts
424
- .map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
425
- .join("."),
426
- lastKey = keyParts.pop(),
427
- config = await configPromise
428
- delete exploreObject(config, keyParts)?.[lastKey]
429
- log(`Removed ${colourV(pathName)} from config file`)
430
- }
431
- break
432
- case "set":
433
- {
434
- const key = commands[2],
435
- value = commands[3]
436
- if (!key) {
437
- logError("Must provide a key and value\n")
438
- logHelp()
439
- break
440
- }
441
- const keys = key.split("."),
442
- pathName = keys
443
- .map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
444
- .join(".")
445
- if (!value) {
446
- logError(`Must provide a value for the key ${pathName}\n`)
447
- logHelp()
448
- break
449
- }
450
- const lastKey = keys.pop(),
451
- config = await configPromise
452
- if (keys.length || "hackmudPath" != lastKey) {
453
- let object = config
454
- for (const key of keys)
455
- if ("object" == typeof object[key]) object = object[key]
456
- else {
457
- object[key] = {}
458
- object = object[key]
459
- }
460
- object[lastKey] = value
461
- } else config.hackmudPath = resolve(value.startsWith("~/") ? homedir() + value.slice(1) : value)
462
- console.log(config)
463
- await (async config => {
464
- const json = JSON.stringify(config, void 0, "\t")
465
- configDidNotExist && log("Creating config file at " + configFilePath)
466
- await writeFile(configFilePath, json).catch(async error => {
467
- switch (error.code) {
468
- case "EISDIR":
469
- await rmdir(configFilePath)
470
- break
471
- case "ENOENT":
472
- await mkdir(configDirectoryPath)
473
- break
474
- default:
475
- throw error
476
- }
477
- await writeFile(configFilePath, json)
478
- })
479
- })(config)
480
- }
481
- break
482
- default:
483
- commands[1] && logError(`Unknown command: ${JSON.stringify(commands[1])}\n`)
484
- logHelp()
485
- }
486
- break
487
256
  case "help":
488
257
  case "h":
489
258
  logHelp()
@@ -511,7 +280,7 @@ switch (commands[0]) {
511
280
  scriptUser =
512
281
  "scripts" == basename(resolve(target, "..")) && "hackmud" == basename(resolve(target, "../../..")) ?
513
282
  basename(resolve(target, "../.."))
514
- : "UNKNOWN",
283
+ : void 0,
515
284
  optionsHasNoMinify = options.has("no-minify")
516
285
  if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
517
286
  logError(
@@ -547,36 +316,31 @@ switch (commands[0]) {
547
316
  : fileBaseName + ".js"
548
317
  )
549
318
  const golfFile = () =>
550
- readFile(target, { encoding: "utf-8" }).then(
551
- async source => {
552
- const timeStart = performance.now(),
553
- { script, warnings } = await processScript(source, {
554
- minify: !(options.get("no-minify") || options.get("skip-minify")),
555
- scriptUser,
556
- scriptName,
557
- filePath: target,
558
- mangleNames,
559
- forceQuineCheats
560
- }),
561
- timeTook = performance.now() - timeStart
562
- for (const { message, line } of warnings)
563
- log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
564
- await writeFilePersistent(outputPath, script)
565
- .catch(async error => {
566
- if (!commands[2] || "EISDIR" != error.code) throw error
567
- outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
568
- await writeFilePersistent(outputPath, script)
569
- })
570
- .then(
571
- () =>
572
- log(
573
- `Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
574
- ),
575
- error => logError(error.message)
319
+ readFile(target, { encoding: "utf8" }).then(async source => {
320
+ const timeStart = performance.now(),
321
+ { script, warnings } = await processScript(source, {
322
+ minify: !(options.get("no-minify") || options.get("skip-minify")),
323
+ scriptUser,
324
+ scriptName,
325
+ filePath: target,
326
+ mangleNames,
327
+ forceQuineCheats
328
+ }),
329
+ timeTook = performance.now() - timeStart
330
+ for (const { message, line } of warnings)
331
+ log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
332
+ await writeFilePersistent(outputPath, script)
333
+ .catch(error => {
334
+ if (!commands[2] || "EISDIR" != error.code) throw error
335
+ outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
336
+ return writeFilePersistent(outputPath, script)
337
+ })
338
+ .then(() =>
339
+ log(
340
+ `Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
576
341
  )
577
- },
578
- error => logError(error.message)
579
- )
342
+ )
343
+ })
580
344
  if (options.get("watch")) {
581
345
  const { watch: watchFile } = await chokidarModule
582
346
  watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
@@ -587,7 +351,87 @@ switch (commands[0]) {
587
351
  }
588
352
  break
589
353
  default:
590
- commands[0] && logError(`Unknown command: ${JSON.stringify(commands[0])}\n`)
354
+ commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
591
355
  logHelp()
592
356
  }
593
357
  autoExit && process.exit()
358
+ function logHelp() {
359
+ const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
360
+ forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`,
361
+ hackmudPathOption = `${colourN("--hackmud-path")}=${colourB("<path>")}\n Override hackmud path`
362
+ console.log(colourN("Version") + colourS(": ") + colourV(version))
363
+ switch (commands[0]) {
364
+ case "dev":
365
+ case "watch":
366
+ case "push":
367
+ console.log(
368
+ colourS(
369
+ `\n${colourJ("push" == commands[0] ? pushCommandDescription : "Watch a directory and push a script when modified")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB('<directory> ["<script user>.<script name>"...]')}\n\n${colourA("Arguments:")}\n${colourB("<directory>")}\n The source directory containing your scripts\n${colourB("<script user>")}\n A user to push script(s) to. Can be set to wild card (${colourV("*")}) which will try\n and discover users to push to\n${colourB("<script name>")}\n Name of a script to push. Can be set to wild card (${colourV("*")}) to find all scripts\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${hackmudPathOption}\n${"push" == commands[0] ? "" : `${colourN("--type-declaration-path")}=${colourB("<path>")}\n Path to generate a type declaration file for the scripts\n`}\n${colourA("Examples:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")}\n\tPushes all scripts found in ${colourV("src")} folder to all users\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("bar")}\n Pushes a script named ${colourL("bar")} found in ${colourV("src")} folder to user ${userColours.get("foo")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("bar")} ${colourC("baz")}${colourV(".")}${colourL("qux")}\n Multiple can be specified\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("foo")}${colourV(".")}${colourL("*")}\n\tPushes all scripts found in ${colourV("src")} folder to user ${userColours.get("foo")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("*")}${colourV(".")}${colourL("foo")}\n\tPushes all scripts named ${colourL("foo")} found in ${colourV("src")} folder to all user\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")} ${colourC("*")}${colourV(".")}${colourL("*")}\n\tPushes all scripts found in ${colourV("src")} folder to all users`
370
+ )
371
+ )
372
+ break
373
+ case "pull":
374
+ console.log(
375
+ colourS(
376
+ `\n${colourJ("Pull a script a from a hackmud user's script directory")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<script user>")}${colourV(".")}${colourB("<script name>")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
377
+ )
378
+ )
379
+ break
380
+ case "minify":
381
+ case "golf":
382
+ console.log(
383
+ colourS(
384
+ `\n${colourJ("Minify a script file on the spot")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<target> [output path]")}\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${colourN("--watch")}\n Watch for changes`
385
+ )
386
+ )
387
+ break
388
+ case "generate-type-declaration":
389
+ case "gen-type-declaration":
390
+ case "gen-dts":
391
+ case "gen-types":
392
+ console.log(
393
+ colourS(
394
+ `${colourJ("Generate a type declaration file for a directory of scripts")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [output path]")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
395
+ )
396
+ )
397
+ break
398
+ case "sync-macros":
399
+ console.log(
400
+ colourS(
401
+ `\n${colourJ("Sync macros across all hackmud users")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
402
+ )
403
+ )
404
+ break
405
+ default:
406
+ console.log(
407
+ colourS(
408
+ `\n${colourJ("Hackmud Script Manager")}\n\n${colourA("Commands:")}\n${colourL("push")}\n ${pushCommandDescription}\n${colourL("dev")}\n Watch a directory and push a script when modified\n${colourL("golf")}\n Minify a script file on the spot\n${colourL("gen-dts")}\n Generate a type declaration file for a directory of scripts\n${colourL("sync-macros")}\n Sync macros across all hackmud users\n${colourL("pull")}\n Pull a script a from a hackmud user's script directory`
409
+ )
410
+ )
411
+ }
412
+ }
413
+ function logInfo({ path, users, characterCount, error }, hackmudPath) {
414
+ path = relative(".", path)
415
+ error ?
416
+ logError(`Error "${chalk.bold(error.message)}" in ${chalk.bold(path)}`)
417
+ : log(
418
+ `Pushed ${chalk.bold(path)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(characterCount + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(path, extname(path))) + ".js")}`
419
+ )
420
+ }
421
+ function logError(message) {
422
+ console.error(colourD(message))
423
+ process.exitCode = 1
424
+ }
425
+ function getHackmudPath() {
426
+ const hackmudPathOption = options.get("hackmud-path")
427
+ if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
428
+ logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
429
+ logHelp()
430
+ process.exit(1)
431
+ }
432
+ return (
433
+ hackmudPathOption ||
434
+ process.env.HSM_HACKMUD_PATH ||
435
+ ("win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud"))
436
+ )
437
+ }