hackmud-script-manager 0.19.1-3ef8894 → 0.19.1-531ddb2
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/bin/hsm.js +181 -232
- package/generateTypeDeclaration.js +18 -18
- package/index.js +2 -1
- package/package.json +5 -7
- package/processScript/index.js +257 -240
- package/processScript/minify.js +380 -394
- package/processScript/preprocess.js +93 -93
- package/processScript/shared.js +11 -11
- package/processScript/transform.js +566 -559
- package/pull.js +1 -1
- package/push.js +204 -215
- package/{bin → src/bin}/hsm.d.ts +0 -0
- package/src/generateTypeDeclaration.d.ts +2 -0
- package/src/processScript/index.d.ts +31 -0
- package/src/processScript/minify.d.ts +18 -0
- package/src/processScript/preprocess.d.ts +9 -0
- package/{processScript → src/processScript}/shared.d.ts +1 -1
- package/src/processScript/transform.d.ts +18 -0
- package/src/pull.d.ts +6 -0
- package/src/push.d.ts +29 -0
- package/{syncMacros.d.ts → src/syncMacros.d.ts} +1 -1
- package/src/watch.d.ts +15 -0
- package/syncMacros.js +5 -4
- package/watch.js +21 -22
- package/generateTypeDeclaration.d.ts +0 -2
- package/processScript/index.d.ts +0 -40
- package/processScript/minify.d.ts +0 -24
- package/processScript/preprocess.d.ts +0 -12
- package/processScript/transform.d.ts +0 -24
- package/pull.d.ts +0 -9
- package/push.d.ts +0 -37
- package/tsconfig.tsbuildinfo +0 -1
- package/watch.d.ts +0 -20
- /package/{constants.d.ts → src/constants.d.ts} +0 -0
- /package/{index.d.ts → src/index.d.ts} +0 -0
- /package/{processScript → src/processScript}/postprocess.d.ts +0 -0
package/bin/hsm.js
CHANGED
@@ -1,7 +1,11 @@
|
|
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"
|
4
5
|
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"
|
5
9
|
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
6
10
|
import { readFile, writeFile, mkdir, rmdir } from "fs/promises"
|
7
11
|
import { homedir } from "os"
|
@@ -10,6 +14,7 @@ import { supportedExtensions } from "../constants.js"
|
|
10
14
|
import { generateTypeDeclaration } from "../generateTypeDeclaration.js"
|
11
15
|
import { pull } from "../pull.js"
|
12
16
|
import { syncMacros } from "../syncMacros.js"
|
17
|
+
import "@samual/lib/readDirectoryWithStats"
|
13
18
|
import "@samual/lib/copyFilePersistent"
|
14
19
|
const configDirectoryPath = resolve(homedir(), ".config"),
|
15
20
|
configFilePath = resolve(configDirectoryPath, "hsm.json"),
|
@@ -20,119 +25,7 @@ const configDirectoryPath = resolve(homedir(), ".config"),
|
|
20
25
|
for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
|
21
26
|
return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
|
22
27
|
}),
|
23
|
-
|
24
|
-
console.error(
|
25
|
-
colourS(
|
26
|
-
`${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>")}"`
|
27
|
-
)
|
28
|
-
),
|
29
|
-
logHelp = () => {
|
30
|
-
const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
|
31
|
-
mangleNamesOptionDescription =
|
32
|
-
"Reduce character count further but lose function names in error call stacks",
|
33
|
-
forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off.`
|
34
|
-
console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-3ef8894"))
|
35
|
-
switch (commands[0]) {
|
36
|
-
case "config":
|
37
|
-
switch (commands[1]) {
|
38
|
-
case "get":
|
39
|
-
console.log(
|
40
|
-
`\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
|
41
|
-
)
|
42
|
-
break
|
43
|
-
case "set":
|
44
|
-
console.log(
|
45
|
-
`\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
|
46
|
-
)
|
47
|
-
break
|
48
|
-
case "delete":
|
49
|
-
console.log(
|
50
|
-
`\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>")}`
|
51
|
-
)
|
52
|
-
break
|
53
|
-
default:
|
54
|
-
console.log(
|
55
|
-
colourS(
|
56
|
-
`${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`
|
57
|
-
)
|
58
|
-
)
|
59
|
-
}
|
60
|
-
break
|
61
|
-
case "push":
|
62
|
-
console.log(
|
63
|
-
colourS(
|
64
|
-
`\n${colourJ(pushCommandDescription)}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [<script user>.<script name>...]")}\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}`
|
65
|
-
)
|
66
|
-
)
|
67
|
-
break
|
68
|
-
case "dev":
|
69
|
-
case "watch":
|
70
|
-
console.log(
|
71
|
-
colourS(
|
72
|
-
`\n${colourJ("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("Options:")}\n${colourN("--no-minify")}\n Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n ${mangleNamesOptionDescription}\n${colourN("--type-declaration-path")}=${colourB("<path>")}\n Path to generate a type declaration file for the scripts\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}`
|
73
|
-
)
|
74
|
-
)
|
75
|
-
break
|
76
|
-
case "pull":
|
77
|
-
console.log(
|
78
|
-
colourS(
|
79
|
-
`\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>")}`
|
80
|
-
)
|
81
|
-
)
|
82
|
-
break
|
83
|
-
case "minify":
|
84
|
-
case "golf":
|
85
|
-
console.log(
|
86
|
-
colourS(
|
87
|
-
`\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 ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n ${forceQuineCheatsOptionDescription}\n${colourN("--watch")}\n Watch for changes`
|
88
|
-
)
|
89
|
-
)
|
90
|
-
break
|
91
|
-
case "generate-type-declaration":
|
92
|
-
case "gen-type-declaration":
|
93
|
-
case "gen-dts":
|
94
|
-
case "gen-types":
|
95
|
-
console.log(
|
96
|
-
colourS(
|
97
|
-
`${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]")}`
|
98
|
-
)
|
99
|
-
)
|
100
|
-
break
|
101
|
-
case "sync-macros":
|
102
|
-
console.log("\n" + colourJ("Sync macros across all hackmud users"))
|
103
|
-
break
|
104
|
-
default:
|
105
|
-
console.log(
|
106
|
-
colourS(
|
107
|
-
`\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`
|
108
|
-
)
|
109
|
-
)
|
110
|
-
}
|
111
|
-
},
|
112
|
-
exploreObject = (object, keys, createPath = !1) => {
|
113
|
-
for (const key of keys)
|
114
|
-
object =
|
115
|
-
createPath ?
|
116
|
-
"object" == typeof object[key] ?
|
117
|
-
object[key]
|
118
|
-
: (object[key] = {})
|
119
|
-
: object?.[key]
|
120
|
-
return object
|
121
|
-
},
|
122
|
-
logInfo = ({ file, users, minLength, error }, hackmudPath) => {
|
123
|
-
error ?
|
124
|
-
logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
|
125
|
-
: console.log(
|
126
|
-
`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")}`
|
127
|
-
)
|
128
|
-
},
|
129
|
-
log = message => {
|
130
|
-
console.log(colourS(message))
|
131
|
-
},
|
132
|
-
logError = message => {
|
133
|
-
console.error(colourD(message))
|
134
|
-
process.exitCode = 1
|
135
|
-
}
|
28
|
+
log = message => console.log(colourS(message))
|
136
29
|
for (const argument of process.argv.slice(2))
|
137
30
|
if ("-" == argument[0]) {
|
138
31
|
const [key, valueRaw] = argument.split("=")
|
@@ -149,20 +42,14 @@ for (const argument of process.argv.slice(2))
|
|
149
42
|
else for (const option of key.slice(1)) options.set(option, value)
|
150
43
|
} else commands.push(argument)
|
151
44
|
if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
|
152
|
-
console.log("0.19.1-
|
45
|
+
console.log("0.19.1-531ddb2")
|
153
46
|
process.exit()
|
154
47
|
}
|
155
48
|
let configDidNotExist = !1
|
156
49
|
const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
|
157
50
|
configFile => {
|
158
|
-
|
159
|
-
|
160
|
-
temporaryConfig = JSON.parse(configFile)
|
161
|
-
} catch {
|
162
|
-
log("Config file was corrupted, resetting")
|
163
|
-
return {}
|
164
|
-
}
|
165
|
-
if (!temporaryConfig || "object" != typeof temporaryConfig) {
|
51
|
+
const [temporaryConfig, error] = catchError(() => JSON.parse(configFile))
|
52
|
+
if (error || !isRecord(temporaryConfig)) {
|
166
53
|
log("Config file was corrupted, resetting")
|
167
54
|
return {}
|
168
55
|
}
|
@@ -199,15 +86,13 @@ if (options.get("help") || options.get("h")) {
|
|
199
86
|
process.exit()
|
200
87
|
}
|
201
88
|
let autoExit = !0
|
89
|
+
const getDefaultHackmudPath = () =>
|
90
|
+
"win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud")
|
202
91
|
switch (commands[0]) {
|
203
92
|
case "push":
|
204
93
|
{
|
205
|
-
const { hackmudPath } = await configPromise
|
206
|
-
|
207
|
-
logNeedHackmudPathMessage()
|
208
|
-
break
|
209
|
-
}
|
210
|
-
const sourcePath = commands[1]
|
94
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
95
|
+
sourcePath = commands[1]
|
211
96
|
if (!sourcePath) {
|
212
97
|
logError("Must provide the directory to push from\n")
|
213
98
|
logHelp()
|
@@ -275,12 +160,8 @@ switch (commands[0]) {
|
|
275
160
|
case "dev":
|
276
161
|
case "watch":
|
277
162
|
{
|
278
|
-
const { hackmudPath } = await configPromise
|
279
|
-
|
280
|
-
logNeedHackmudPathMessage()
|
281
|
-
break
|
282
|
-
}
|
283
|
-
const sourcePath = commands[1]
|
163
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
164
|
+
sourcePath = commands[1]
|
284
165
|
if (!sourcePath) {
|
285
166
|
logError("Must provide the directory to watch\n")
|
286
167
|
logHelp()
|
@@ -353,34 +234,24 @@ switch (commands[0]) {
|
|
353
234
|
break
|
354
235
|
case "pull":
|
355
236
|
{
|
356
|
-
const { hackmudPath } = await configPromise
|
357
|
-
|
358
|
-
logNeedHackmudPathMessage()
|
359
|
-
break
|
360
|
-
}
|
361
|
-
const script = commands[1]
|
237
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
238
|
+
script = commands[1]
|
362
239
|
if (!script) {
|
363
240
|
logError("Must provide the script to pull\n")
|
364
241
|
logHelp()
|
365
242
|
break
|
366
243
|
}
|
367
244
|
const sourcePath = commands[2] || "."
|
368
|
-
|
369
|
-
await pull(sourcePath, hackmudPath, script)
|
370
|
-
} catch (error) {
|
245
|
+
await pull(sourcePath, hackmudPath, script).catch(error => {
|
371
246
|
console.error(error)
|
372
247
|
logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
|
373
|
-
}
|
248
|
+
})
|
374
249
|
}
|
375
250
|
break
|
376
251
|
case "sync-macros":
|
377
252
|
{
|
378
|
-
const { hackmudPath } = await configPromise
|
379
|
-
|
380
|
-
logNeedHackmudPathMessage()
|
381
|
-
break
|
382
|
-
}
|
383
|
-
const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
|
253
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
254
|
+
{ macrosSynced, usersSynced } = await syncMacros(hackmudPath)
|
384
255
|
log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
|
385
256
|
}
|
386
257
|
break
|
@@ -397,16 +268,17 @@ switch (commands[0]) {
|
|
397
268
|
}
|
398
269
|
const sourcePath = resolve(target),
|
399
270
|
outputPath = commands[2] || "./player.d.ts",
|
400
|
-
typeDeclaration = await generateTypeDeclaration(
|
271
|
+
typeDeclaration = await generateTypeDeclaration(
|
272
|
+
sourcePath,
|
273
|
+
(await configPromise).hackmudPath || getDefaultHackmudPath()
|
274
|
+
)
|
401
275
|
let typeDeclarationPath = resolve(outputPath)
|
402
|
-
|
403
|
-
|
404
|
-
} catch (error) {
|
405
|
-
assert(error instanceof Error)
|
276
|
+
await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
|
277
|
+
assert(error instanceof Error, "src/bin/hsm.ts:365:35")
|
406
278
|
if ("EISDIR" != error.code) throw error
|
407
279
|
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
408
|
-
|
409
|
-
}
|
280
|
+
return writeFile(typeDeclarationPath, typeDeclaration)
|
281
|
+
})
|
410
282
|
log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
|
411
283
|
}
|
412
284
|
break
|
@@ -414,8 +286,14 @@ switch (commands[0]) {
|
|
414
286
|
switch (commands[1]) {
|
415
287
|
case "get":
|
416
288
|
{
|
417
|
-
const key = commands[2]
|
418
|
-
|
289
|
+
const key = commands[2],
|
290
|
+
config = await configPromise
|
291
|
+
if (key) {
|
292
|
+
const [value, error] = catchError(() => getDeepObjectProperty(config, key.split(".")))
|
293
|
+
error ? logError("Could not get key " + colourV(key))
|
294
|
+
: "string" == typeof value ? log(value)
|
295
|
+
: console.log(value)
|
296
|
+
} else console.log(config)
|
419
297
|
}
|
420
298
|
break
|
421
299
|
case "delete":
|
@@ -426,14 +304,16 @@ switch (commands[0]) {
|
|
426
304
|
logHelp()
|
427
305
|
break
|
428
306
|
}
|
429
|
-
const
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
307
|
+
const keys = key.split("."),
|
308
|
+
lastKey = keys.pop(),
|
309
|
+
config = await configPromise,
|
310
|
+
object = getDeepObjectProperty(config, keys)
|
311
|
+
if (isRecord(object)) {
|
312
|
+
delete object[lastKey]
|
313
|
+
await updateConfig(config)
|
314
|
+
log(`Removed ${colourV(key)} from config file:`)
|
315
|
+
console.log(config)
|
316
|
+
} else log("Could not delete " + colourV(key))
|
437
317
|
}
|
438
318
|
break
|
439
319
|
case "set":
|
@@ -445,49 +325,20 @@ switch (commands[0]) {
|
|
445
325
|
logHelp()
|
446
326
|
break
|
447
327
|
}
|
448
|
-
const keys = key.split("."),
|
449
|
-
pathName = keys
|
450
|
-
.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
|
451
|
-
.join(".")
|
452
328
|
if (!value) {
|
453
|
-
logError(`Must provide a value for the key ${
|
329
|
+
logError(`Must provide a value for the key ${colourV(key)}\n`)
|
454
330
|
logHelp()
|
455
331
|
break
|
456
332
|
}
|
457
|
-
const
|
458
|
-
|
459
|
-
|
460
|
-
let object = config
|
461
|
-
for (const key of keys)
|
462
|
-
if ("object" == typeof object[key]) object = object[key]
|
463
|
-
else {
|
464
|
-
object[key] = {}
|
465
|
-
object = object[key]
|
466
|
-
}
|
467
|
-
object[lastKey] = value
|
468
|
-
} else config.hackmudPath = resolve(value.startsWith("~/") ? homedir() + value.slice(1) : value)
|
333
|
+
const config = await configPromise
|
334
|
+
setDeepObjectProperty(config, key.split("."), value)
|
335
|
+
log(`Set ${colourV(key)} to ${colourV(value)}:`)
|
469
336
|
console.log(config)
|
470
|
-
await (
|
471
|
-
const json = JSON.stringify(config, void 0, "\t")
|
472
|
-
configDidNotExist && log("Creating config file at " + configFilePath)
|
473
|
-
await writeFile(configFilePath, json).catch(async error => {
|
474
|
-
switch (error.code) {
|
475
|
-
case "EISDIR":
|
476
|
-
await rmdir(configFilePath)
|
477
|
-
break
|
478
|
-
case "ENOENT":
|
479
|
-
await mkdir(configDirectoryPath)
|
480
|
-
break
|
481
|
-
default:
|
482
|
-
throw error
|
483
|
-
}
|
484
|
-
await writeFile(configFilePath, json)
|
485
|
-
})
|
486
|
-
})(config)
|
337
|
+
await updateConfig(config)
|
487
338
|
}
|
488
339
|
break
|
489
340
|
default:
|
490
|
-
commands[1] && logError(`Unknown command: ${
|
341
|
+
commands[1] && logError(`Unknown command: ${colourL(commands[1])}\n`)
|
491
342
|
logHelp()
|
492
343
|
}
|
493
344
|
break
|
@@ -554,36 +405,31 @@ switch (commands[0]) {
|
|
554
405
|
: fileBaseName + ".js"
|
555
406
|
)
|
556
407
|
const golfFile = () =>
|
557
|
-
readFile(target, { encoding: "utf-8" }).then(
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
()
|
579
|
-
log(
|
580
|
-
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
581
|
-
),
|
582
|
-
error => logError(error.message)
|
408
|
+
readFile(target, { encoding: "utf-8" }).then(async source => {
|
409
|
+
const timeStart = performance.now(),
|
410
|
+
{ script, warnings } = await processScript(source, {
|
411
|
+
minify: !(options.get("no-minify") || options.get("skip-minify")),
|
412
|
+
scriptUser,
|
413
|
+
scriptName,
|
414
|
+
filePath: target,
|
415
|
+
mangleNames,
|
416
|
+
forceQuineCheats
|
417
|
+
}),
|
418
|
+
timeTook = performance.now() - timeStart
|
419
|
+
for (const { message, line } of warnings)
|
420
|
+
log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
|
421
|
+
await writeFilePersistent(outputPath, script)
|
422
|
+
.catch(error => {
|
423
|
+
if (!commands[2] || "EISDIR" != error.code) throw error
|
424
|
+
outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
|
425
|
+
return writeFilePersistent(outputPath, script)
|
426
|
+
})
|
427
|
+
.then(() =>
|
428
|
+
log(
|
429
|
+
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
583
430
|
)
|
584
|
-
|
585
|
-
|
586
|
-
)
|
431
|
+
)
|
432
|
+
})
|
587
433
|
if (options.get("watch")) {
|
588
434
|
const { watch: watchFile } = await chokidarModule
|
589
435
|
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
@@ -594,7 +440,110 @@ switch (commands[0]) {
|
|
594
440
|
}
|
595
441
|
break
|
596
442
|
default:
|
597
|
-
commands[0] && logError(`Unknown command: ${
|
443
|
+
commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
|
598
444
|
logHelp()
|
599
445
|
}
|
600
446
|
autoExit && process.exit()
|
447
|
+
function logHelp() {
|
448
|
+
const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
|
449
|
+
forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`
|
450
|
+
console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-531ddb2"))
|
451
|
+
switch (commands[0]) {
|
452
|
+
case "config":
|
453
|
+
switch (commands[1]) {
|
454
|
+
case "get":
|
455
|
+
console.log(
|
456
|
+
`\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
|
457
|
+
)
|
458
|
+
break
|
459
|
+
case "set":
|
460
|
+
console.log(
|
461
|
+
`\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
|
462
|
+
)
|
463
|
+
break
|
464
|
+
case "delete":
|
465
|
+
console.log(
|
466
|
+
`\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>")}`
|
467
|
+
)
|
468
|
+
break
|
469
|
+
default:
|
470
|
+
console.log(
|
471
|
+
colourS(
|
472
|
+
`${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`
|
473
|
+
)
|
474
|
+
)
|
475
|
+
}
|
476
|
+
break
|
477
|
+
case "dev":
|
478
|
+
case "watch":
|
479
|
+
case "push":
|
480
|
+
console.log(
|
481
|
+
colourS(
|
482
|
+
`\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`
|
483
|
+
)
|
484
|
+
)
|
485
|
+
break
|
486
|
+
case "pull":
|
487
|
+
console.log(
|
488
|
+
colourS(
|
489
|
+
`\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>")}`
|
490
|
+
)
|
491
|
+
)
|
492
|
+
break
|
493
|
+
case "minify":
|
494
|
+
case "golf":
|
495
|
+
console.log(
|
496
|
+
colourS(
|
497
|
+
`\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`
|
498
|
+
)
|
499
|
+
)
|
500
|
+
break
|
501
|
+
case "generate-type-declaration":
|
502
|
+
case "gen-type-declaration":
|
503
|
+
case "gen-dts":
|
504
|
+
case "gen-types":
|
505
|
+
console.log(
|
506
|
+
colourS(
|
507
|
+
`${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]")}`
|
508
|
+
)
|
509
|
+
)
|
510
|
+
break
|
511
|
+
case "sync-macros":
|
512
|
+
console.log("\n" + colourJ("Sync macros across all hackmud users"))
|
513
|
+
break
|
514
|
+
default:
|
515
|
+
console.log(
|
516
|
+
colourS(
|
517
|
+
`\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`
|
518
|
+
)
|
519
|
+
)
|
520
|
+
}
|
521
|
+
}
|
522
|
+
async function updateConfig(config) {
|
523
|
+
const json = JSON.stringify(config, void 0, "\t")
|
524
|
+
configDidNotExist && log("Creating config file at " + configFilePath)
|
525
|
+
await writeFile(configFilePath, json).catch(async error => {
|
526
|
+
switch (error.code) {
|
527
|
+
case "EISDIR":
|
528
|
+
await rmdir(configFilePath)
|
529
|
+
break
|
530
|
+
case "ENOENT":
|
531
|
+
await mkdir(configDirectoryPath)
|
532
|
+
break
|
533
|
+
default:
|
534
|
+
throw error
|
535
|
+
}
|
536
|
+
await writeFile(configFilePath, json)
|
537
|
+
})
|
538
|
+
}
|
539
|
+
function logInfo({ file, users, minLength, error }, hackmudPath) {
|
540
|
+
error ?
|
541
|
+
logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
|
542
|
+
: console.log(
|
543
|
+
`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")}`
|
544
|
+
)
|
545
|
+
}
|
546
|
+
function logError(message) {
|
547
|
+
console.error(colourD(message))
|
548
|
+
process.exitCode = 1
|
549
|
+
}
|
@@ -1,31 +1,31 @@
|
|
1
|
-
import {
|
1
|
+
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
2
2
|
import { basename, resolve } from "path"
|
3
|
-
|
3
|
+
async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
|
4
4
|
const users = new Set()
|
5
5
|
if (hackmudPath)
|
6
|
-
for (const
|
7
|
-
|
6
|
+
for (const { stats, name } of await readDirectoryWithStats(hackmudPath))
|
7
|
+
stats.isFile() && name.endsWith(".key") && users.add(basename(name, ".key"))
|
8
8
|
const wildScripts = [],
|
9
9
|
wildAnyScripts = [],
|
10
10
|
allScripts = {},
|
11
11
|
allAnyScripts = {}
|
12
12
|
await Promise.all(
|
13
|
-
(await
|
14
|
-
if (
|
15
|
-
|
16
|
-
|
17
|
-
:
|
18
|
-
else if (
|
13
|
+
(await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name }) => {
|
14
|
+
if (stats.isFile())
|
15
|
+
name.endsWith(".ts") ?
|
16
|
+
name.endsWith(".d.ts") || wildScripts.push(basename(name, ".ts"))
|
17
|
+
: name.endsWith(".js") && wildAnyScripts.push(basename(name, ".js"))
|
18
|
+
else if (stats.isDirectory()) {
|
19
19
|
const scripts = [],
|
20
20
|
anyScripts = []
|
21
|
-
allScripts[
|
22
|
-
allAnyScripts[
|
23
|
-
users.add(
|
24
|
-
for (const
|
25
|
-
|
26
|
-
(
|
27
|
-
|
28
|
-
:
|
21
|
+
allScripts[name] = scripts
|
22
|
+
allAnyScripts[name] = anyScripts
|
23
|
+
users.add(name)
|
24
|
+
for (const child of await readDirectoryWithStats(resolve(sourceDirectory, name)))
|
25
|
+
child.stats.isFile() &&
|
26
|
+
(child.name.endsWith(".ts") ?
|
27
|
+
name.endsWith(".d.ts") || scripts.push(basename(child.name, ".ts"))
|
28
|
+
: child.name.endsWith(".js") && anyScripts.push(basename(child.name, ".js")))
|
29
29
|
}
|
30
30
|
})
|
31
31
|
)
|
package/index.js
CHANGED
@@ -5,7 +5,7 @@ export { pull } from "./pull.js"
|
|
5
5
|
export { push } from "./push.js"
|
6
6
|
export { syncMacros } from "./syncMacros.js"
|
7
7
|
export { watch } from "./watch.js"
|
8
|
-
import "
|
8
|
+
import "@samual/lib/readDirectoryWithStats"
|
9
9
|
import "path"
|
10
10
|
import "@babel/generator"
|
11
11
|
import "@babel/parser"
|
@@ -47,4 +47,5 @@ import "@samual/lib/clearObject"
|
|
47
47
|
import "@samual/lib/copyFilePersistent"
|
48
48
|
import "@samual/lib/Cache"
|
49
49
|
import "@samual/lib/writeFilePersistent"
|
50
|
+
import "fs/promises"
|
50
51
|
import "chokidar"
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "hackmud-script-manager",
|
3
|
-
"version": "0.19.1-
|
3
|
+
"version": "0.19.1-531ddb2",
|
4
4
|
"description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
|
5
5
|
"keywords": [
|
6
6
|
"api",
|
@@ -59,7 +59,7 @@
|
|
59
59
|
"@rollup/plugin-commonjs": "^25.0.7",
|
60
60
|
"@rollup/plugin-json": "^6.1.0",
|
61
61
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
62
|
-
"@samual/lib": "
|
62
|
+
"@samual/lib": "0.10.2-e64c5bc",
|
63
63
|
"acorn": "^8.11.3",
|
64
64
|
"chalk": "^5.3.0",
|
65
65
|
"chokidar": "^3.6.0",
|
@@ -69,17 +69,15 @@
|
|
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": {
|
78
74
|
"./*": "./*.js",
|
79
75
|
"./*.js": "./*.js"
|
80
76
|
},
|
81
77
|
"bin": {
|
82
|
-
"hsm.d": "bin/hsm.d.ts",
|
83
78
|
"hsm": "bin/hsm.js"
|
79
|
+
},
|
80
|
+
"engines": {
|
81
|
+
"node": "^18 || >=20"
|
84
82
|
}
|
85
83
|
}
|