hackmud-script-manager 0.19.1-bf4dc4a → 0.19.1-c2f3057

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
@@ -1,23 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { Cache } from "@samual/lib/Cache"
3
3
  import { assert } from "@samual/lib/assert"
4
- import { catchError } from "@samual/lib/catchError"
5
4
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
6
- import { getDeepObjectProperty } from "@samual/lib/getDeepObjectProperty"
7
- import { isRecord } from "@samual/lib/isRecord"
8
- import { setDeepObjectProperty } from "@samual/lib/setDeepObjectProperty"
9
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
10
- import { readFile, writeFile, mkdir, rmdir } from "fs/promises"
6
+ import { writeFile, readFile } from "fs/promises"
11
7
  import { homedir } from "os"
12
- import { resolve, extname, basename, dirname, relative } from "path"
8
+ import { extname, basename, resolve, dirname, relative } from "path"
13
9
  import { supportedExtensions } from "../constants.js"
14
10
  import { generateTypeDeclaration } from "../generateTypeDeclaration.js"
15
11
  import { pull } from "../pull.js"
16
12
  import { syncMacros } from "../syncMacros.js"
17
13
  import "@samual/lib/readDirectoryWithStats"
18
14
  import "@samual/lib/copyFilePersistent"
19
- const configDirectoryPath = resolve(homedir(), ".config"),
20
- configFilePath = resolve(configDirectoryPath, "hsm.json"),
15
+ const version = "0.19.1-c2f3057",
21
16
  options = new Map(),
22
17
  commands = [],
23
18
  userColours = new Cache(user => {
@@ -25,118 +20,7 @@ const configDirectoryPath = resolve(homedir(), ".config"),
25
20
  for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
26
21
  return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
27
22
  }),
28
- logNeedHackmudPathMessage = () =>
29
- console.error(
30
- colourS(
31
- `${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>")}"`
32
- )
33
- ),
34
- logHelp = () => {
35
- const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
36
- forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`
37
- console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-bf4dc4a"))
38
- switch (commands[0]) {
39
- case "config":
40
- switch (commands[1]) {
41
- case "get":
42
- console.log(
43
- `\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
44
- )
45
- break
46
- case "set":
47
- console.log(
48
- `\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
49
- )
50
- break
51
- case "delete":
52
- console.log(
53
- `\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>")}`
54
- )
55
- break
56
- default:
57
- console.log(
58
- colourS(
59
- `${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`
60
- )
61
- )
62
- }
63
- break
64
- case "dev":
65
- case "watch":
66
- case "push":
67
- console.log(
68
- colourS(
69
- `\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`
70
- )
71
- )
72
- break
73
- case "pull":
74
- console.log(
75
- colourS(
76
- `\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>")}`
77
- )
78
- )
79
- break
80
- case "minify":
81
- case "golf":
82
- console.log(
83
- colourS(
84
- `\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`
85
- )
86
- )
87
- break
88
- case "generate-type-declaration":
89
- case "gen-type-declaration":
90
- case "gen-dts":
91
- case "gen-types":
92
- console.log(
93
- colourS(
94
- `${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]")}`
95
- )
96
- )
97
- break
98
- case "sync-macros":
99
- console.log("\n" + colourJ("Sync macros across all hackmud users"))
100
- break
101
- default:
102
- console.log(
103
- colourS(
104
- `\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`
105
- )
106
- )
107
- }
108
- },
109
- updateConfig = async config => {
110
- const json = JSON.stringify(config, void 0, "\t")
111
- configDidNotExist && log("Creating config file at " + configFilePath)
112
- await writeFile(configFilePath, json).catch(async error => {
113
- switch (error.code) {
114
- case "EISDIR":
115
- await rmdir(configFilePath)
116
- break
117
- case "ENOENT":
118
- await mkdir(configDirectoryPath)
119
- break
120
- default:
121
- throw error
122
- }
123
- await writeFile(configFilePath, json)
124
- })
125
- },
126
- logInfo = ({ file, users, minLength, error }, hackmudPath) => {
127
- error ?
128
- logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
129
- : console.log(
130
- `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")}`
131
- )
132
- },
133
- log = message => {
134
- console.log(colourS(message))
135
- },
136
- logError = message => {
137
- console.error(colourD(message))
138
- process.exitCode = 1
139
- }
23
+ log = message => console.log(colourS(message))
140
24
  for (const argument of process.argv.slice(2))
