hackmud-script-manager 0.20.4-d9a4cf1 → 0.20.4-ec30de9
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 +170 -233
- package/env.d.ts +93 -27
- package/package.json +1 -1
- package/processScript/index.js +1 -1
- package/processScript/minify.js +14 -19
- package/processScript/postprocess.d.ts +1 -1
- package/processScript/postprocess.js +3 -3
- package/processScript/transform.js +50 -39
- package/push.d.ts +9 -1
- package/push.js +33 -11
package/bin/hsm.js
CHANGED
@@ -5,14 +5,14 @@ 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
14
|
import "@samual/lib/copyFilePersistent"
|
15
|
-
const version = "0.20.4-
|
15
|
+
const version = "0.20.4-ec30de9",
|
16
16
|
options = new Map(),
|
17
17
|
commands = [],
|
18
18
|
userColours = new Cache(user => {
|
@@ -36,10 +36,6 @@ for (const argument of process.argv.slice(2))
|
|
36
36
|
if ("-" == argument[1]) options.set(key.slice(2), value)
|
37
37
|
else for (const option of key.slice(1)) options.set(option, value)
|
38
38
|
} 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
39
|
const pushModule = import("../push.js"),
|
44
40
|
processScriptModule = import("../processScript/index.js"),
|
45
41
|
watchModule = import("../watch.js"),
|
@@ -57,153 +53,163 @@ const pushModule = import("../push.js"),
|
|
57
53
|
colourS = chalk.rgb(122, 178, 244),
|
58
54
|
colourV = chalk.rgb(255, 0, 236),
|
59
55
|
colourW = chalk.rgb(255, 150, 224)
|
60
|
-
if (
|
56
|
+
if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
|
57
|
+
console.log(version)
|
58
|
+
process.exit()
|
59
|
+
}
|
60
|
+
if (popOption("help", "h")?.value) {
|
61
61
|
logHelp()
|
62
62
|
process.exit()
|
63
63
|
}
|
64
64
|
let autoExit = !0
|
65
65
|
switch (commands[0]) {
|
66
66
|
case "push":
|
67
|
+
case "dev":
|
68
|
+
case "watch":
|
69
|
+
case "golf":
|
70
|
+
case "minify":
|
67
71
|
{
|
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")) {
|
72
|
+
const noMinifyOption = popOption("no-minify", "skip-minify"),
|
73
|
+
mangleNamesOption = popOption("mangle-names"),
|
74
|
+
forceQuineCheatsOption = popOption("force-quine-cheats"),
|
75
|
+
noMinifyIncompatibleOption = mangleNamesOption || forceQuineCheatsOption
|
76
|
+
if (noMinifyOption && noMinifyIncompatibleOption) {
|
88
77
|
logError(
|
89
|
-
`Options ${colourN(
|
78
|
+
`Options ${colourN(noMinifyOption.name)} and ${colourN(noMinifyIncompatibleOption.name)} are incompatible\n`
|
90
79
|
)
|
91
80
|
logHelp()
|
92
|
-
|
81
|
+
process.exit(1)
|
93
82
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
83
|
+
noMinifyOption && assertOptionIsBoolean(noMinifyOption)
|
84
|
+
mangleNamesOption && assertOptionIsBoolean(mangleNamesOption)
|
85
|
+
forceQuineCheatsOption && assertOptionIsBoolean(forceQuineCheatsOption)
|
86
|
+
if ("golf" == commands[0] || "minify" == commands[0]) {
|
87
|
+
const watchOption = popOption("watch"),
|
88
|
+
target = commands[1]
|
89
|
+
if (!target) {
|
90
|
+
logError("Must provide target\n")
|
91
|
+
logHelp()
|
92
|
+
process.exit(1)
|
93
|
+
}
|
94
|
+
const fileExtension = extname(target)
|
95
|
+
if (!supportedExtensions.includes(fileExtension)) {
|
98
96
|
logError(
|
99
|
-
`
|
97
|
+
`Unsupported file extension "${chalk.bold(fileExtension)}"\nSupported extensions are "${supportedExtensions.map(extension => chalk.bold(extension)).join('", "')}"`
|
100
98
|
)
|
101
|
-
|
102
|
-
break
|
99
|
+
process.exit(1)
|
103
100
|
}
|
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
|
-
if (
|
150
|
-
|
101
|
+
const { processScript } = await processScriptModule,
|
102
|
+
fileBaseName = basename(target, fileExtension),
|
103
|
+
fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
|
104
|
+
scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName,
|
105
|
+
scriptUser =
|
106
|
+
(
|
107
|
+
"scripts" == basename(resolve(target, "..")) &&
|
108
|
+
"hackmud" == basename(resolve(target, "../../.."))
|
109
|
+
) ?
|
110
|
+
basename(resolve(target, "../.."))
|
111
|
+
: void 0
|
112
|
+
let outputPath =
|
113
|
+
commands[2] ||
|
114
|
+
resolve(
|
115
|
+
dirname(target),
|
116
|
+
fileBaseNameEndsWithDotSrc ? scriptName + ".js"
|
117
|
+
: ".js" == fileExtension ? fileBaseName + ".min.js"
|
118
|
+
: fileBaseName + ".js"
|
119
|
+
)
|
120
|
+
const golfFile = () =>
|
121
|
+
readFile(target, { encoding: "utf8" }).then(async source => {
|
122
|
+
const timeStart = performance.now(),
|
123
|
+
{ script, warnings } = await processScript(source, {
|
124
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
125
|
+
scriptUser,
|
126
|
+
scriptName,
|
127
|
+
filePath: target,
|
128
|
+
mangleNames: mangleNamesOption?.value,
|
129
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
130
|
+
}),
|
131
|
+
timeTook = performance.now() - timeStart
|
132
|
+
for (const { message, line } of warnings)
|
133
|
+
log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
|
134
|
+
await writeFilePersistent(outputPath, script)
|
135
|
+
.catch(error => {
|
136
|
+
if (!commands[2] || "EISDIR" != error.code) throw error
|
137
|
+
outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
|
138
|
+
return writeFilePersistent(outputPath, script)
|
139
|
+
})
|
140
|
+
.then(() =>
|
141
|
+
log(
|
142
|
+
`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
|
143
|
+
)
|
144
|
+
)
|
145
|
+
})
|
146
|
+
if (watchOption) {
|
147
|
+
const { watch: watchFile } = await chokidarModule
|
148
|
+
watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
|
149
|
+
.on("ready", () => log("Watching " + target))
|
150
|
+
.on("change", golfFile)
|
151
|
+
autoExit = !1
|
152
|
+
} else await golfFile()
|
153
|
+
} else {
|
154
|
+
const hackmudPath = getHackmudPath(),
|
155
|
+
sourcePath = commands[1]
|
156
|
+
if (!sourcePath) {
|
157
|
+
logError(`Must provide the directory to ${"push" == commands[0] ? "push from" : "watch"}\n`)
|
151
158
|
logHelp()
|
152
|
-
|
159
|
+
process.exit(1)
|
153
160
|
}
|
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`
|
161
|
+
const scripts = commands.slice(2)
|
162
|
+
if (scripts.length) {
|
163
|
+
const invalidScript = scripts.find(
|
164
|
+
script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script)
|
169
165
|
)
|
170
|
-
|
171
|
-
|
166
|
+
if (invalidScript) {
|
167
|
+
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`)
|
168
|
+
logHelp()
|
169
|
+
process.exit(1)
|
170
|
+
}
|
171
|
+
} else scripts.push("*.*")
|
172
|
+
if ("push" == commands[0]) {
|
173
|
+
const { push, MissingSourceFolderError, MissingHackmudFolderError, NoUsersError } =
|
174
|
+
await pushModule,
|
175
|
+
infos = await push(sourcePath, hackmudPath, {
|
176
|
+
scripts,
|
177
|
+
onPush: info => logInfo(info, hackmudPath),
|
178
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
179
|
+
mangleNames: mangleNamesOption?.value,
|
180
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
181
|
+
})
|
182
|
+
if (infos instanceof Error) {
|
183
|
+
logError(infos.message)
|
184
|
+
if (infos instanceof MissingSourceFolderError || infos instanceof NoUsersError) {
|
185
|
+
console.log()
|
186
|
+
logHelp()
|
187
|
+
} else
|
188
|
+
infos instanceof MissingHackmudFolderError &&
|
189
|
+
log(
|
190
|
+
`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`
|
191
|
+
)
|
192
|
+
} else infos.length || logError("Could not find any scripts to push")
|
193
|
+
} else {
|
194
|
+
const typeDeclarationPathOption = popOption(
|
195
|
+
"type-declaration-path",
|
196
|
+
"type-declaration",
|
197
|
+
"dts",
|
198
|
+
"gen-types"
|
199
|
+
),
|
200
|
+
{ watch } = await watchModule
|
201
|
+
watch(sourcePath, hackmudPath, {
|
202
|
+
scripts,
|
203
|
+
onPush: info => logInfo(info, hackmudPath),
|
204
|
+
typeDeclarationPath: typeDeclarationPathOption?.value.toString(),
|
205
|
+
minify: noMinifyOption && !noMinifyOption.value,
|
206
|
+
mangleNames: mangleNamesOption?.value,
|
207
|
+
onReady: () => log("Watching"),
|
208
|
+
forceQuineCheats: forceQuineCheatsOption?.value
|
209
|
+
})
|
210
|
+
autoExit = !1
|
172
211
|
}
|
173
|
-
shouldMinify = !shouldSkipMinify
|
174
212
|
}
|
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
213
|
}
|
208
214
|
break
|
209
215
|
case "pull":
|
@@ -213,7 +219,7 @@ switch (commands[0]) {
|
|
213
219
|
if (!script) {
|
214
220
|
logError("Must provide the script to pull\n")
|
215
221
|
logHelp()
|
216
|
-
|
222
|
+
process.exit(1)
|
217
223
|
}
|
218
224
|
const sourcePath = commands[2] || "."
|
219
225
|
await pull(sourcePath, hackmudPath, script).catch(error => {
|
@@ -234,18 +240,19 @@ switch (commands[0]) {
|
|
234
240
|
case "gen-dts":
|
235
241
|
case "gen-types":
|
236
242
|
{
|
237
|
-
const
|
243
|
+
const hackmudPath = getHackmudPath(),
|
244
|
+
target = commands[1]
|
238
245
|
if (!target) {
|
239
246
|
logError("Must provide target directory\n")
|
240
247
|
logHelp()
|
241
|
-
|
248
|
+
process.exit(1)
|
242
249
|
}
|
243
250
|
const sourcePath = resolve(target),
|
244
251
|
outputPath = commands[2] || "./player.d.ts",
|
245
|
-
typeDeclaration = await generateTypeDeclaration(sourcePath,
|
252
|
+
typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
|
246
253
|
let typeDeclarationPath = resolve(outputPath)
|
247
254
|
await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
|
248
|
-
assert(error instanceof Error, "src/bin/hsm.ts:
|
255
|
+
assert(error instanceof Error, "src/bin/hsm.ts:321:35")
|
249
256
|
if ("EISDIR" != error.code) throw error
|
250
257
|
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
251
258
|
return writeFile(typeDeclarationPath, typeDeclaration)
|
@@ -257,99 +264,6 @@ switch (commands[0]) {
|
|
257
264
|
case "h":
|
258
265
|
logHelp()
|
259
266
|
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
267
|
default:
|
354
268
|
commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
|
355
269
|
logHelp()
|
@@ -423,7 +337,7 @@ function logError(message) {
|
|
423
337
|
process.exitCode = 1
|
424
338
|
}
|
425
339
|
function getHackmudPath() {
|
426
|
-
const hackmudPathOption =
|
340
|
+
const hackmudPathOption = popOption("hackmud-path")
|
427
341
|
if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
|
428
342
|
logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
|
429
343
|
logHelp()
|
@@ -435,3 +349,26 @@ function getHackmudPath() {
|
|
435
349
|
("win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud"))
|
436
350
|
)
|
437
351
|
}
|
352
|
+
function assertOptionIsBoolean(option) {
|
353
|
+
if ("boolean" != typeof option.value) {
|
354
|
+
logError(`The value for ${colourN(option.name)} must be ${colourV("true")} or ${colourV("false")}\n`)
|
355
|
+
logHelp()
|
356
|
+
process.exit(1)
|
357
|
+
}
|
358
|
+
}
|
359
|
+
function popOption(...names) {
|
360
|
+
const presentOptionNames = names.filter(name => options.has(name))
|
361
|
+
if (!presentOptionNames.length) return
|
362
|
+
const presentOptionNamesWithDashDash = presentOptionNames.map(name =>
|
363
|
+
colourN(`-${1 == name.length ? "" : "-"}${name}`)
|
364
|
+
)
|
365
|
+
if (presentOptionNames.length > 1) {
|
366
|
+
logError(
|
367
|
+
`The options ${presentOptionNamesWithDashDash.join(", ")} are aliases for each other. Please only specify one`
|
368
|
+
)
|
369
|
+
process.exit(1)
|
370
|
+
}
|
371
|
+
const value = options.get(presentOptionNames[0])
|
372
|
+
options.delete(presentOptionNames[0])
|
373
|
+
return { name: presentOptionNamesWithDashDash[0], value }
|
374
|
+
}
|
package/env.d.ts
CHANGED
@@ -1,18 +1,14 @@
|
|
1
|
-
type Replace<
|
1
|
+
type Replace<A, B> = Omit<A, keyof B> & B
|
2
2
|
type ScriptSuccess<T = object> = { ok: true } & T
|
3
3
|
type ScriptFailure = { ok: false, msg?: string }
|
4
4
|
type ScriptResponse<T = object> = ScriptSuccess<T> | ScriptFailure
|
5
5
|
type ErrorScripts = Record<string, () => ScriptFailure>
|
6
6
|
|
7
|
-
type AllOptional<T> = {
|
8
|
-
[K in keyof T]-?: {} extends Pick<T, K> ? true : false
|
9
|
-
}[keyof T]
|
7
|
+
type AllOptional<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? true : false }[keyof T]
|
10
8
|
|
11
9
|
type Scriptor<Args = unknown, Ret = unknown> = {
|
12
|
-
name: string
|
13
|
-
call: AllOptional<Args> extends true
|
14
|
-
? (args?: Args) => Ret
|
15
|
-
: (args: Args) => Ret
|
10
|
+
name: string
|
11
|
+
call: AllOptional<Args> extends true ? (args?: Args) => Ret : (args: Args) => Ret
|
16
12
|
}
|
17
13
|
|
18
14
|
type Subscripts = Record<string, Record<string, (...args: any) => any>> & {
|
@@ -41,7 +37,7 @@ type UpgradeRarityString = "`0noob`" | "`1kiddie`" | "`2h4x0r`" | "`3h4rdc0r3`"
|
|
41
37
|
type UpgradeRarityNumber = 0 | 1 | 2 | 3 | 4 | 5;
|
42
38
|
type UpgradeRarity = UpgradeRarityString | UpgradeRarityNumber;
|
43
39
|
|
44
|
-
type
|
40
|
+
type UpgradeBase = {
|
45
41
|
name: string
|
46
42
|
type: "lock" | "script_space" | "chat" | "script" | "tool" | "bot_brain" | "glam"
|
47
43
|
up_class?: -1 | 0 | 1 | 2 | 3
|
@@ -53,9 +49,9 @@ type UpgradeCore = {
|
|
53
49
|
description: string
|
54
50
|
}
|
55
51
|
|
56
|
-
type Upgrade =
|
52
|
+
type Upgrade = UpgradeBase & Record<string, null | boolean | number | string>
|
57
53
|
|
58
|
-
type
|
54
|
+
type CliUpgrade = Omit<UpgradeBase, `rarity`> & {
|
59
55
|
[x: string]: null | boolean | number | string
|
60
56
|
rarity: UpgradeRarityString
|
61
57
|
}
|
@@ -155,7 +151,16 @@ type Fullsec = Subscripts & PlayerFullsec & {
|
|
155
151
|
market: {
|
156
152
|
/** **FULLSEC** */ browse: {
|
157
153
|
(args:
|
158
|
-
Partial<{
|
154
|
+
Partial<{
|
155
|
+
seller: string | MongoQuerySelector<string>,
|
156
|
+
listed_before: number | MongoQuerySelector<number>,
|
157
|
+
listed_after: number,
|
158
|
+
cost: number | MongoQuerySelector<number> | string,
|
159
|
+
rarity: UpgradeRarityNumber | MongoQuerySelector<UpgradeRarityNumber>,
|
160
|
+
name: string | MongoQuerySelector<string>
|
161
|
+
} & Omit<{
|
162
|
+
[k in keyof CliUpgrade]: CliUpgrade[k] | MongoQuerySelector<CliUpgrade[k]>
|
163
|
+
}, "rarity">>
|
159
164
|
): { i: string, name: string, rarity: Upgrade["rarity"], cost: number }[] | ScriptFailure
|
160
165
|
|
161
166
|
<I extends string>(args: { i: I }): {
|
@@ -357,7 +362,7 @@ type Fullsec = Subscripts & PlayerFullsec & {
|
|
357
362
|
* const arr = [ 1, 2, 2, 3, 2 ]
|
358
363
|
*
|
359
364
|
* $D(uniq(arr)) // [ 1, 2, 3, 2 ] */
|
360
|
-
uniq: (array: T[]) => T[]
|
365
|
+
uniq: <T>(array: T[]) => T[]
|
361
366
|
|
362
367
|
/** Sorts an array of numbers or number-coercible strings in descending order. */
|
363
368
|
u_sort_num_arr_desc: <T>(array: T[]) => T[]
|
@@ -424,17 +429,17 @@ type Fullsec = Subscripts & PlayerFullsec & {
|
|
424
429
|
upgrades_of_owner: {
|
425
430
|
<F extends Partial<Upgrade & { loaded: boolean }> = object>(args?: { filter?: F, full?: false }): (
|
426
431
|
Omit<
|
427
|
-
Pick<
|
432
|
+
Pick<UpgradeBase, "tier" | "rarity" | "name" | "type" | "i" | "loaded">,
|
428
433
|
keyof F
|
429
434
|
> & Pick<F, "tier" | "rarity" | "name" | "type" | "i" | "loaded">
|
430
435
|
)[] | ScriptFailure
|
431
436
|
|
432
437
|
<F extends Partial<Upgrade & { loaded: boolean }> = object>(args: { filter?: F, full: true }): (
|
433
|
-
Omit<
|
438
|
+
Omit<UpgradeBase, keyof F> & F & Record<string, null | boolean | number | string>
|
434
439
|
)[] | ScriptFailure
|
435
440
|
|
436
441
|
<I extends number>(args: { i: I }): (
|
437
|
-
Omit<
|
442
|
+
Omit<UpgradeBase, "i"> & { [x: string]: null | boolean | number | string, i: I }
|
438
443
|
) | ScriptFailure
|
439
444
|
}
|
440
445
|
|
@@ -511,7 +516,7 @@ type Highsec = Fullsec & PlayerHighsec & {
|
|
511
516
|
/** **HIGHSEC** */
|
512
517
|
upgrades: {
|
513
518
|
<I extends number>(args: { i: I }): (
|
514
|
-
Omit<
|
519
|
+
Omit<UpgradeBase, "i"> & { [x: string]: null | boolean | number | string, i: I }
|
515
520
|
) | ScriptFailure
|
516
521
|
|
517
522
|
<F extends Partial<Upgrade & { loaded: boolean }> = object>(args?: {
|
@@ -519,20 +524,20 @@ type Highsec = Fullsec & PlayerHighsec & {
|
|
519
524
|
is_script?: true
|
520
525
|
full?: false
|
521
526
|
}): (
|
522
|
-
Omit<Pick<
|
527
|
+
Omit<Pick<UpgradeBase, "tier" | "rarity" | "name" | "type" | "i" | "loaded">, keyof F> & F &
|
523
528
|
Record<string, null | boolean | number | string>
|
524
529
|
)[] | ScriptFailure
|
525
530
|
|
526
531
|
<F extends Partial<Upgrade & { loaded: boolean }> = object>(args?:
|
527
532
|
{ filter?: F, is_script?: true, full: true }
|
528
|
-
): (Omit<
|
533
|
+
): (Omit<UpgradeBase, keyof F> & F & Record<string, null | boolean | number | string>)[] | ScriptFailure
|
529
534
|
|
530
535
|
(args?: { filter?: Partial<Upgrade & { loaded: boolean }>, is_script: false, full?: false }):
|
531
536
|
{ msg: string, upgrades: string[] } | ScriptFailure
|
532
537
|
|
533
538
|
<F extends Partial<Upgrade & { loaded: boolean }> = object>(
|
534
539
|
args?: { filter?: F, is_script: false, full: true }
|
535
|
-
): (Omit<
|
540
|
+
): (Omit<UpgradeBase, keyof F | `rarity`> & F & {
|
536
541
|
[x: string]: null | boolean | number | string
|
537
542
|
rarity: UpgradeRarityString
|
538
543
|
})[] | ScriptFailure
|
@@ -714,10 +719,50 @@ type Nullsec = Lowsec & PlayerNullsec & {
|
|
714
719
|
}
|
715
720
|
}
|
716
721
|
|
722
|
+
type MongoTypeString = "minKey" | "double" | "string" | "object" | "array" | "binData" | "undefined" | "objectId" |
|
723
|
+
"bool" | "date" | "null" | "regex" | "dbPointer" | "javascript" | "symbol" | "int" | "timestamp" | "long" | "decimal" | "maxKey";
|
724
|
+
type MongoTypeNumber = -1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 127;
|
725
|
+
|
717
726
|
type MongoValue = string | number | boolean | Date | MongoValue[] | { [key: string]: MongoValue } | null
|
718
727
|
|
719
728
|
type MongoCommandValue = string | number | boolean | Date | MongoCommandValue[] | { [key: string]: MongoCommandValue } |
|
720
|
-
|
729
|
+
null | undefined
|
730
|
+
|
731
|
+
/**
|
732
|
+
* Currently unused
|
733
|
+
*/
|
734
|
+
type MongoLogicalSelectors<T extends MongoValue = MongoValue> = {
|
735
|
+
$not: T | MongoComparisonSelectors<T> | MongoLogicalSelectors<T>
|
736
|
+
$nor: T[]
|
737
|
+
$or: T[]
|
738
|
+
$and: T[]
|
739
|
+
}
|
740
|
+
|
741
|
+
type MongoArraySelectors<T extends Array<MongoValue> = Array<MongoValue>> = {
|
742
|
+
$all: T
|
743
|
+
$elemMatch: T
|
744
|
+
$size: number
|
745
|
+
}
|
746
|
+
|
747
|
+
type MongoComparisonSelectors<T extends MongoValue = MongoValue> = {
|
748
|
+
$eq: T
|
749
|
+
$gt: T
|
750
|
+
$gte: T
|
751
|
+
$in: T[]
|
752
|
+
$lt: T
|
753
|
+
$lte: T
|
754
|
+
$ne: T
|
755
|
+
$nin: T[]
|
756
|
+
}
|
757
|
+
|
758
|
+
type MongoElementSelectors = {
|
759
|
+
$exists: boolean
|
760
|
+
$type: MongoTypeNumber | MongoTypeString
|
761
|
+
}
|
762
|
+
|
763
|
+
type MongoQuerySelector<T extends MongoValue = MongoValue> = Partial<T extends MongoValue[] ?
|
764
|
+
(MongoArraySelectors<T> & MongoElementSelectors & MongoComparisonSelectors<T>) :
|
765
|
+
(MongoElementSelectors & MongoComparisonSelectors<T>)>
|
721
766
|
|
722
767
|
type Query = { [key: string]: MongoValue | Query } & { _id?: Id, $in?: MongoValue[] }
|
723
768
|
type Projection = Record<string, boolean | 0 | 1>
|
@@ -766,7 +811,7 @@ type Cursor = {
|
|
766
811
|
ObjectId: () => any
|
767
812
|
}
|
768
813
|
|
769
|
-
type
|
814
|
+
type CliContext = {
|
770
815
|
/** The name of the user who is calling the script. */ caller: string
|
771
816
|
/** The name of this script. */ this_script: string
|
772
817
|
/** The number of columns in the caller’s terminal. */ cols: number
|
@@ -774,17 +819,23 @@ type CLIContext = {
|
|
774
819
|
|
775
820
|
/** The name of the script that directly called this script, or null if called on the command line or as a
|
776
821
|
* scriptor. */ calling_script: null
|
822
|
+
is_scriptor?: undefined
|
823
|
+
is_brain?: undefined
|
777
824
|
}
|
778
825
|
|
779
|
-
type SubscriptContext = Replace<
|
826
|
+
type SubscriptContext = Replace<CliContext, {
|
780
827
|
/** The name of the script that directly called this script, or null if called on the command line or as a scriptor.
|
781
828
|
*/
|
782
829
|
calling_script: string
|
783
830
|
}>
|
784
831
|
|
785
|
-
type ScriptorContext =
|
786
|
-
|
787
|
-
|
832
|
+
type ScriptorContext =
|
833
|
+
Replace<CliContext, { /** Whether the script is being run as a scriptor. */ is_scriptor: true }>
|
834
|
+
|
835
|
+
type BrainContext =
|
836
|
+
Replace<CliContext, { /** Whether the script is being run via a bot brain. */ is_brain: true }>
|
837
|
+
|
838
|
+
type Context = CliContext | SubscriptContext | ScriptorContext | BrainContext
|
788
839
|
|
789
840
|
/** Subscript space that can call FULLSEC scripts. */ declare const $fs: Fullsec
|
790
841
|
|
@@ -827,6 +878,8 @@ declare const $0s: typeof $ns
|
|
827
878
|
* } */
|
828
879
|
declare const $s: Nullsec
|
829
880
|
|
881
|
+
type ObjectId = { $oid: string }
|
882
|
+
|
830
883
|
declare const $db: {
|
831
884
|
/** Insert a document or documents into a collection.
|
832
885
|
* @param documents A document or array of documents to insert into the collection. */
|
@@ -920,6 +973,8 @@ declare const $db: {
|
|
920
973
|
signature: { hash: "Undefined Conversion", keyId: "Undefined Conversion" }
|
921
974
|
}
|
922
975
|
}
|
976
|
+
|
977
|
+
ObjectId: () => ObjectId
|
923
978
|
}
|
924
979
|
|
925
980
|
/** Debug Log.
|
@@ -956,7 +1011,7 @@ declare const $FMCL: undefined | true
|
|
956
1011
|
* @example
|
957
1012
|
* if (!$G.dbCache)
|
958
1013
|
* $G.dbCache = $db.f({ whatever: true }).first() */
|
959
|
-
declare const $G: any
|
1014
|
+
declare const $G: Record<string | symbol, any>
|
960
1015
|
|
961
1016
|
/** This contains a JS timestamp (not Date) set immediately before your code begins running.
|
962
1017
|
* @example
|
@@ -1005,3 +1060,14 @@ declare const _FULL_SCRIPT_NAME: string
|
|
1005
1060
|
*
|
1006
1061
|
* In rare cases where it's not known at build time, it's `-1`. */
|
1007
1062
|
declare const _SECLEVEL: -1 | 0 | 1 | 2 | 3 | 4
|
1063
|
+
|
1064
|
+
type DeepFreeze<T> = { readonly [P in keyof T]: DeepFreeze<T[P]> }
|
1065
|
+
|
1066
|
+
/** Recursively
|
1067
|
+
* [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
|
1068
|
+
* an object and its properties' objects and its properties' objects and so on.
|
1069
|
+
*
|
1070
|
+
* [Official Hackmud Wiki](https://wiki.hackmud.com/scripting/extensions/deep_freeze) */
|
1071
|
+
declare const DEEP_FREEZE: <T>(value: T) => DeepFreeze<T>
|
1072
|
+
|
1073
|
+
declare const _RUN_ID: string
|
package/package.json
CHANGED
package/processScript/index.js
CHANGED
@@ -323,7 +323,7 @@ async function processScript(
|
|
323
323
|
trailingComma: "none"
|
324
324
|
})
|
325
325
|
}
|
326
|
-
code = postprocess(code,
|
326
|
+
code = postprocess(code, uniqueId)
|
327
327
|
if (includesIllegalString(code))
|
328
328
|
throw Error(
|
329
329
|
'you found a weird edge case where I wasn\'t able to replace illegal strings like "SC$", please report thx'
|
package/processScript/minify.js
CHANGED
@@ -43,15 +43,6 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
43
43
|
)
|
44
44
|
}
|
45
45
|
}
|
46
|
-
const hashGReferencePaths = getReferencePathsToGlobal(`$${uniqueId}$GLOBAL$`, program)
|
47
|
-
if (hashGReferencePaths.length > 3) {
|
48
|
-
for (const path of hashGReferencePaths) path.replaceWith(t.identifier(`_${uniqueId}_G_`))
|
49
|
-
mainFunctionPath.node.body.body.unshift(
|
50
|
-
t.variableDeclaration("let", [
|
51
|
-
t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
|
52
|
-
])
|
53
|
-
)
|
54
|
-
}
|
55
46
|
const jsonValues = []
|
56
47
|
let scriptBeforeJSONValueReplacement,
|
57
48
|
comment,
|
@@ -61,7 +52,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
61
52
|
traverse(fileBeforeJSONValueReplacement, {
|
62
53
|
MemberExpression({ node: memberExpression }) {
|
63
54
|
if (!memberExpression.computed) {
|
64
|
-
assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:
|
55
|
+
assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:115:60")
|
65
56
|
if ("prototype" == memberExpression.property.name) {
|
66
57
|
memberExpression.computed = !0
|
67
58
|
memberExpression.property = t.identifier(`_${uniqueId}_PROTOTYPE_PROPERTY_`)
|
@@ -136,7 +127,8 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
136
127
|
const promises = []
|
137
128
|
traverse(file, {
|
138
129
|
FunctionDeclaration(path) {
|
139
|
-
path.
|
130
|
+
const body = path.get("body")
|
131
|
+
body.traverse({
|
140
132
|
Function(path) {
|
141
133
|
"CallExpression" != path.parent.type && "callee" != path.parentKey && path.skip()
|
142
134
|
},
|
@@ -152,7 +144,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
152
144
|
path.replaceWith(t.identifier(`_${uniqueId}_JSON_VALUE_${jsonValues.push(o) - 1}_`))
|
153
145
|
}
|
154
146
|
})
|
155
|
-
|
147
|
+
body.traverse({
|
156
148
|
TemplateLiteral(path) {
|
157
149
|
if ("TaggedTemplateExpression" == path.parent.type) return
|
158
150
|
const templateLiteral = path.node
|
@@ -172,7 +164,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
172
164
|
},
|
173
165
|
MemberExpression({ node: memberExpression }) {
|
174
166
|
if (!memberExpression.computed) {
|
175
|
-
assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:
|
167
|
+
assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:249:62")
|
176
168
|
if (!(memberExpression.property.name.length < 3)) {
|
177
169
|
memberExpression.computed = !0
|
178
170
|
memberExpression.property = t.stringLiteral(memberExpression.property.name)
|
@@ -246,7 +238,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
246
238
|
})
|
247
239
|
await Promise.all(promises)
|
248
240
|
const functionDeclaration = file.program.body[0]
|
249
|
-
assert("FunctionDeclaration" == functionDeclaration.type, "src/processScript/minify.ts:
|
241
|
+
assert("FunctionDeclaration" == functionDeclaration.type, "src/processScript/minify.ts:354:61")
|
250
242
|
if (jsonValues.length) {
|
251
243
|
hasComment = !0
|
252
244
|
if (1 == jsonValues.length)
|
@@ -258,7 +250,10 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
258
250
|
t.memberExpression(
|
259
251
|
t.taggedTemplateExpression(
|
260
252
|
t.memberExpression(
|
261
|
-
t.callExpression(
|
253
|
+
t.callExpression(
|
254
|
+
t.identifier(`$${uniqueId}$4$SUBSCRIPT$scripts$quine$`),
|
255
|
+
[]
|
256
|
+
),
|
262
257
|
t.identifier("split")
|
263
258
|
),
|
264
259
|
t.templateLiteral([t.templateElement({ raw: "\t", cooked: "\t" }, !0)], [])
|
@@ -282,7 +277,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
282
277
|
t.memberExpression(
|
283
278
|
t.taggedTemplateExpression(
|
284
279
|
t.memberExpression(
|
285
|
-
t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$scripts$quine$`), []),
|
280
|
+
t.callExpression(t.identifier(`$${uniqueId}$4$SUBSCRIPT$scripts$quine$`), []),
|
286
281
|
t.identifier("split")
|
287
282
|
),
|
288
283
|
t.templateLiteral([t.templateElement({ raw: "\t", cooked: "\t" }, !0)], [])
|
@@ -307,7 +302,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
307
302
|
t.memberExpression(
|
308
303
|
t.taggedTemplateExpression(
|
309
304
|
t.memberExpression(
|
310
|
-
t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$scripts$quine$`), []),
|
305
|
+
t.callExpression(t.identifier(`$${uniqueId}$4$SUBSCRIPT$scripts$quine$`), []),
|
311
306
|
t.identifier("split")
|
312
307
|
),
|
313
308
|
t.templateLiteral([t.templateElement({ raw: "\t", cooked: "\t" }, !0)], [])
|
@@ -363,7 +358,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
|
|
363
358
|
)
|
364
359
|
}
|
365
360
|
if (1 == forceQuineCheats) return code
|
366
|
-
assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:
|
361
|
+
assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:485:43")
|
367
362
|
return (
|
368
363
|
countHackmudCharacters(scriptBeforeJSONValueReplacement) <=
|
369
364
|
countHackmudCharacters(code) + Number(hasComment)
|
@@ -379,7 +374,7 @@ function parseObjectExpression(node, o) {
|
|
379
374
|
"Identifier" == property.key.type ||
|
380
375
|
"NumericLiteral" == property.key.type ||
|
381
376
|
"StringLiteral" == property.key.type,
|
382
|
-
"src/processScript/minify.ts:
|
377
|
+
"src/processScript/minify.ts:507:4"
|
383
378
|
)
|
384
379
|
if ("ArrayExpression" == property.value.type) {
|
385
380
|
const childArray = []
|
@@ -1 +1 @@
|
|
1
|
-
export declare const postprocess: (code: string,
|
1
|
+
export declare const postprocess: (code: string, uniqueId: string) => string;
|
@@ -1,12 +1,12 @@
|
|
1
|
-
const postprocess = (code,
|
1
|
+
const postprocess = (code, uniqueId) =>
|
2
2
|
code
|
3
|
-
.replace(/^function\s
|
3
|
+
.replace(/^function\s*[\w$]+\(/, "function(")
|
4
4
|
.replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$SC_DOLLAR\\$`, "g"), "S\\C$")
|
5
5
|
.replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$DB_DOLLAR\\$`, "g"), "D\\B$")
|
6
6
|
.replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$D\\$`, "g"), "_\\_D_S")
|
7
7
|
.replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$FMCL\\$`, "g"), "_\\_FMCL_")
|
8
8
|
.replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$G\\$`, "g"), "_\\_G_")
|
9
|
-
.replace(RegExp(`\\$${uniqueId}\\$SUBSCRIPT\\$(\\w+)\\$(\\w+)\\$`, "g"),
|
9
|
+
.replace(RegExp(`\\$${uniqueId}\\$(\\d)\\$SUBSCRIPT\\$(\\w+)\\$(\\w+)\\$`, "g"), "#$1s.$2.$3")
|
10
10
|
.replace(RegExp(`\\$${uniqueId}\\$DEBUG\\$`, "g"), "#D")
|
11
11
|
.replace(RegExp(`\\$${uniqueId}\\$FMCL\\$`, "g"), "#FMCL")
|
12
12
|
.replace(RegExp(`\\$${uniqueId}\\$GLOBAL\\$`, "g"), "#G")
|
@@ -101,29 +101,29 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
101
101
|
functionDotPrototypeIsReferencedMultipleTimes = !0
|
102
102
|
}
|
103
103
|
}
|
104
|
-
const neededSubscriptLets = new
|
104
|
+
const neededSubscriptLets = new Map()
|
105
105
|
let detectedSeclevel = 4
|
106
106
|
for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
|
107
|
-
program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName)
|
107
|
+
program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName, 4)
|
108
108
|
for (const fakeSubscriptObjectName of ["$hs", "$3s"])
|
109
109
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
110
110
|
detectedSeclevel = 3
|
111
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
111
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 3)
|
112
112
|
}
|
113
113
|
for (const fakeSubscriptObjectName of ["$ms", "$2s"])
|
114
114
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
115
115
|
detectedSeclevel = 2
|
116
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
116
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 2)
|
117
117
|
}
|
118
118
|
for (const fakeSubscriptObjectName of ["$ls", "$1s"])
|
119
119
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
120
120
|
detectedSeclevel = 1
|
121
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
121
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 1)
|
122
122
|
}
|
123
123
|
for (const fakeSubscriptObjectName of ["$ns", "$0s"])
|
124
124
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
125
125
|
detectedSeclevel = 0
|
126
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
126
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 0)
|
127
127
|
}
|
128
128
|
seclevel = Math.min(seclevel, detectedSeclevel)
|
129
129
|
const neededDbMethodLets = new Set()
|
@@ -157,9 +157,10 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
157
157
|
if (program.scope.hasGlobal("$FMCL"))
|
158
158
|
for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
|
159
159
|
referencePath.replaceWith(t.identifier(`$${uniqueId}$FMCL$`))
|
160
|
-
|
160
|
+
let needG = program.scope.hasGlobal("$G")
|
161
|
+
if (needG)
|
161
162
|
for (const referencePath of getReferencePathsToGlobal("$G", program))
|
162
|
-
referencePath.replaceWith(t.identifier(
|
163
|
+
referencePath.replaceWith(t.identifier(`_${uniqueId}_G_`))
|
163
164
|
if (program.scope.hasGlobal("_SECLEVEL"))
|
164
165
|
for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
|
165
166
|
referencePath.replaceWith(t.numericLiteral(seclevel))
|
@@ -167,7 +168,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
167
168
|
if (program.scope.hasGlobal("Object"))
|
168
169
|
for (const referencePath of getReferencePathsToGlobal("Object", program))
|
169
170
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
170
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
171
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:243:64")
|
171
172
|
if ("getPrototypeOf" == referencePath.parent.property.name) {
|
172
173
|
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
|
173
174
|
needGetPrototypeOf = !0
|
@@ -177,7 +178,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
177
178
|
if (program.scope.hasGlobal("console"))
|
178
179
|
for (const referencePath of getReferencePathsToGlobal("console", program))
|
179
180
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
180
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
181
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:258:64")
|
181
182
|
referencePath.parentPath.replaceWith(
|
182
183
|
t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
|
183
184
|
)
|
@@ -185,13 +186,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
185
186
|
}
|
186
187
|
const lastStatement = program.node.body.at(-1)
|
187
188
|
let exportDefaultName
|
188
|
-
assert(lastStatement, "src/processScript/transform.ts:
|
189
|
+
assert(lastStatement, "src/processScript/transform.ts:272:27 program is empty")
|
189
190
|
if ("ExportNamedDeclaration" == lastStatement.type) {
|
190
191
|
program.node.body.pop()
|
191
192
|
for (const specifier of lastStatement.specifiers) {
|
192
193
|
assert(
|
193
194
|
"ExportSpecifier" == specifier.type,
|
194
|
-
`src/processScript/transform.ts:
|
195
|
+
`src/processScript/transform.ts:278:51 ${specifier.type} is currently unsupported`
|
195
196
|
)
|
196
197
|
const exportedName =
|
197
198
|
"Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value
|
@@ -314,11 +315,11 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
314
315
|
let hoistedGlobalBlockFunctions = 0
|
315
316
|
for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
|
316
317
|
if ("VariableDeclaration" == globalBlockStatement.type) {
|
317
|
-
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:
|
318
|
+
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:412:59")
|
318
319
|
const declarator = globalBlockStatement.declarations[0]
|
319
320
|
assert(
|
320
321
|
"Identifier" == declarator.id.type,
|
321
|
-
`src/processScript/transform.ts:
|
322
|
+
`src/processScript/transform.ts:416:51 declarator.id.type was "${declarator.id.type}"`
|
322
323
|
)
|
323
324
|
program.scope.crawl()
|
324
325
|
if (program.scope.hasGlobal(declarator.id.name)) {
|
@@ -333,15 +334,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
333
334
|
Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
|
334
335
|
) {
|
335
336
|
const binding = program.scope.getBinding(declarator.id.name)
|
336
|
-
assert(binding, "src/processScript/transform.ts:
|
337
|
+
assert(binding, "src/processScript/transform.ts:435:23")
|
337
338
|
for (const referencePath of binding.referencePaths) {
|
338
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
339
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:438:56")
|
339
340
|
referencePath.replaceWith(
|
340
341
|
t.memberExpression(
|
341
|
-
t.identifier(
|
342
|
+
t.identifier(`_${uniqueId}_G_`),
|
342
343
|
t.identifier(referencePath.node.name)
|
343
344
|
)
|
344
345
|
)
|
346
|
+
needG = !0
|
345
347
|
}
|
346
348
|
for (const referencePath of binding.constantViolations)
|
347
349
|
if ("AssignmentExpression" == referencePath.node.type)
|
@@ -350,12 +352,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
350
352
|
clearObject(node)
|
351
353
|
Object.assign(
|
352
354
|
node,
|
353
|
-
t.memberExpression(t.identifier(
|
355
|
+
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(name))
|
354
356
|
)
|
357
|
+
needG = !0
|
355
358
|
}
|
356
359
|
globalBlockPath.remove()
|
357
360
|
globalBlockStatementPath.remove()
|
358
|
-
declarator.init
|
361
|
+
if (declarator.init) {
|
359
362
|
globalBlock.body.splice(
|
360
363
|
globalBlockIndex,
|
361
364
|
0,
|
@@ -363,13 +366,15 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
363
366
|
t.assignmentExpression(
|
364
367
|
"=",
|
365
368
|
t.memberExpression(
|
366
|
-
t.identifier(
|
369
|
+
t.identifier(`_${uniqueId}_G_`),
|
367
370
|
t.identifier(declarator.id.name)
|
368
371
|
),
|
369
372
|
declarator.init
|
370
373
|
)
|
371
374
|
)
|
372
375
|
)
|
376
|
+
needG = !0
|
377
|
+
}
|
373
378
|
} else {
|
374
379
|
globalBlockPath.remove()
|
375
380
|
globalBlockStatementPath.remove()
|
@@ -379,22 +384,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
379
384
|
} else globalBlockVariables.add(declarator.id.name)
|
380
385
|
} else if ("ClassDeclaration" == globalBlockStatement.type) {
|
381
386
|
program.scope.crawl()
|
382
|
-
assert(globalBlockStatement.id, "src/processScript/transform.ts:
|
387
|
+
assert(globalBlockStatement.id, "src/processScript/transform.ts:495:37")
|
383
388
|
if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
|
384
389
|
globalBlock.body.splice(globalBlockIndex, 1)
|
385
390
|
const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
|
386
391
|
[globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
|
387
392
|
program.scope.crawl()
|
388
393
|
const binding = program.scope.getBinding(globalBlockStatement.id.name)
|
389
|
-
assert(binding, "src/processScript/transform.ts:
|
394
|
+
assert(binding, "src/processScript/transform.ts:507:22")
|
390
395
|
for (const referencePath of binding.referencePaths) {
|
391
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
396
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:510:55")
|
392
397
|
referencePath.replaceWith(
|
393
|
-
t.memberExpression(
|
394
|
-
t.identifier(`$${uniqueId}$GLOBAL$`),
|
395
|
-
t.identifier(referencePath.node.name)
|
396
|
-
)
|
398
|
+
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
|
397
399
|
)
|
400
|
+
needG = !0
|
398
401
|
}
|
399
402
|
globalBlockPath.remove()
|
400
403
|
globalBlockStatementPath.remove()
|
@@ -405,7 +408,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
405
408
|
t.assignmentExpression(
|
406
409
|
"=",
|
407
410
|
t.memberExpression(
|
408
|
-
t.identifier(
|
411
|
+
t.identifier(`_${uniqueId}_G_`),
|
409
412
|
t.identifier(globalBlockStatement.id.name)
|
410
413
|
),
|
411
414
|
t.classExpression(
|
@@ -417,6 +420,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
417
420
|
)
|
418
421
|
)
|
419
422
|
)
|
423
|
+
needG = !0
|
420
424
|
}
|
421
425
|
}
|
422
426
|
if (program.scope.hasGlobal("_EXPORTS"))
|
@@ -522,12 +526,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
522
526
|
mainFunction.body.body.unshift(
|
523
527
|
t.variableDeclaration(
|
524
528
|
"let",
|
525
|
-
[...neededSubscriptLets].map(name =>
|
529
|
+
[...neededSubscriptLets].map(([name, seclevel]) =>
|
526
530
|
t.variableDeclarator(
|
527
531
|
t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`),
|
528
532
|
t.arrowFunctionExpression(
|
529
533
|
[t.restElement(t.identifier("args"))],
|
530
|
-
t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$${name}$`), [
|
534
|
+
t.callExpression(t.identifier(`$${uniqueId}$${seclevel}$SUBSCRIPT$${name}$`), [
|
531
535
|
t.spreadElement(t.identifier("args"))
|
532
536
|
])
|
533
537
|
)
|
@@ -535,6 +539,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
535
539
|
)
|
536
540
|
)
|
537
541
|
)
|
542
|
+
needG &&
|
543
|
+
mainFunction.body.body.unshift(
|
544
|
+
t.variableDeclaration("let", [
|
545
|
+
t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
|
546
|
+
])
|
547
|
+
)
|
538
548
|
traverse(file, {
|
539
549
|
BlockStatement({ node: blockStatement }) {
|
540
550
|
for (const [index, functionDeclaration] of blockStatement.body.entries())
|
@@ -555,7 +565,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
555
565
|
}
|
556
566
|
},
|
557
567
|
ClassBody({ node: classBody, scope, parent }) {
|
558
|
-
assert(t.isClass(parent), "src/processScript/transform.ts:
|
568
|
+
assert(t.isClass(parent), "src/processScript/transform.ts:688:30")
|
559
569
|
let thisIsReferenced = !1
|
560
570
|
for (const classMethod of classBody.body) {
|
561
571
|
if ("ClassMethod" != classMethod.type) continue
|
@@ -661,36 +671,37 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
661
671
|
t.identifier("prototype")
|
662
672
|
)
|
663
673
|
}
|
664
|
-
function processFakeSubscriptObject(fakeSubscriptObjectName) {
|
674
|
+
function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
|
665
675
|
for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
|
666
|
-
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:
|
676
|
+
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:804:60")
|
667
677
|
assert("Identifier" == referencePath.parent.property.type)
|
668
678
|
assert(
|
669
679
|
"MemberExpression" == referencePath.parentPath.parentPath?.node.type,
|
670
|
-
"src/processScript/transform.ts:
|
680
|
+
"src/processScript/transform.ts:806:81"
|
671
681
|
)
|
672
682
|
assert(
|
673
683
|
"Identifier" == referencePath.parentPath.parentPath.node.property.type,
|
674
|
-
"src/processScript/transform.ts:
|
684
|
+
"src/processScript/transform.ts:807:83"
|
675
685
|
)
|
676
686
|
assert(
|
677
687
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
|
678
|
-
`src/processScript/transform.ts:
|
688
|
+
`src/processScript/transform.ts:811:8 invalid user "${referencePath.parent.property.name}" in subscript`
|
679
689
|
)
|
680
690
|
assert(
|
681
691
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
|
682
|
-
`src/processScript/transform.ts:
|
692
|
+
`src/processScript/transform.ts:816:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
|
683
693
|
)
|
684
694
|
if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
|
685
695
|
referencePath.parentPath.parentPath.replaceWith(
|
686
696
|
t.identifier(
|
687
|
-
`$${uniqueId}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
|
697
|
+
`$${uniqueId}$${seclevel}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
|
688
698
|
)
|
689
699
|
)
|
690
700
|
else {
|
691
701
|
const name = `${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}`
|
692
702
|
referencePath.parentPath.parentPath.replaceWith(t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`))
|
693
|
-
neededSubscriptLets.
|
703
|
+
const maxSecLevel = Math.max(neededSubscriptLets.get(name) || 0, seclevel)
|
704
|
+
neededSubscriptLets.set(name, maxSecLevel)
|
694
705
|
}
|
695
706
|
}
|
696
707
|
}
|
package/push.d.ts
CHANGED
@@ -18,6 +18,14 @@ export type PushOptions = LaxPartial<{
|
|
18
18
|
*/
|
19
19
|
forceQuineCheats: boolean;
|
20
20
|
}>;
|
21
|
+
export declare class MissingSourceFolderError extends Error {
|
22
|
+
}
|
23
|
+
export declare class MissingHackmudFolderError extends Error {
|
24
|
+
}
|
25
|
+
export declare class NoUsersError extends Error {
|
26
|
+
}
|
27
|
+
export declare class NoScriptsError extends Error {
|
28
|
+
}
|
21
29
|
/** Push scripts from a source directory to the hackmud directory.
|
22
30
|
*
|
23
31
|
* Pushes files directly in the source folder to all users
|
@@ -25,4 +33,4 @@ export type PushOptions = LaxPartial<{
|
|
25
33
|
* @param hackmudPath directory created by hackmud containing user data including scripts
|
26
34
|
* @param options {@link PushOptions details}
|
27
35
|
* @returns array of info on pushed scripts */
|
28
|
-
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
|
36
|
+
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;
|
package/push.js
CHANGED
@@ -42,32 +42,54 @@ import "./processScript/preprocess.js"
|
|
42
42
|
import "import-meta-resolve"
|
43
43
|
import "./processScript/transform.js"
|
44
44
|
import "@samual/lib/clearObject"
|
45
|
+
class MissingSourceFolderError extends Error {}
|
46
|
+
Object.defineProperty(MissingSourceFolderError.prototype, "name", { value: "MissingSourceFolderError" })
|
47
|
+
class MissingHackmudFolderError extends Error {}
|
48
|
+
Object.defineProperty(MissingHackmudFolderError.prototype, "name", { value: "MissingHackmudFolderError" })
|
49
|
+
class NoUsersError extends Error {}
|
50
|
+
Object.defineProperty(NoUsersError.prototype, "name", { value: "NoUsersError" })
|
51
|
+
class NoScriptsError extends Error {}
|
52
|
+
Object.defineProperty(NoScriptsError.prototype, "name", { value: "NoScriptsError" })
|
45
53
|
async function push(
|
46
54
|
sourcePath,
|
47
55
|
hackmudPath,
|
48
56
|
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
|
49
57
|
) {
|
50
58
|
const [sourceFolder, hackmudFolder] = await Promise.all([
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
59
|
+
readDirectoryWithStats(sourcePath).catch(error => {
|
60
|
+
if (error && "ENOENT" == error.code)
|
61
|
+
return new MissingSourceFolderError("There is no folder at " + sourcePath)
|
62
|
+
throw error
|
63
|
+
}),
|
64
|
+
readDirectoryWithStats(hackmudPath).catch(error => {
|
65
|
+
if (error && "ENOENT" == error.code)
|
66
|
+
return new MissingHackmudFolderError("There is no folder at " + hackmudPath)
|
67
|
+
throw error
|
68
|
+
})
|
69
|
+
])
|
70
|
+
if (sourceFolder instanceof Error) return sourceFolder
|
71
|
+
if (hackmudFolder instanceof Error) return hackmudFolder
|
72
|
+
const sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
|
55
73
|
allUsers = new Set([
|
56
74
|
...scripts
|
57
|
-
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:
|
75
|
+
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:82:65"))
|
58
76
|
.filter(name => "*" != name),
|
59
77
|
...sourceFolderFolders.map(({ name }) => name),
|
60
78
|
...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
|
61
79
|
...hackmudFolder
|
62
80
|
.filter(({ stats, name }) => stats.isFile() && name.endsWith(".key"))
|
63
81
|
.map(({ name }) => name.slice(0, -4))
|
64
|
-
])
|
65
|
-
|
82
|
+
])
|
83
|
+
if (!allUsers.size)
|
84
|
+
return new NoUsersError(
|
85
|
+
"Could not find any users. Either provide the names of your users or log into a user in hackmud"
|
86
|
+
)
|
87
|
+
const usersToScriptsToPush = new Cache(_user => new Map()),
|
66
88
|
scriptNamesToUsers = new Cache(_scriptName => new Set())
|
67
89
|
for (const script of scripts) {
|
68
90
|
const [user, scriptName] = script.split(".")
|
69
|
-
assert(user, "src/push.ts:
|
70
|
-
assert(scriptName, "src/push.ts:
|
91
|
+
assert(user, "src/push.ts:105:16")
|
92
|
+
assert(scriptName, "src/push.ts:106:22")
|
71
93
|
"*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
|
72
94
|
}
|
73
95
|
const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
|
@@ -98,7 +120,7 @@ async function push(
|
|
98
120
|
for (const [scriptName, users] of scriptNamesToUsers)
|
99
121
|
for (const user of users)
|
100
122
|
if (!usersToScriptsToPush.get(user).has(scriptName))
|
101
|
-
|
123
|
+
return new NoScriptsError(`Could not find script ${user}.${scriptName} to push`)
|
102
124
|
const pathsToUsers = new Cache(_path => new Set())
|
103
125
|
for (const [user, scriptsToPush] of usersToScriptsToPush)
|
104
126
|
for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
|
@@ -135,4 +157,4 @@ async function push(
|
|
135
157
|
)
|
136
158
|
return allInfo
|
137
159
|
}
|
138
|
-
export { push }
|
160
|
+
export { MissingHackmudFolderError, MissingSourceFolderError, NoScriptsError, NoUsersError, push }
|