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

Sign up to get free protection for your applications and to get access to all the features.
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;