141
25
  if ("-" == argument[0]) {
142
26
  const [key, valueRaw] = argument.split("=")
@@ -153,35 +37,10 @@ for (const argument of process.argv.slice(2))
153
37
  else for (const option of key.slice(1)) options.set(option, value)
154
38
  } else commands.push(argument)
155
39
  if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
156
- console.log("0.19.1-bf4dc4a")
40
+ console.log(version)
157
41
  process.exit()
158
42
  }
159
- let configDidNotExist = !1
160
- const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
161
- configFile => {
162
- let temporaryConfig
163
- try {
164
- temporaryConfig = JSON.parse(configFile)
165
- } catch {
166
- log("Config file was corrupted, resetting")
167
- return {}
168
- }
169
- if (!temporaryConfig || "object" != typeof temporaryConfig) {
170
- log("Config file was corrupted, resetting")
171
- return {}
172
- }
173
- if ("hackmudPath" in temporaryConfig && "string" != typeof temporaryConfig.hackmudPath) {
174
- log('Property "hackmudPath" of config file was corrupted, removing')
175
- delete temporaryConfig.hackmudPath
176
- }
177
- return temporaryConfig
178
- },
179
- () => {
180
- configDidNotExist = !0
181
- return {}
182
- }
183
- ),
184
- pushModule = import("../push.js"),
43
+ const pushModule = import("../push.js"),
185
44
  processScriptModule = import("../processScript/index.js"),
186
45
  watchModule = import("../watch.js"),
187
46
  chokidarModule = import("chokidar"),
