hackmud-script-manager 0.20.3 → 0.20.4-0dd1d9b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/bin/hsm.js +193 -236
- package/env.d.ts +704 -1294
- package/generateTypeDeclaration.js +2 -1
- package/index.js +1 -0
- package/package.json +6 -2
- package/processScript/index.js +3 -3
- package/processScript/minify.js +18 -21
- package/processScript/postprocess.d.ts +1 -1
- package/processScript/postprocess.js +3 -3
- package/processScript/preprocess.js +5 -3
- package/processScript/transform.js +68 -91
- package/push.d.ts +9 -1
- package/push.js +33 -11
- package/syncMacros.js +1 -1
- package/watch.js +6 -4
package/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Hackmud Script Manager
|
2
|
-
Command made for [
|
2
|
+
Command made for [Hackmud Scripting Environment](https://github.com/samualtnorman/hackmud-environment), which is a scripting environment for hackmud with minification, autocompletes / intellisense, and TypeScript support.
|
3
|
+
|
4
|
+
[](https://ko-fi.com/R6R0XN5CX)
|
5
|
+
|
6
|
+
You can read about how HSM works [in my blog post](https://samual.uk/blog/js-code-transformation-niche-environment/).
|
3
7
|
|
4
8
|
## Install
|
5
9
|
1. [Install Node.js](https://nodejs.org/en/download)
|
@@ -16,6 +20,10 @@ Command made for [hackmud-environment](https://github.com/samualtnorman/hackmud-
|
|
16
20
|
> ```
|
17
21
|
> You will need to run `Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser` in PowerShell as an administrator. For more information, see [Microsoft's page about Execution Policies](https://learn.microsoft.com/en-gb/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4).
|
18
22
|
|
23
|
+

|
24
|
+

|
25
|
+

|
26
|
+
|
19
27
|
## Features
|
20
28
|
- Minification
|
21
29
|
- This includes auto quine cheating.
|
package/bin/hsm.js
CHANGED
@@ -5,14 +5,16 @@ import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
|
5
5
|
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
6
6
|
import { writeFile, readFile } from "fs/promises"
|
7
7
|
import { homedir } from "os"
|
8
|
-
import { extname, basename,
|
8
|
+
import { resolve, extname, basename, dirname, relative } from "path"
|
9
9
|
import { supportedExtensions } from "../constants.js"
|
10
10
|
import { generateTypeDeclaration } from "../generateTypeDeclaration.js"
|
11
11
|
import { pull } from "../pull.js"
|
12
12
|
import { syncMacros } from "../syncMacros.js"
|
13
13
|
import "@samual/lib/readDirectoryWithStats"
|
14
|
+
import "path/posix"
|
14
15
|
import "@samual/lib/copyFilePersistent"
|
15
|
-
const version = "0.20.
|
16
|
+
const version = "0.20.4-0dd1d9b",
|
17
|
+
formatOption = name => colourN(`-${1 == name.length ? "" : "-"}${name}`),
|
16
18
|
options = new Map(),
|
17
19
|
commands = [],
|
18
20
|
userColours = new Cache(user => {
|
@@ -36,10 +38,6 @@ for (const argument of process.argv.slice(2))
|
|
36
38
|
if ("-" == argument[1]) options.set(key.slice(2), value)
|
37
39
|
else for (const option of key.slice(1)) options.set(option, value)
|
38
40
|
} else commands.push(argument)
|
39
|
-
if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
|
40
|
-
console.log(version)
|
41
|
-
process.exit()
|
42
|
-
}
|
43
41
|
const pushModule = import("../push.js"),
|
44
42
|
processScriptModule = import("../processScript/index.js"),
|
45
43
|
watchModule = import("../watch.js"),
|
@@ -49,6 +47,7 @@ const pushModule = import("../push.js"),
|
|
49
47
|
colourB = chalk.rgb(202, 202, 202),
|
50
48
|
colourC = chalk.rgb(155, 155, 155),
|
51
49
|
colourD = chalk.rgb(255, 0, 0),
|
50
|
+
colourF = chalk.rgb(255, 128, 0),
|
52
51
|
colourJ = chalk.rgb(255, 244, 4),
|
53
52
|
colourK = chalk.rgb(243, 249, 152),
|
54
53
|
colourL = chalk.rgb(30, 255, 0),
|
@@ -57,153 +56,171 @@ const pushModule = import("../push.js"),
|
|
57
56
|
colourS = chalk.rgb(122, 178, 244),
|
58
57
|
colourV = chalk.rgb(255, 0, 236),
|
59
58
|
colourW = chalk.rgb(255, 150, 224)
|
60
|
-
|
59
|
+
process.version.startsWith("v21.") &&
|
60
|
+
console.warn(
|
61
|
+
colourF(
|
62
|
+
"Warning: Support for Node.js 21 will be dropped in the next minor version of HSM\n You should update your version of Node.js\n https://nodejs.org/en/download/package-manager"
|
63
|
+
)
|
64
|
+
)
|
65
|
+
if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
|
66
|
+
console.log(version)
|
67
|
+
process.exit()
|
68
|
+
}
|
69
|
+
if (popOption("help", "h")?.value) {
|
61
70
|
logHelp()
|
62
71
|
process.exit()
|
63
72
|
}
|
64
73
|
let autoExit = !0
|
65
74
|
switch (commands[0]) {
|
66
75
|
case "push":
|
76
|
+
case "dev":
|
77
|
+
case "watch":
|
78
|
+
case "golf":
|
79
|
+
case "minify":
|
67
80
|
{
|
68
|
-
const
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
break
|
74
|
-
}
|
75
|
-
const scripts = commands.slice(2)
|
76
|
-
if (scripts.length) {
|
77
|
-
const invalidScript = scripts.find(
|
78
|
-
script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script)
|
79
|
-
)
|
80
|
-
if (invalidScript) {
|
81
|
-
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`)
|
82
|
-
logHelp()
|
83
|
-
break
|
84
|
-
}
|
85
|
-
} else scripts.push("*.*")
|
86
|
-
const optionsHasNoMinify = options.has("no-minify")
|
87
|
-
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
81
|
+
const noMinifyOption = popOption("no-minify", "skip-minify"),
|
82
|
+
mangleNamesOption = popOption("mangle-names"),
|
83
|
+
forceQuineCheatsOption = popOption("force-quine-cheats"),
|
84
|
+
noMinifyIncompatibleOption = mangleNamesOption || forceQuineCheatsOption
|
85
|
+
if (noMinifyOption && noMinifyIncompatibleOption) {
|
88
86
|
logError(
|
89
|
-
`Options ${
|
87
|
+
`Options ${formatOption(noMinifyOption.name)} and ${formatOption(noMinifyIncompatibleOption.name)} are incompatible\n`
|
90
88
|
)
|
91
89
|
logHelp()
|
92
|
-
|
90
|
+
process.exit(1)
|
93
91
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
92
|
+
noMinifyOption && assertOptionIsBoolean(noMinifyOption)
|
93
|
+
mangleNamesOption && assertOptionIsBoolean(mangleNamesOption)
|
94
|
+
forceQuineCheatsOption && assertOptionIsBoolean(forceQuineCheatsOption)
|
95
|
+
if ("golf" == commands[0] || "minify" == commands[0]) {
|
96
|
+
const watchOption = popOption("watch"),
|
97
|
+
target = commands[1]
|
98
|
+
if (!target) {
|
99
|
+
logError("Must provide target\n")
|
100
|
+
logHelp()
|
101
|
+
process.exit(1)
|
102
|
+
}
|
103
|
+
const fileExtension = extname(target)
|
104
|
+
if (!supportedExtensions.includes(fileExtension)) {
|
98
105
|
logError(
|
99
|
-
`
|
106
|
+
`Unsupported file extension "${chalk.bold(fileExtension)}"\nSupported extensions are "${supportedExtensions.map(extension => chalk.bold(extension)).join('", "')}"`
|
100
107
|
)
|
101
|
-
|
102
|
-
break
|
108
|
+
process.exit(1)
|
103
109
|
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
110
|
+
complainAboutUnrecognisedOptions()
|
111
|
+
const { processScript } = await processScriptModule,
|
112
|
+
fileBaseName = basename(target, fileExtension),
|
113
|
+
fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
|
114
|
+
scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName,
|
115
|
+
scriptUser =
|
116
|
+
(
|
117
|
+
"scripts" == basename(resolve(target, "..")) &&
|
118
|
+
"hackmud" == basename(resolve(target, "../../.."))
|
119
|
+
) ?
|
120
|
+
basename(resolve(target, "../.."))
|
121
|
+
: void 0
|
122
|
+
let outputPath =
|
123
|
+
commands[2] ||
|
124
|
+
resolve(
|
125
|
+
dirname(target),
|
126
|
+
fileBaseNameEndsWithDotSrc ? scriptName + ".js"
|
127
|
+
: ".js" == fileExtension ? fileBaseName + ".min.js"
|
128
|
+
: fileBaseName + ".js"
|
129
|
+
)
|
130
|
+
const golfFile = () =>
|
131
|
+
readFile(target, { encoding: "utf8" }).then(async source => {
|
132
|
+
const timeStart = performance.now(),
|
133
|
+
{ script, warnings } = await processScript(source, {
|
134
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
135
|
+
scriptUser,
|
136
|
+
scriptName,
|
137
|
+
filePath: target,
|
138
|
+
mangleNames: mangleNamesOption?.value,
|
139
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
140
|
+
}),
|
141
|
+
timeTook = performance.now() - timeStart
|
142
|
+
for (const { message, line } of warnings)
|
143
|
+
log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
|
144
|
+
await writeFilePersistent(outputPath, script)
|
145
|
+
.catch(error => {
|
146
|
+
if (!commands[2] || "EISDIR" != error.code) throw error
|
147
|
+
outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
|
148
|
+
return writeFilePersistent(outputPath, script)
|
149
|
+
})
|
150
|
+
.then(() =>
|
151
|
+
log(
|
152
|
+
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
153
|
+
)
|
154
|
+
)
|
155
|
+
})
|
156
|
+
if (watchOption) {
|
157
|
+
const { watch: watchFile } = await chokidarModule
|
158
|
+
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
159
|
+
.on("ready", () => log("Watching " + target))
|
160
|
+
.on("change", golfFile)
|
161
|
+
autoExit = !1
|
162
|
+
} else await golfFile()
|
163
|
+
} else {
|
164
|
+
const hackmudPath = getHackmudPath(),
|
165
|
+
sourcePath = commands[1]
|
166
|
+
if (!sourcePath) {
|
167
|
+
logError(`Must provide the directory to ${"push" == commands[0] ? "push from" : "watch"}\n`)
|
151
168
|
logHelp()
|
152
|
-
|
169
|
+
process.exit(1)
|
153
170
|
}
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
159
|
-
)
|
160
|
-
logHelp()
|
161
|
-
break
|
162
|
-
}
|
163
|
-
const shouldSkipMinify = options.get("no-minify") || options.get("skip-minify")
|
164
|
-
let shouldMinify
|
165
|
-
if (null != shouldSkipMinify) {
|
166
|
-
if ("boolean" != typeof shouldSkipMinify) {
|
167
|
-
logError(
|
168
|
-
`The value for ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
|
171
|
+
const scripts = commands.slice(2)
|
172
|
+
if (scripts.length) {
|
173
|
+
const invalidScript = scripts.find(
|
174
|
+
script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script)
|
169
175
|
)
|
170
|
-
|
171
|
-
|
176
|
+
if (invalidScript) {
|
177
|
+
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`)
|
178
|
+
logHelp()
|
179
|
+
process.exit(1)
|
180
|
+
}
|
181
|
+
} else scripts.push("*.*")
|
182
|
+
if ("push" == commands[0]) {
|
183
|
+
const { push, MissingSourceFolderError, MissingHackmudFolderError, NoUsersError } = await pushModule
|
184
|
+
complainAboutUnrecognisedOptions()
|
185
|
+
const infos = await push(sourcePath, hackmudPath, {
|
186
|
+
scripts,
|
187
|
+
onPush: info => logInfo(info, hackmudPath),
|
188
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
189
|
+
mangleNames: mangleNamesOption?.value,
|
190
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
191
|
+
})
|
192
|
+
if (infos instanceof Error) {
|
193
|
+
logError(infos.message)
|
194
|
+
if (infos instanceof MissingSourceFolderError || infos instanceof NoUsersError) {
|
195
|
+
console.log()
|
196
|
+
logHelp()
|
197
|
+
} else
|
198
|
+
infos instanceof MissingHackmudFolderError &&
|
199
|
+
log(
|
200
|
+
`If this is not where your hackmud folder is, you can specify it with the\n${colourN("--hackmud-path")}=${colourB("<path>")} option or ${colourN("HSM_HACKMUD_PATH")} environment variable`
|
201
|
+
)
|
202
|
+
} else infos.length || logError("Could not find any scripts to push")
|
203
|
+
} else {
|
204
|
+
const typeDeclarationPathOption = popOption(
|
205
|
+
"type-declaration-path",
|
206
|
+
"type-declaration",
|
207
|
+
"dts",
|
208
|
+
"gen-types"
|
209
|
+
)
|
210
|
+
complainAboutUnrecognisedOptions()
|
211
|
+
const { watch } = await watchModule
|
212
|
+
watch(sourcePath, hackmudPath, {
|
213
|
+
scripts,
|
214
|
+
onPush: info => logInfo(info, hackmudPath),
|
215
|
+
typeDeclarationPath: typeDeclarationPathOption?.value.toString(),
|
216
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
217
|
+
mangleNames: mangleNamesOption?.value,
|
218
|
+
onReady: () => log("Watching"),
|
219
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
220
|
+
})
|
221
|
+
autoExit = !1
|
172
222
|
}
|
173
|
-
shouldMinify = !shouldSkipMinify
|
174
223
|
}
|
175
|
-
const shouldMangleNames = options.get("mangle-names")
|
176
|
-
if (null != shouldMangleNames && "boolean" != typeof shouldMangleNames) {
|
177
|
-
logError(
|
178
|
-
`The value for ${colourN("--mangle-names")} must be ${colourV("true")} or ${colourV("false")}\n`
|
179
|
-
)
|
180
|
-
logHelp()
|
181
|
-
break
|
182
|
-
}
|
183
|
-
const shouldforceQuineCheats = options.get("force-quine-cheats")
|
184
|
-
if (null != shouldforceQuineCheats && "boolean" != typeof shouldforceQuineCheats) {
|
185
|
-
logError(
|
186
|
-
`The value for ${colourN("--force-quine-cheats")} must be ${colourV("true")} or ${colourV("false")}\n`
|
187
|
-
)
|
188
|
-
logHelp()
|
189
|
-
break
|
190
|
-
}
|
191
|
-
const { watch } = await watchModule
|
192
|
-
watch(sourcePath, hackmudPath, {
|
193
|
-
scripts,
|
194
|
-
onPush: info => logInfo(info, hackmudPath),
|
195
|
-
typeDeclarationPath: (
|
196
|
-
options.get("type-declaration-path") ||
|
197
|
-
options.get("type-declaration") ||
|
198
|
-
options.get("dts") ||
|
199
|
-
options.get("gen-types")
|
200
|
-
)?.toString(),
|
201
|
-
minify: shouldMinify,
|
202
|
-
mangleNames: shouldMangleNames,
|
203
|
-
onReady: () => log("Watching"),
|
204
|
-
forceQuineCheats: shouldforceQuineCheats
|
205
|
-
})
|
206
|
-
autoExit = !1
|
207
224
|
}
|
208
225
|
break
|
209
226
|
case "pull":
|
@@ -213,8 +230,9 @@ switch (commands[0]) {
|
|
213
230
|
if (!script) {
|
214
231
|
logError("Must provide the script to pull\n")
|
215
232
|
logHelp()
|
216
|
-
|
233
|
+
process.exit(1)
|
217
234
|
}
|
235
|
+
complainAboutUnrecognisedOptions()
|
218
236
|
const sourcePath = commands[2] || "."
|
219
237
|
await pull(sourcePath, hackmudPath, script).catch(error => {
|
220
238
|
console.error(error)
|
@@ -224,8 +242,9 @@ switch (commands[0]) {
|
|
224
242
|
break
|
225
243
|
case "sync-macros":
|
226
244
|
{
|
227
|
-
const hackmudPath = getHackmudPath()
|
228
|
-
|
245
|
+
const hackmudPath = getHackmudPath()
|
246
|
+
complainAboutUnrecognisedOptions()
|
247
|
+
const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
|
229
248
|
log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
|
230
249
|
}
|
231
250
|
break
|
@@ -234,18 +253,20 @@ switch (commands[0]) {
|
|
234
253
|
case "gen-dts":
|
235
254
|
case "gen-types":
|
236
255
|
{
|
237
|
-
const
|
256
|
+
const hackmudPath = getHackmudPath(),
|
257
|
+
target = commands[1]
|
238
258
|
if (!target) {
|
239
259
|
logError("Must provide target directory\n")
|
240
260
|
logHelp()
|
241
|
-
|
261
|
+
process.exit(1)
|
242
262
|
}
|
263
|
+
complainAboutUnrecognisedOptions()
|
243
264
|
const sourcePath = resolve(target),
|
244
265
|
outputPath = commands[2] || "./player.d.ts",
|
245
|
-
typeDeclaration = await generateTypeDeclaration(sourcePath,
|
266
|
+
typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
|
246
267
|
let typeDeclarationPath = resolve(outputPath)
|
247
268
|
await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
|
248
|
-
assert(error instanceof Error, "src/bin/hsm.ts:
|
269
|
+
assert(error instanceof Error, "src/bin/hsm.ts:343:35")
|
249
270
|
if ("EISDIR" != error.code) throw error
|
250
271
|
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
251
272
|
return writeFile(typeDeclarationPath, typeDeclaration)
|
@@ -257,99 +278,6 @@ switch (commands[0]) {
|
|
257
278
|
case "h":
|
258
279
|
logHelp()
|
259
280
|
break
|
260
|
-
case "golf":
|
261
|
-
case "minify":
|
262
|
-
{
|
263
|
-
const target = commands[1]
|
264
|
-
if (!target) {
|
265
|
-
logError("Must provide target\n")
|
266
|
-
logHelp()
|
267
|
-
break
|
268
|
-
}
|
269
|
-
const fileExtension = extname(target)
|
270
|
-
if (!supportedExtensions.includes(fileExtension)) {
|
271
|
-
logError(
|
272
|
-
`Unsupported file extension "${chalk.bold(fileExtension)}"\nSupported extensions are "${supportedExtensions.map(extension => chalk.bold(extension)).join('", "')}"`
|
273
|
-
)
|
274
|
-
break
|
275
|
-
}
|
276
|
-
const { processScript } = await processScriptModule,
|
277
|
-
fileBaseName = basename(target, fileExtension),
|
278
|
-
fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
|
279
|
-
scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName,
|
280
|
-
scriptUser =
|
281
|
-
"scripts" == basename(resolve(target, "..")) && "hackmud" == basename(resolve(target, "../../..")) ?
|
282
|
-
basename(resolve(target, "../.."))
|
283
|
-
: void 0,
|
284
|
-
optionsHasNoMinify = options.has("no-minify")
|
285
|
-
if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
|
286
|
-
logError(
|
287
|
-
`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
|
288
|
-
)
|
289
|
-
logHelp()
|
290
|
-
break
|
291
|
-
}
|
292
|
-
const mangleNames_ = options.get("mangle-names")
|
293
|
-
if (null != mangleNames_ && "boolean" != typeof mangleNames_) {
|
294
|
-
logError(
|
295
|
-
`The value for ${colourN("--mangle-names")} must be ${colourV("true")} or ${colourV("false")}\n`
|
296
|
-
)
|
297
|
-
logHelp()
|
298
|
-
break
|
299
|
-
}
|
300
|
-
const mangleNames = mangleNames_,
|
301
|
-
forceQuineCheats_ = options.get("force-quine-cheats")
|
302
|
-
if (null != forceQuineCheats_ && "boolean" != typeof forceQuineCheats_) {
|
303
|
-
logError(
|
304
|
-
`the value for ${colourN("--force-quine-cheats")} must be ${colourV("true")} or ${colourV("false")}\n`
|
305
|
-
)
|
306
|
-
logHelp()
|
307
|
-
break
|
308
|
-
}
|
309
|
-
const forceQuineCheats = forceQuineCheats_
|
310
|
-
let outputPath =
|
311
|
-
commands[2] ||
|
312
|
-
resolve(
|
313
|
-
dirname(target),
|
314
|
-
fileBaseNameEndsWithDotSrc ? scriptName + ".js"
|
315
|
-
: ".js" == fileExtension ? fileBaseName + ".min.js"
|
316
|
-
: fileBaseName + ".js"
|
317
|
-
)
|
318
|
-
const golfFile = () =>
|
319
|
-
readFile(target, { encoding: "utf8" }).then(async source => {
|
320
|
-
const timeStart = performance.now(),
|
321
|
-
{ script, warnings } = await processScript(source, {
|
322
|
-
minify: !(options.get("no-minify") || options.get("skip-minify")),
|
323
|
-
scriptUser,
|
324
|
-
scriptName,
|
325
|
-
filePath: target,
|
326
|
-
mangleNames,
|
327
|
-
forceQuineCheats
|
328
|
-
}),
|
329
|
-
timeTook = performance.now() - timeStart
|
330
|
-
for (const { message, line } of warnings)
|
331
|
-
log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
|
332
|
-
await writeFilePersistent(outputPath, script)
|
333
|
-
.catch(error => {
|
334
|
-
if (!commands[2] || "EISDIR" != error.code) throw error
|
335
|
-
outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
|
336
|
-
return writeFilePersistent(outputPath, script)
|
337
|
-
})
|
338
|
-
.then(() =>
|
339
|
-
log(
|
340
|
-
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
341
|
-
)
|
342
|
-
)
|
343
|
-
})
|
344
|
-
if (options.get("watch")) {
|
345
|
-
const { watch: watchFile } = await chokidarModule
|
346
|
-
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
347
|
-
.on("ready", () => log("Watching " + target))
|
348
|
-
.on("change", golfFile)
|
349
|
-
autoExit = !1
|
350
|
-
} else await golfFile()
|
351
|
-
}
|
352
|
-
break
|
353
281
|
default:
|
354
282
|
commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
|
355
283
|
logHelp()
|
@@ -366,7 +294,7 @@ function logHelp() {
|
|
366
294
|
case "push":
|
367
295
|
console.log(
|
368
296
|
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
|
297
|
+
`\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 Pushes 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 Pushes 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 Pushes 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 Pushes all scripts found in ${colourV("src")} folder to all users`
|
370
298
|
)
|
371
299
|
)
|
372
300
|
break
|
@@ -423,7 +351,7 @@ function logError(message) {
|
|
423
351
|
process.exitCode = 1
|
424
352
|
}
|
425
353
|
function getHackmudPath() {
|
426
|
-
const hackmudPathOption =
|
354
|
+
const hackmudPathOption = popOption("hackmud-path")
|
427
355
|
if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
|
428
356
|
logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
|
429
357
|
logHelp()
|
@@ -435,3 +363,32 @@ function getHackmudPath() {
|
|
435
363
|
("win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud"))
|
436
364
|
)
|
437
365
|
}
|
366
|
+
function assertOptionIsBoolean(option) {
|
367
|
+
if ("boolean" != typeof option.value) {
|
368
|
+
logError(`The value for ${formatOption(option.name)} must be ${colourV("true")} or ${colourV("false")}\n`)
|
369
|
+
logHelp()
|
370
|
+
process.exit(1)
|
371
|
+
}
|
372
|
+
}
|
373
|
+
function popOption(...names) {
|
374
|
+
const presentOptionNames = names.filter(name => options.has(name))
|
375
|
+
if (!presentOptionNames.length) return
|
376
|
+
const presentOptionNamesWithDashDash = presentOptionNames.map(formatOption)
|
377
|
+
if (presentOptionNames.length > 1) {
|
378
|
+
logError(
|
379
|
+
`The options ${presentOptionNamesWithDashDash.join(", ")} are aliases for each other. Please only specify one`
|
380
|
+
)
|
381
|
+
process.exit(1)
|
382
|
+
}
|
383
|
+
const value = options.get(presentOptionNames[0])
|
384
|
+
options.delete(presentOptionNames[0])
|
385
|
+
return { name: presentOptionNamesWithDashDash[0], value }
|
386
|
+
}
|
387
|
+
function complainAboutUnrecognisedOptions() {
|
388
|
+
if (options.size) {
|
389
|
+
logError(
|
390
|
+
`Unrecognised option${options.size > 1 ? "s" : ""}: ${[...options.keys()].map(formatOption).join(", ")}`
|
391
|
+
)
|
392
|
+
process.exit(1)
|
393
|
+
}
|
394
|
+
}
|