hackmud-script-manager 0.19.1-4bde221 → 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 +200 -241
- package/generateTypeDeclaration.js +18 -18
- package/index.js +2 -1
- package/package.json +7 -9
- 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 +569 -550
- package/pull.js +1 -1
- package/push.js +45 -39
- 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,117 +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 = "Reduce character count further but lose function names in error call stacks"
|
32
|
-
console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-4bde221"))
|
33
|
-
switch (commands[0]) {
|
34
|
-
case "config":
|
35
|
-
switch (commands[1]) {
|
36
|
-
case "get":
|
37
|
-
console.log(
|
38
|
-
`\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
|
39
|
-
)
|
40
|
-
break
|
41
|
-
case "set":
|
42
|
-
console.log(
|
43
|
-
`\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
|
44
|
-
)
|
45
|
-
break
|
46
|
-
case "delete":
|
47
|
-
console.log(
|
48
|
-
`\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>")}`
|
49
|
-
)
|
50
|
-
break
|
51
|
-
default:
|
52
|
-
console.log(
|
53
|
-
colourS(
|
54
|
-
`${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`
|
55
|
-
)
|
56
|
-
)
|
57
|
-
}
|
58
|
-
break
|
59
|
-
case "push":
|
60
|
-
console.log(
|
61
|
-
colourS(
|
62
|
-
`\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("--skip-minify")}\n Skip minification to produce a readable script\n${colourN("--mangle-names")}\n ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n Force quine cheats even if the character count is higher`
|
63
|
-
)
|
64
|
-
)
|
65
|
-
break
|
66
|
-
case "dev":
|
67
|
-
case "watch":
|
68
|
-
console.log(
|
69
|
-
colourS(
|
70
|
-
`${colourN("Aliases")}: ${colourV("watch, dev")}\n\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("--skip-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 Force quine cheats even if the character count is higher`
|
71
|
-
)
|
72
|
-
)
|
73
|
-
break
|
74
|
-
case "pull":
|
75
|
-
console.log(
|
76
|
-
colourS(
|
77
|
-
`\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>")}`
|
78
|
-
)
|
79
|
-
)
|
80
|
-
break
|
81
|
-
case "minify":
|
82
|
-
case "golf":
|
83
|
-
console.log(
|
84
|
-
colourS(
|
85
|
-
`${colourN("Aliases")}: ${colourV("minify, golf")}\n\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("--skip-minify")}\n Skip minification to produce a readable script\n${colourN("--mangle-names")}\n ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n Force quine cheats even if the character count is higher\n${colourN("--watch")}\n Watch for changes`
|
86
|
-
)
|
87
|
-
)
|
88
|
-
break
|
89
|
-
case "generate-type-declaration":
|
90
|
-
case "gen-type-declaration":
|
91
|
-
case "gen-dts":
|
92
|
-
case "gen-types":
|
93
|
-
console.log(
|
94
|
-
colourS(
|
95
|
-
`${colourN("Aliases")}: ${colourV("generate-type-declaration, gen-type-declaration, gen-types, gen-dts")}\n\n${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]")}`
|
96
|
-
)
|
97
|
-
)
|
98
|
-
break
|
99
|
-
case "sync-macros":
|
100
|
-
console.log("\n" + colourJ("Sync macros across all hackmud users"))
|
101
|
-
break
|
102
|
-
default:
|
103
|
-
console.log(
|
104
|
-
colourS(
|
105
|
-
`\n${colourJ("Hackmud Script Manager")}\n\n${colourA("Commands:")}\n${colourL("push")}\n ${pushCommandDescription}\n${colourL("watch")}, ${colourL("dev")}\n Watch a directory and push a script when modified\n${colourL("minify")}, ${colourL("golf")}\n Minify a script file on the spot\n${colourL("generate-type-declaration")}, ${colourL("gen-type-declaration")}, ${colourL("gen-types")}, ${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`
|
106
|
-
)
|
107
|
-
)
|
108
|
-
}
|
109
|
-
},
|
110
|
-
exploreObject = (object, keys, createPath = !1) => {
|
111
|
-
for (const key of keys)
|
112
|
-
object =
|
113
|
-
createPath ?
|
114
|
-
"object" == typeof object[key] ?
|
115
|
-
object[key]
|
116
|
-
: (object[key] = {})
|
117
|
-
: object?.[key]
|
118
|
-
return object
|
119
|
-
},
|
120
|
-
logInfo = ({ file, users, minLength, error }, hackmudPath) => {
|
121
|
-
error ?
|
122
|
-
logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
|
123
|
-
: console.log(
|
124
|
-
`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")}`
|
125
|
-
)
|
126
|
-
},
|
127
|
-
log = message => {
|
128
|
-
console.log(colourS(message))
|
129
|
-
},
|
130
|
-
logError = message => {
|
131
|
-
console.error(colourD(message))
|
132
|
-
process.exitCode = 1
|
133
|
-
}
|
28
|
+
log = message => console.log(colourS(message))
|
134
29
|
for (const argument of process.argv.slice(2))
|
135
30
|
if ("-" == argument[0]) {
|
136
31
|
const [key, valueRaw] = argument.split("=")
|
@@ -147,20 +42,14 @@ for (const argument of process.argv.slice(2))
|
|
147
42
|
else for (const option of key.slice(1)) options.set(option, value)
|
148
43
|
} else commands.push(argument)
|
149
44
|
if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
|
150
|
-
console.log("0.19.1-
|
45
|
+
console.log("0.19.1-531ddb2")
|
151
46
|
process.exit()
|
152
47
|
}
|
153
48
|
let configDidNotExist = !1
|
154
49
|
const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
|
155
50
|
configFile => {
|
156
|
-
|
157
|
-
|
158
|
-
temporaryConfig = JSON.parse(configFile)
|
159
|
-
} catch {
|
160
|
-
log("Config file was corrupted, resetting")
|
161
|
-
return {}
|
162
|
-
}
|
163
|
-
if (!temporaryConfig || "object" != typeof temporaryConfig) {
|
51
|
+
const [temporaryConfig, error] = catchError(() => JSON.parse(configFile))
|
52
|
+
if (error || !isRecord(temporaryConfig)) {
|
164
53
|
log("Config file was corrupted, resetting")
|
165
54
|
return {}
|
166
55
|
}
|
@@ -197,15 +86,13 @@ if (options.get("help") || options.get("h")) {
|
|
197
86
|
process.exit()
|
198
87
|
}
|
199
88
|
let autoExit = !0
|
89
|
+
const getDefaultHackmudPath = () =>
|
90
|
+
"win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud")
|
200
91
|
switch (commands[0]) {
|
201
92
|
case "push":
|
202
93
|
{
|
203
|
-
const { hackmudPath } = await configPromise
|
204
|
-
|
205
|
-
logNeedHackmudPathMessage()
|
206
|
-
break
|
207
|
-
}
|
208
|
-
const sourcePath = commands[1]
|
94
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
95
|
+
sourcePath = commands[1]
|
209
96
|
if (!sourcePath) {
|
210
97
|
logError("Must provide the directory to push from\n")
|
211
98
|
logHelp()
|
@@ -222,17 +109,20 @@ switch (commands[0]) {
|
|
222
109
|
break
|
223
110
|
}
|
224
111
|
} else scripts.push("*.*")
|
225
|
-
|
226
|
-
|
112
|
+
const optionsHasNoMinify = options.has("no-minify")
|
113
|
+
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
114
|
+
logError(
|
115
|
+
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
116
|
+
)
|
227
117
|
logHelp()
|
228
118
|
break
|
229
119
|
}
|
230
|
-
const shouldSkipMinify = options.get("skip-minify")
|
120
|
+
const shouldSkipMinify = options.get("no-minify") || options.get("skip-minify")
|
231
121
|
let shouldMinify
|
232
122
|
if (null != shouldSkipMinify) {
|
233
123
|
if ("boolean" != typeof shouldSkipMinify) {
|
234
124
|
logError(
|
235
|
-
`The value for ${colourN("--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
|
125
|
+
`The value for ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
|
236
126
|
)
|
237
127
|
logHelp()
|
238
128
|
break
|
@@ -270,12 +160,8 @@ switch (commands[0]) {
|
|
270
160
|
case "dev":
|
271
161
|
case "watch":
|
272
162
|
{
|
273
|
-
const { hackmudPath } = await configPromise
|
274
|
-
|
275
|
-
logNeedHackmudPathMessage()
|
276
|
-
break
|
277
|
-
}
|
278
|
-
const sourcePath = commands[1]
|
163
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
164
|
+
sourcePath = commands[1]
|
279
165
|
if (!sourcePath) {
|
280
166
|
logError("Must provide the directory to watch\n")
|
281
167
|
logHelp()
|
@@ -292,17 +178,20 @@ switch (commands[0]) {
|
|
292
178
|
break
|
293
179
|
}
|
294
180
|
} else scripts.push("*.*")
|
295
|
-
|
296
|
-
|
181
|
+
const optionsHasNoMinify = options.has("no-minify")
|
182
|
+
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
183
|
+
logError(
|
184
|
+
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
185
|
+
)
|
297
186
|
logHelp()
|
298
187
|
break
|
299
188
|
}
|
300
|
-
const shouldSkipMinify = options.get("skip-minify")
|
189
|
+
const shouldSkipMinify = options.get("no-minify") || options.get("skip-minify")
|
301
190
|
let shouldMinify
|
302
191
|
if (null != shouldSkipMinify) {
|
303
192
|
if ("boolean" != typeof shouldSkipMinify) {
|
304
193
|
logError(
|
305
|
-
`The value for ${colourN("--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
|
194
|
+
`The value for ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
|
306
195
|
)
|
307
196
|
logHelp()
|
308
197
|
break
|
@@ -345,34 +234,24 @@ switch (commands[0]) {
|
|
345
234
|
break
|
346
235
|
case "pull":
|
347
236
|
{
|
348
|
-
const { hackmudPath } = await configPromise
|
349
|
-
|
350
|
-
logNeedHackmudPathMessage()
|
351
|
-
break
|
352
|
-
}
|
353
|
-
const script = commands[1]
|
237
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
238
|
+
script = commands[1]
|
354
239
|
if (!script) {
|
355
240
|
logError("Must provide the script to pull\n")
|
356
241
|
logHelp()
|
357
242
|
break
|
358
243
|
}
|
359
244
|
const sourcePath = commands[2] || "."
|
360
|
-
|
361
|
-
await pull(sourcePath, hackmudPath, script)
|
362
|
-
} catch (error) {
|
245
|
+
await pull(sourcePath, hackmudPath, script).catch(error => {
|
363
246
|
console.error(error)
|
364
247
|
logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
|
365
|
-
}
|
248
|
+
})
|
366
249
|
}
|
367
250
|
break
|
368
251
|
case "sync-macros":
|
369
252
|
{
|
370
|
-
const { hackmudPath } = await configPromise
|
371
|
-
|
372
|
-
logNeedHackmudPathMessage()
|
373
|
-
break
|
374
|
-
}
|
375
|
-
const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
|
253
|
+
const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
|
254
|
+
{ macrosSynced, usersSynced } = await syncMacros(hackmudPath)
|
376
255
|
log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
|
377
256
|
}
|
378
257
|
break
|
@@ -389,16 +268,17 @@ switch (commands[0]) {
|
|
389
268
|
}
|
390
269
|
const sourcePath = resolve(target),
|
391
270
|
outputPath = commands[2] || "./player.d.ts",
|
392
|
-
typeDeclaration = await generateTypeDeclaration(
|
271
|
+
typeDeclaration = await generateTypeDeclaration(
|
272
|
+
sourcePath,
|
273
|
+
(await configPromise).hackmudPath || getDefaultHackmudPath()
|
274
|
+
)
|
393
275
|
let typeDeclarationPath = resolve(outputPath)
|
394
|
-
|
395
|
-
|
396
|
-
} catch (error) {
|
397
|
-
assert(error instanceof Error)
|
276
|
+
await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
|
277
|
+
assert(error instanceof Error, "src/bin/hsm.ts:365:35")
|
398
278
|
if ("EISDIR" != error.code) throw error
|
399
279
|
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
400
|
-
|
401
|
-
}
|
280
|
+
return writeFile(typeDeclarationPath, typeDeclaration)
|
281
|
+
})
|
402
282
|
log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
|
403
283
|
}
|
404
284
|
break
|
@@ -406,8 +286,14 @@ switch (commands[0]) {
|
|
406
286
|
switch (commands[1]) {
|
407
287
|
case "get":
|
408
288
|
{
|
409
|
-
const key = commands[2]
|
410
|
-
|
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)
|
411
297
|
}
|
412
298
|
break
|
413
299
|
case "delete":
|
@@ -418,14 +304,16 @@ switch (commands[0]) {
|
|
418
304
|
logHelp()
|
419
305
|
break
|
420
306
|
}
|
421
|
-
const
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
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))
|
429
317
|
}
|
430
318
|
break
|
431
319
|
case "set":
|
@@ -437,49 +325,20 @@ switch (commands[0]) {
|
|
437
325
|
logHelp()
|
438
326
|
break
|
439
327
|
}
|
440
|
-
const keys = key.split("."),
|
441
|
-
pathName = keys
|
442
|
-
.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
|
443
|
-
.join(".")
|
444
328
|
if (!value) {
|
445
|
-
logError(`Must provide a value for the key ${
|
329
|
+
logError(`Must provide a value for the key ${colourV(key)}\n`)
|
446
330
|
logHelp()
|
447
331
|
break
|
448
332
|
}
|
449
|
-
const
|
450
|
-
|
451
|
-
|
452
|
-
let object = config
|
453
|
-
for (const key of keys)
|
454
|
-
if ("object" == typeof object[key]) object = object[key]
|
455
|
-
else {
|
456
|
-
object[key] = {}
|
457
|
-
object = object[key]
|
458
|
-
}
|
459
|
-
object[lastKey] = value
|
460
|
-
} 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)}:`)
|
461
336
|
console.log(config)
|
462
|
-
await (
|
463
|
-
const json = JSON.stringify(config, void 0, "\t")
|
464
|
-
configDidNotExist && log("Creating config file at " + configFilePath)
|
465
|
-
await writeFile(configFilePath, json).catch(async error => {
|
466
|
-
switch (error.code) {
|
467
|
-
case "EISDIR":
|
468
|
-
await rmdir(configFilePath)
|
469
|
-
break
|
470
|
-
case "ENOENT":
|
471
|
-
await mkdir(configDirectoryPath)
|
472
|
-
break
|
473
|
-
default:
|
474
|
-
throw error
|
475
|
-
}
|
476
|
-
await writeFile(configFilePath, json)
|
477
|
-
})
|
478
|
-
})(config)
|
337
|
+
await updateConfig(config)
|
479
338
|
}
|
480
339
|
break
|
481
340
|
default:
|
482
|
-
commands[1] && logError(`Unknown command: ${
|
341
|
+
commands[1] && logError(`Unknown command: ${colourL(commands[1])}\n`)
|
483
342
|
logHelp()
|
484
343
|
}
|
485
344
|
break
|
@@ -511,9 +370,11 @@ switch (commands[0]) {
|
|
511
370
|
"scripts" == basename(resolve(target, "..")) && "hackmud" == basename(resolve(target, "../../..")) ?
|
512
371
|
basename(resolve(target, "../.."))
|
513
372
|
: "UNKNOWN",
|
514
|
-
|
515
|
-
if (options.has("skip-minify") && options.has("mangle-names")) {
|
516
|
-
logError(
|
373
|
+
optionsHasNoMinify = options.has("no-minify")
|
374
|
+
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
375
|
+
logError(
|
376
|
+
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
377
|
+
)
|
517
378
|
logHelp()
|
518
379
|
break
|
519
380
|
}
|
@@ -544,36 +405,31 @@ switch (commands[0]) {
|
|
544
405
|
: fileBaseName + ".js"
|
545
406
|
)
|
546
407
|
const golfFile = () =>
|
547
|
-
readFile(target, { encoding: "utf-8" }).then(
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
()
|
569
|
-
log(
|
570
|
-
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
571
|
-
),
|
572
|
-
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`
|
573
430
|
)
|
574
|
-
|
575
|
-
|
576
|
-
)
|
431
|
+
)
|
432
|
+
})
|
577
433
|
if (options.get("watch")) {
|
578
434
|
const { watch: watchFile } = await chokidarModule
|
579
435
|
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
@@ -584,7 +440,110 @@ switch (commands[0]) {
|
|
584
440
|
}
|
585
441
|
break
|
586
442
|
default:
|
587
|
-
commands[0] && logError(`Unknown command: ${
|
443
|
+
commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
|
588
444
|
logHelp()
|
589
445
|
}
|
590
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
|
)
|