@@ -206,12 +65,8 @@ let autoExit = !0
206
65
  switch (commands[0]) {
207
66
  case "push":
208
67
  {
209
- const { hackmudPath } = await configPromise
210
- if (!hackmudPath) {
211
- logNeedHackmudPathMessage()
212
- break
213
- }
214
- const sourcePath = commands[1]
68
+ const hackmudPath = getHackmudPath(),
69
+ sourcePath = commands[1]
215
70
  if (!sourcePath) {
216
71
  logError("Must provide the directory to push from\n")
217
72
  logHelp()
@@ -279,12 +134,8 @@ switch (commands[0]) {
279
134
  case "dev":
280
135
  case "watch":
281
136
  {
282
- const { hackmudPath } = await configPromise
283
- if (!hackmudPath) {
284
- logNeedHackmudPathMessage()
285
- break
286
- }
287
- const sourcePath = commands[1]
137
+ const hackmudPath = getHackmudPath(),
138
+ sourcePath = commands[1]
288
139
  if (!sourcePath) {
289
140
  logError("Must provide the directory to watch\n")
290
141
  logHelp()
@@ -357,34 +208,24 @@ switch (commands[0]) {
357
208
  break
358
209
  case "pull":
359
210
  {
360
- const { hackmudPath } = await configPromise
361
- if (!hackmudPath) {
362
- logNeedHackmudPathMessage()
363
- break
364
- }
365
- const script = commands[1]
211
+ const hackmudPath = getHackmudPath(),
212
+ script = commands[1]
366
213
  if (!script) {
367
214
  logError("Must provide the script to pull\n")
368
215
  logHelp()
369
216
  break
370
217
  }
371
218
  const sourcePath = commands[2] || "."
372
- try {
373
- await pull(sourcePath, hackmudPath, script)
374
- } catch (error) {
219
+ await pull(sourcePath, hackmudPath, script).catch(error => {
375
220
  console.error(error)
376
221
  logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
377
- }
222
+ })
378
223
  }
379
224
  break
380
225
  case "sync-macros":
381
226
  {
382
- const { hackmudPath } = await configPromise
383
- if (!hackmudPath) {
384
- logNeedHackmudPathMessage()
385
- break
386
- }
387
- const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
227
+ const hackmudPath = getHackmudPath(),
228
+ { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
388
229
  log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
389
230
  }
390
231
  break
@@ -401,79 +242,17 @@ switch (commands[0]) {
401
242
  }
402
243
  const sourcePath = resolve(target),
403
244
  outputPath = commands[2] || "./player.d.ts",
404
- typeDeclaration = await generateTypeDeclaration(sourcePath, (await configPromise).hackmudPath)
245
+ typeDeclaration = await generateTypeDeclaration(sourcePath, getHackmudPath())
405
246
  let typeDeclarationPath = resolve(outputPath)
406
- try {
407
- await writeFile(typeDeclarationPath, typeDeclaration)
408
- } catch (error) {
409
- assert(error instanceof Error)
247
+ await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
248
+ assert(error instanceof Error, "src/bin/hsm.ts:327:35")
410
249
  if ("EISDIR" != error.code) throw error
411
250
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
412
- await writeFile(typeDeclarationPath, typeDeclaration)
413
- }
251
+ return writeFile(typeDeclarationPath, typeDeclaration)
252
+ })
414
253
  log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
415
254
  }
416
255
  break
417
- case "config":
418
- switch (commands[1]) {
419
- case "get":
420
- {
421
- const key = commands[2],
422
- config = await configPromise
423
- if (key) {
424
- const [value, error] = catchError(() => getDeepObjectProperty(config, key.split(".")))
425
- error ? logError("Could not get key " + colourV(key))
426
- : "string" == typeof value ? log(value)
427
- : console.log(value)
428
- } else console.log(config)
429
- }
430
- break
431
- case "delete":
432
- {
433
- const key = commands[2]
434
- if (!key) {
435
- logError("Must provide a key to delete\n")
436
- logHelp()
437
- break
438
- }
439
- const keys = key.split("."),
440
- lastKey = keys.pop(),
441
- config = await configPromise,
442
- object = getDeepObjectProperty(config, keys)
443
- if (isRecord(object)) {
444
- delete object[lastKey]
445
- await updateConfig(config)
446
- log(`Removed ${colourV(key)} from config file:`)
447
- console.log(config)
448
- } else log("Could not delete " + colourV(key))
449
- }
450
- break
451
- case "set":
452
- {
453
- const key = commands[2],
454
- value = commands[3]
455
- if (!key) {
456
- logError("Must provide a key and value\n")
457
- logHelp()
458
- break
459
- }
460
- if (!value) {
461
- logError(`Must provide a value for the key ${colourV(key)}\n`)
462
- logHelp()
463
- break
464
- }
465
- const config = await configPromise
466
- setDeepObjectProperty(config, key.split("."), value)
467
- log(`Set ${colourV(key)} to ${colourV(value)}:`)
468
- console.log(config)
469
- await updateConfig(config)
470
- }
471
- break
472
- default:
473
- commands[1] && logError(`Unknown command: ${colourL(commands[1])}\n`)
474
- logHelp()
475
- }
476
- break
477
256
  case "help":
478
257
  case "h":
479
258
  logHelp()
@@ -501,7 +280,7 @@ switch (commands[0]) {
501
280
  scriptUser =
502
281
  "scripts" == basename(resolve(target, "..")) && "hackmud" == basename(resolve(target, "../../..")) ?
503
282
  basename(resolve(target, "../.."))
504
- : "UNKNOWN",
283
+ : void 0,
505
284
  optionsHasNoMinify = options.has("no-minify")
506
285
  if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
507
286
  logError(
@@ -537,36 +316,31 @@ switch (commands[0]) {
537
316
  : fileBaseName + ".js"
538
317
  )
539
318
  const golfFile = () =>
540
- readFile(target, { encoding: "utf-8" }).then(
541
- async source => {
542
- const timeStart = performance.now(),
543
- { script, warnings } = await processScript(source, {
544
- minify: !(options.get("no-minify") || options.get("skip-minify")),
545
- scriptUser,
546
- scriptName,
547
- filePath: target,
548
- mangleNames,
549
- forceQuineCheats
550
- }),
551
- timeTook = performance.now() - timeStart
552
- for (const { message, line } of warnings)
553
- log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
554
- await writeFilePersistent(outputPath, script)
555
- .catch(async error => {
556
- if (!commands[2] || "EISDIR" != error.code) throw error
557
- outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
558
- await writeFilePersistent(outputPath, script)
559
- })
560
- .then(
561
- () =>
562
- log(
563
- `Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
564
- ),
565
- error => logError(error.message)
319
+ readFile(target, { encoding: "utf-8" }).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`
566
341
  )
567
- },
568
- error => logError(error.message)
569
- )
342
+ )
343
+ })
570
344
  if (options.get("watch")) {
571
345
  const { watch: watchFile } = await chokidarModule
572
346
  watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
@@ -581,3 +355,82 @@ switch (commands[0]) {
581
355
  logHelp()
582
356
  }
583
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({ file, users, minLength, error }, hackmudPath) {
414
+ error ?
415
+ logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
416
+ : console.log(
417
+ `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")}`
418
+ )
419
+ }
420
+ function logError(message) {
421
+ console.error(colourD(message))
422
+ process.exitCode = 1
423
+ }
424
+ function getHackmudPath() {
425
+ const hackmudPathOption = options.get("hackmud-path")
426
+ if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
427
+ logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
428
+ logHelp()
429
+ process.exit(1)
430
+ }
431
+ return (
432
+ hackmudPathOption ||
433
+ process.env.HSM_HACKMUD_PATH ||
434
+ ("win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud"))
435
+ )
436
+ }
@@ -1,2 +1 @@
1
- export declare const generateTypeDeclaration: (sourceDirectory: string, hackmudPath?: string) => Promise<string>;
2
- export default generateTypeDeclaration;
1
+ export declare function generateTypeDeclaration(sourceDirectory: string, hackmudPath?: string): Promise<string>;
@@ -1,6 +1,6 @@
1
1
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
2
2
  import { basename, resolve } from "path"
3
- const generateTypeDeclaration = async (sourceDirectory, hackmudPath) => {
3
+ async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
4
4
  const users = new Set()
5
5
  if (hackmudPath)
6
6
  for (const { stats, name } of await readDirectoryWithStats(hackmudPath))
@@ -65,4 +65,4 @@ const generateTypeDeclaration = async (sourceDirectory, hackmudPath) => {
65
65
  o += "}\n"
66
66
  return o
67
67
  }
68
- export { generateTypeDeclaration as default, generateTypeDeclaration }
68
+ export { generateTypeDeclaration }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.19.1-bf4dc4a",
3
+ "version": "0.19.1-c2f3057",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -69,17 +69,16 @@
69
69
  "rollup": "^4.14.2",
70
70
  "terser": "^5.30.3"
71
71
  },
72
- "engines": {
73
- "node": "^18 || >=20",
74
- "pnpm": "^9.0.1"
75
- },
76
72
  "type": "module",
77
73
  "exports": {
74
+ ".": "./index.js",
78
75
  "./*": "./*.js",
79
76
  "./*.js": "./*.js"
80
77
  },
81
78
  "bin": {
82
- "hsm.d": "bin/hsm.d.ts",
83
79
  "hsm": "bin/hsm.js"
80
+ },
81
+ "engines": {
82
+ "node": "^18 || >=20"
84
83
  }
85
84
  }
@@ -3,38 +3,29 @@ export { minify } from "./minify";
3
3
  export { postprocess } from "./postprocess";
4
4
  export { preprocess } from "./preprocess";
5
5
  export { transform } from "./transform";
6
- export type ProcessOptions = {
7
- /** whether to minify the given code */
8
- minify: boolean;
9
- /** 11 a-z 0-9 characters */
10
- uniqueID: string;
11
- /** the user going to be hosting this script (or set to `true` if not yet known) */
12
- scriptUser: string | true;
13
- /** the name of this script (or set to `true` if not yet known) */
14
- scriptName: string | true;
6
+ export type ProcessOptions = LaxPartial<{
7
+ /** whether to minify the given code */ minify: boolean;
8
+ /** 11 a-z 0-9 characters */ uniqueID: string;
9
+ /** the user going to be hosting this script (or set to `true` if not yet known) */ scriptUser: string | true;
15
10
  filePath: string;
16
- /** whether to mangle function and class names (defaults to `false`) */
17
- mangleNames: boolean;
18
- /**
19
- * when set to `true` forces use of quine cheats
20
- *
21
- * when set to `false` forces quine cheats not to be used
22
- *
23
- * when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
24
- */
11
+ /** whether to mangle function and class names (defaults to `false`) */ mangleNames: boolean;
12
+ /** when set to `true` forces use of quine cheats
13
+ *
14
+ * when set to `false` forces quine cheats not to be used
15
+ *
16
+ * when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
17
+ */
25
18
  forceQuineCheats: boolean;
19
+ }> & {
20
+ scriptName: string | true;
26
21
  };
27
- /**
28
- * Minifies a given script
29
- *
30
- * @param code JavaScript or TypeScript code
31
- * @param options {@link ProcessOptions details}
32
- */
33
- export declare const processScript: (code: string, { minify: shouldMinify, uniqueID, scriptUser, scriptName, filePath, mangleNames, forceQuineCheats }?: LaxPartial<ProcessOptions>) => Promise<{
22
+ /** Minifies a given script
23
+ * @param code JavaScript or TypeScript code
24
+ * @param options {@link ProcessOptions details} */
25
+ export declare function processScript(code: string, { minify: shouldMinify, uniqueID, scriptUser, scriptName, filePath, mangleNames, forceQuineCheats }: ProcessOptions): Promise<{
34
26
  script: string;
35
27
  warnings: {
36
28
  message: string;
37
29
  line: number;
38
30
  }[];
39
31
  }>;
40
- export default processScript;