hackmud-script-manager 0.20.4-9f460e8 → 0.20.4-a7d8309
Sign up to get free protection for your applications and to get access to all the features.
- package/bin/hsm.js +39 -17
- package/env.d.ts +312 -304
- package/index.js +1 -1
- package/package.json +38 -38
- package/processScript/transform.js +47 -18
- package/push.js +4 -4
- package/watch.js +3 -3
package/bin/hsm.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import {
|
2
|
+
import { AutoMap } from "@samual/lib/AutoMap"
|
3
3
|
import { assert } from "@samual/lib/assert"
|
4
4
|
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
5
5
|
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
@@ -13,11 +13,10 @@ import { syncMacros } from "../syncMacros.js"
|
|
13
13
|
import "@samual/lib/readDirectoryWithStats"
|
14
14
|
import "path/posix"
|
15
15
|
import "@samual/lib/copyFilePersistent"
|
16
|
-
const
|
17
|
-
formatOption = name => colourN(`-${1 == name.length ? "" : "-"}${name}`),
|
16
|
+
const formatOption = name => colourN(`-${1 == name.length ? "" : "-"}${name}`),
|
18
17
|
options = new Map(),
|
19
18
|
commands = [],
|
20
|
-
userColours = new
|
19
|
+
userColours = new AutoMap(user => {
|
21
20
|
let hash = 0
|
22
21
|
for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
|
23
22
|
return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
|
@@ -59,11 +58,11 @@ const pushModule = import("../push.js"),
|
|
59
58
|
process.version.startsWith("v21.") &&
|
60
59
|
console.warn(
|
61
60
|
colourF(
|
62
|
-
|
61
|
+
`Warning: Support for Node.js 21 will be dropped in the next minor version of HSM\n Your current version of Node.js is ${chalk.bold(process.version)}\n You should update your version of Node.js\n https://nodejs.org/en/download/package-manager\n`
|
63
62
|
)
|
64
63
|
)
|
65
64
|
if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
|
66
|
-
console.log(
|
65
|
+
console.log("0.20.4-a7d8309")
|
67
66
|
process.exit()
|
68
67
|
}
|
69
68
|
if (popOption("help", "h")?.value) {
|
@@ -201,18 +200,27 @@ switch (commands[0]) {
|
|
201
200
|
)
|
202
201
|
} else infos.length || logError("Could not find any scripts to push")
|
203
202
|
} else {
|
204
|
-
const
|
203
|
+
const dtsPathOption = popOption(
|
204
|
+
"dts-path",
|
205
205
|
"type-declaration-path",
|
206
206
|
"type-declaration",
|
207
207
|
"dts",
|
208
208
|
"gen-types"
|
209
209
|
)
|
210
|
+
dtsPathOption &&
|
211
|
+
"emit-dts" != dtsPathOption.name &&
|
212
|
+
"gen-dts" != dtsPathOption.name &&
|
213
|
+
console.warn(
|
214
|
+
colourF(
|
215
|
+
`Warning: ${colourN(dtsPathOption.name)} is being deprecated and will be removed in the\n next minor release of HSM\n You should switch to using its alias ${colourN("--dts-path")}\n`
|
216
|
+
)
|
217
|
+
)
|
210
218
|
complainAboutUnrecognisedOptions()
|
211
219
|
const { watch } = await watchModule
|
212
220
|
watch(sourcePath, hackmudPath, {
|
213
221
|
scripts,
|
214
222
|
onPush: info => logInfo(info, hackmudPath),
|
215
|
-
typeDeclarationPath:
|
223
|
+
typeDeclarationPath: dtsPathOption?.value.toString(),
|
216
224
|
minify: noMinifyOption && !noMinifyOption.value,
|
217
225
|
mangleNames: mangleNamesOption?.value,
|
218
226
|
onReady: () => log("Watching"),
|
@@ -252,7 +260,15 @@ switch (commands[0]) {
|
|
252
260
|
case "gen-type-declaration":
|
253
261
|
case "gen-dts":
|
254
262
|
case "gen-types":
|
263
|
+
case "emit-dts":
|
255
264
|
{
|
265
|
+
"emit-dts" != commands[0] &&
|
266
|
+
"gen-dts" != commands[0] &&
|
267
|
+
console.warn(
|
268
|
+
colourF(
|
269
|
+
`Warning: ${colourC("hsm")} ${colourL(commands[0])} is being deprecated and will be removed\n in the next minor release of HSM\n You should switch to using its alias ${colourC("hsm")} ${colourL("emit-dts")}\n`
|
270
|
+
)
|
271
|
+
)
|
256
272
|
const hackmudPath = getHackmudPath(),
|
257
273
|
target = commands[1]
|
258
274
|
if (!target) {
|
@@ -266,7 +282,7 @@ switch (commands[0]) {
|
|
266
282
|
typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
|
267
283
|
let typeDeclarationPath = resolve(outputPath)
|
268
284
|
await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
|
269
|
-
assert(error instanceof Error, "src/bin/hsm.ts:
|
285
|
+
assert(error instanceof Error, "src/bin/hsm.ts:361:35")
|
270
286
|
if ("EISDIR" != error.code) throw error
|
271
287
|
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
272
288
|
return writeFile(typeDeclarationPath, typeDeclaration)
|
@@ -275,7 +291,6 @@ switch (commands[0]) {
|
|
275
291
|
}
|
276
292
|
break
|
277
293
|
case "help":
|
278
|
-
case "h":
|
279
294
|
logHelp()
|
280
295
|
break
|
281
296
|
default:
|
@@ -287,21 +302,20 @@ function logHelp() {
|
|
287
302
|
const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
|
288
303
|
forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`,
|
289
304
|
hackmudPathOption = `${colourN("--hackmud-path")}=${colourB("<path>")}\n Override hackmud path`
|
290
|
-
console.log(colourN("Version") + colourS(": ") + colourV(version))
|
291
305
|
switch (commands[0]) {
|
292
306
|
case "dev":
|
293
307
|
case "watch":
|
294
308
|
case "push":
|
295
309
|
console.log(
|
296
310
|
colourS(
|
297
|
-
|
311
|
+
`${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("--dts-path")}=${colourB("<path>")}\n Path to generate a type declaration (.d.ts) 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`
|
298
312
|
)
|
299
313
|
)
|
300
314
|
break
|
301
315
|
case "pull":
|
302
316
|
console.log(
|
303
317
|
colourS(
|
304
|
-
|
318
|
+
`${colourJ("Pull a script a from a hackmud user's script directory")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<script user>")}${colourV(".")}${colourB("<script name>")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
|
305
319
|
)
|
306
320
|
)
|
307
321
|
break
|
@@ -309,7 +323,7 @@ function logHelp() {
|
|
309
323
|
case "golf":
|
310
324
|
console.log(
|
311
325
|
colourS(
|
312
|
-
|
326
|
+
`${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`
|
313
327
|
)
|
314
328
|
)
|
315
329
|
break
|
@@ -317,6 +331,14 @@ function logHelp() {
|
|
317
331
|
case "gen-type-declaration":
|
318
332
|
case "gen-dts":
|
319
333
|
case "gen-types":
|
334
|
+
case "emit-dts":
|
335
|
+
"emit-dts" != commands[0] &&
|
336
|
+
"gen-dts" != commands[0] &&
|
337
|
+
console.warn(
|
338
|
+
colourF(
|
339
|
+
`Warning: ${colourC("hsm")} ${colourL(commands[0])} is being deprecated and will be removed\n in the next minor release of HSM\n You should switch to using its alias ${colourC("hsm")} ${colourL("emit-dts")}\n`
|
340
|
+
)
|
341
|
+
)
|
320
342
|
console.log(
|
321
343
|
colourS(
|
322
344
|
`${colourJ("Generate a type declaration file for a directory of scripts")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [output path]")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
|
@@ -326,14 +348,14 @@ function logHelp() {
|
|
326
348
|
case "sync-macros":
|
327
349
|
console.log(
|
328
350
|
colourS(
|
329
|
-
|
351
|
+
`${colourJ("Sync macros across all hackmud users")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
|
330
352
|
)
|
331
353
|
)
|
332
354
|
break
|
333
355
|
default:
|
334
356
|
console.log(
|
335
357
|
colourS(
|
336
|
-
|
358
|
+
`${colourJ("Hackmud Script Manager")}\n${colourN("Version") + colourS(": ") + colourV("0.20.4-a7d8309")}\n\n${colourA("Commands:")}\n${colourL("push")}\n ${pushCommandDescription}\n${colourL("dev")}\n Watch a directory and push a script when modified\n${colourL("minify")}\n Minify a script file on the spot\n${colourL("emit-dts")}\n Generate a type declaration file for a directory of scripts\n${colourL("sync-macros")}\n Sync macros across all hackmud users\n${colourL("pull")}\n Pull a script a from a hackmud user's script directory\n\n${colourA("Options:")}\n${colourN("--help")}\n Can be used on any command e.g. ${colourC("hsm")} ${colourL("push")} ${colourN("--help")} to show helpful information`
|
337
359
|
)
|
338
360
|
)
|
339
361
|
}
|
@@ -351,7 +373,7 @@ function logError(message) {
|
|
351
373
|
process.exitCode = 1
|
352
374
|
}
|
353
375
|
function getHackmudPath() {
|
354
|
-
const hackmudPathOption = popOption("hackmud-path")
|
376
|
+
const hackmudPathOption = popOption("hackmud-path")?.value
|
355
377
|
if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
|
356
378
|
logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
|
357
379
|
logHelp()
|
package/env.d.ts
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
type Replace<A, B> = Omit<A, keyof B> & B
|
2
|
-
type ScriptSuccess<T =
|
2
|
+
type ScriptSuccess<T = unknown> = { ok: true } & T
|
3
3
|
type ScriptFailure = { ok: false, msg?: string }
|
4
|
-
type ScriptResponse<T =
|
4
|
+
type ScriptResponse<T = unknown> = ScriptSuccess<T> | ScriptFailure
|
5
5
|
type ErrorScripts = Record<string, () => ScriptFailure>
|
6
|
-
type Scriptor<TArgs extends any[] = any[]> = { name: string, call: (...args: TArgs) => unknown }
|
7
6
|
|
8
7
|
type Subscripts = Record<string, Record<string, (...args: any) => any>> & {
|
9
8
|
accts: ErrorScripts
|
@@ -28,8 +27,7 @@ interface PlayerLowsec {}
|
|
28
27
|
interface PlayerNullsec {}
|
29
28
|
|
30
29
|
type UpgradeRarityString = "`0noob`" | "`1kiddie`" | "`2h4x0r`" | "`3h4rdc0r3`" | "`4|_|b3|2`" | "`531337`"
|
31
|
-
type UpgradeRarityNumber = 0 | 1 | 2 | 3 | 4 | 5
|
32
|
-
type UpgradeRarity = UpgradeRarityString | UpgradeRarityNumber;
|
30
|
+
type UpgradeRarityNumber = 0 | 1 | 2 | 3 | 4 | 5
|
33
31
|
|
34
32
|
type UpgradeBase = {
|
35
33
|
name: string
|
@@ -45,10 +43,8 @@ type UpgradeBase = {
|
|
45
43
|
|
46
44
|
type Upgrade = UpgradeBase & Record<string, null | boolean | number | string>
|
47
45
|
|
48
|
-
type CliUpgrade = Omit<UpgradeBase, `rarity`> &
|
49
|
-
[
|
50
|
-
rarity: UpgradeRarityString
|
51
|
-
}
|
46
|
+
type CliUpgrade = Omit<UpgradeBase, `rarity`> &
|
47
|
+
{ [k: string]: null | boolean | number | string, rarity: UpgradeRarityString }
|
52
48
|
|
53
49
|
type UsersTopItem<R> = { rank: R, name: string, last_activity: string, balance: string }
|
54
50
|
type CorpsTopItem<R> = { rank: R, name: string, worth: string }
|
@@ -126,21 +122,11 @@ type Fullsec = Subscripts & PlayerFullsec & {
|
|
126
122
|
}
|
127
123
|
|
128
124
|
escrow: {
|
129
|
-
/** **FULLSEC** */ charge: (args: {
|
130
|
-
cost: number | string
|
131
|
-
is_unlim?: boolean
|
132
|
-
}) => null | ScriptFailure
|
133
|
-
|
125
|
+
/** **FULLSEC** */ charge: (args: { cost: number | string, is_unlim?: boolean }) => null | ScriptFailure
|
134
126
|
confirm: never
|
135
127
|
}
|
136
128
|
|
137
|
-
gui: {
|
138
|
-
chats: never
|
139
|
-
quiet: never
|
140
|
-
size: never
|
141
|
-
vfx: never
|
142
|
-
vol: never
|
143
|
-
}
|
129
|
+
gui: { chats: never, quiet: never, size: never, vfx: never, vol: never }
|
144
130
|
|
145
131
|
market: {
|
146
132
|
/** **FULLSEC** */ browse: {
|
@@ -459,7 +445,10 @@ type Highsec = Fullsec & PlayerHighsec & {
|
|
459
445
|
/** **HIGHSEC**
|
460
446
|
* @returns GC balance as number if `is_script` is true (default).
|
461
447
|
* @returns GC balance as string if `is_script` is false. */
|
462
|
-
balance:
|
448
|
+
balance: {
|
449
|
+
(args?: { is_script?: true }): number
|
450
|
+
(args: { is_script: false }): string
|
451
|
+
}
|
463
452
|
|
464
453
|
/** **HIGHSEC**
|
465
454
|
* @returns Transaction history according to filter.
|
@@ -716,95 +705,145 @@ type Nullsec = Lowsec & PlayerNullsec & {
|
|
716
705
|
}
|
717
706
|
}
|
718
707
|
|
719
|
-
|
720
|
-
|
721
|
-
type
|
708
|
+
// database
|
709
|
+
type MongoPrimitive = null | boolean | number | Date | string
|
710
|
+
type MongoValue = MongoPrimitive | MongoValue[] | MongoObject
|
711
|
+
type MongoObject = { [k: string]: MongoValue, [k: `$${string}`]: never }
|
712
|
+
type MongoQueryValue = MongoPrimitive | MongoQueryValue[] | MongoQueryObject
|
713
|
+
|
714
|
+
type MongoQueryObject =
|
715
|
+
{ [k: string]: MongoQueryValue, [k: `$${string}`]: MongoValue, $type?: keyof MongoTypeStringsToTypes | (string & {}) }
|
716
|
+
|
717
|
+
type MongoTypeStringsToTypes = {
|
718
|
+
double: number
|
719
|
+
string: string
|
720
|
+
object: MongoObject
|
721
|
+
array: MongoValue[]
|
722
|
+
objectId: ObjectId
|
723
|
+
bool: boolean
|
724
|
+
date: Date
|
725
|
+
null: null
|
726
|
+
int: number
|
727
|
+
long: number
|
728
|
+
}
|
729
|
+
|
730
|
+
type MongoTypeString = keyof MongoTypeStringsToTypes
|
731
|
+
type MongoTypeNumber = -1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 127
|
732
|
+
type MongoId = Exclude<MongoPrimitive, null> | MongoObject
|
733
|
+
type MongoQueryId = Exclude<MongoPrimitive, null> | MongoQueryObject
|
734
|
+
type MongoDocument = MongoObject & { _id?: MongoId }
|
735
|
+
|
736
|
+
type MongoQueryType<TQuery extends MongoQueryObject> = {
|
737
|
+
-readonly [K in keyof TQuery]:
|
738
|
+
TQuery[K] extends MongoPrimitive ?
|
739
|
+
TQuery[K]
|
740
|
+
: TQuery[K] extends { $type: infer TType } ?
|
741
|
+
TType extends keyof MongoTypeStringsToTypes ? MongoTypeStringsToTypes[TType] : unknown
|
742
|
+
: TQuery[K] extends { $in: (infer TIn)[] } ?
|
743
|
+
TIn
|
744
|
+
: keyof TQuery[K] extends `$${string}` ?
|
745
|
+
unknown
|
746
|
+
: TQuery[K] extends { [k: string]: any } ?
|
747
|
+
MongoQueryType<TQuery[K]>
|
748
|
+
: never
|
749
|
+
}
|
722
750
|
|
723
|
-
type
|
751
|
+
type MongoCommandValue = MongoPrimitive | MongoCommandValue[] | { [k: string]: MongoCommandValue }
|
752
|
+
type MongoArraySelectors<T extends MongoValue[] = MongoValue[]> = { $all: T, $elemMatch: T, $size: number }
|
724
753
|
|
725
|
-
type
|
726
|
-
|
754
|
+
type MongoComparisonSelectors<T extends MongoValue = MongoValue> =
|
755
|
+
{ $eq: T, $gt: T, $gte: T, $in: T[], $lt: T, $lte: T, $ne: T, $nin: T[] }
|
727
756
|
|
728
|
-
|
729
|
-
* Currently unused
|
730
|
-
*/
|
731
|
-
type MongoLogicalSelectors<T extends MongoValue = MongoValue> = {
|
732
|
-
$not: T | MongoComparisonSelectors<T> | MongoLogicalSelectors<T>
|
733
|
-
$nor: T[]
|
734
|
-
$or: T[]
|
735
|
-
$and: T[]
|
736
|
-
}
|
757
|
+
type MongoElementSelectors = { $exists: boolean, $type: MongoTypeNumber | MongoTypeString }
|
737
758
|
|
738
|
-
type
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
759
|
+
type MongoQuerySelector<T extends MongoValue> = Partial<
|
760
|
+
T extends []
|
761
|
+
? MongoArraySelectors<T> & MongoElementSelectors & MongoComparisonSelectors<T>
|
762
|
+
: MongoElementSelectors & MongoComparisonSelectors<T>
|
763
|
+
>
|
743
764
|
|
744
|
-
type
|
745
|
-
$eq: T
|
746
|
-
$gt: T
|
747
|
-
$gte: T
|
748
|
-
$in: T[]
|
749
|
-
$lt: T
|
750
|
-
$lte: T
|
751
|
-
$ne: T
|
752
|
-
$nin: T[]
|
753
|
-
}
|
765
|
+
type MongoQuery<T extends MongoObject> = { [K in keyof T]?: T[K] | MongoQuerySelector<T[K]> } & { _id?: MongoId }
|
754
766
|
|
755
|
-
type
|
756
|
-
|
757
|
-
$
|
758
|
-
|
767
|
+
type MongoUpdateOperators<T extends MongoObject> = Partial<{
|
768
|
+
/* Universal operators */
|
769
|
+
$set: Partial<Record<string, MongoCommandValue> & T>
|
770
|
+
$setOnInsert: Partial<Record<string, MongoCommandValue> & T>
|
771
|
+
$unset: Partial<Record<string, ""> & T>
|
759
772
|
|
760
|
-
|
761
|
-
(MongoArraySelectors<T> & MongoElementSelectors & MongoComparisonSelectors<T>) :
|
762
|
-
(MongoElementSelectors & MongoComparisonSelectors<T>)>
|
773
|
+
$rename: Partial<Record<string, string> & { [key in keyof T]: string }>
|
763
774
|
|
764
|
-
|
765
|
-
|
775
|
+
/* Date & number operators */
|
776
|
+
$inc: Record<string, number> &
|
777
|
+
{ [K in keyof T as T[K] extends number | Date ? K : never]?: T[K] extends number ? number : Date }
|
766
778
|
|
767
|
-
|
768
|
-
|
769
|
-
>
|
779
|
+
$mul: Record<string, number> & { [K in keyof T as T[K] extends number ? K : never]?: number }
|
780
|
+
$min: Record<string, number> & { [K in keyof T as T[K] extends number ? K : never]?: number }
|
781
|
+
$max: Record<string, number> & { [K in keyof T as T[K] extends number ? K : never]?: number }
|
782
|
+
|
783
|
+
/* Array operators */
|
784
|
+
$pop: Record<string, -1 | 1> & { [K in keyof T as T[K] extends [] ? K : never]?: -1 | 1 }
|
785
|
+
|
786
|
+
$push: Record<string, MongoCommandValue> & {
|
787
|
+
[K in keyof T as T[K] extends [] ? K : never]?: (T[K] extends (infer U)[] ? U : never)
|
788
|
+
| MongoUpdateArrayOperatorModifiers<T[K]>
|
789
|
+
}
|
790
|
+
|
791
|
+
$addToSet: Partial<Record<string, MongoCommandValue> & {
|
792
|
+
[K in keyof T as T[K] extends [] ? K : never]: (T[K] extends (infer U)[] ? U : never)
|
793
|
+
| MongoUpdateArrayOperatorUniversalModifiers<T[K]>
|
794
|
+
}>
|
795
|
+
|
796
|
+
$pull: Partial<Record<string, MongoCommandValue> & {
|
797
|
+
[K in keyof T as T[K] extends [] ? K : never]: (T[K] extends (infer U)[] ? U : never)
|
798
|
+
| MongoQuerySelector<T[K]>
|
799
|
+
}>
|
800
|
+
|
801
|
+
$pullAll: Record<string, MongoCommandValue> & { [K in keyof T as T[K] extends [] ? K : never]?: T[K] }
|
802
|
+
}>
|
803
|
+
|
804
|
+
type MongoUpdateArrayOperatorUniversalModifiers<T> = { $each?: T extends [] ? T : T[] }
|
805
|
+
|
806
|
+
type MongoUpdateArrayOperatorModifiers<T> = MongoUpdateArrayOperatorUniversalModifiers<T> &
|
807
|
+
{ $position?: number, $slice?: number, $sort?: 1 | -1 }
|
808
|
+
|
809
|
+
type MongoUpdateCommand<Schema extends MongoObject> = MongoUpdateOperators<Schema>
|
770
810
|
|
771
|
-
type Id = string | number | boolean | Date | Record<string, MongoValue>
|
772
|
-
type MongoDocument = { [key: string]: MongoValue, _id: Id }
|
773
811
|
type SortOrder = { [key: string]: 1 | -1 | SortOrder }
|
774
812
|
|
775
|
-
type Cursor = {
|
776
|
-
/** Returns the first document that satisfies the query. */ first: () =>
|
777
|
-
/** Returns an array of documents that satisfy the query. */ array: () =>
|
813
|
+
type Cursor<T> = {
|
814
|
+
/** Returns the first document that satisfies the query. */ first: () => T | null
|
815
|
+
/** Returns an array of documents that satisfy the query. */ array: () => T[]
|
778
816
|
/** Returns the number of documents that match the query. */ count: () => number
|
779
817
|
|
780
818
|
/** Returns the first document that satisfies the query. Also makes cursor unusable. */
|
781
|
-
first_and_close: () =>
|
819
|
+
first_and_close: () => T
|
782
820
|
|
783
821
|
/** Returns an array of documents that satisfy the query. Also makes cursor unusable. */
|
784
|
-
array_and_close: () =>
|
822
|
+
array_and_close: () => T[]
|
785
823
|
|
786
824
|
/** Returns the number of documents that match the query. Also makes cursor unusable. */
|
787
825
|
count_and_close: () => number
|
788
826
|
|
789
827
|
/** Run `callback` on each document that satisfied the query. */
|
790
|
-
each: (callback: (document:
|
828
|
+
each: (callback: (document: T) => void) => null
|
791
829
|
|
792
830
|
/** Returns a new cursor with documents sorted as specified.
|
793
831
|
* A value of 1 sorts the property ascending, and -1 descending.
|
794
832
|
* @param order The way the documents are to be sorted. */
|
795
|
-
sort: (order?: SortOrder) => Cursor
|
833
|
+
sort: (order?: SortOrder) => Cursor<T>
|
796
834
|
|
797
835
|
/** Returns a new cursor without the first number of documents.
|
798
836
|
* @param count Number of documents to skip. */
|
799
|
-
skip: (count: number) => Cursor
|
837
|
+
skip: (count: number) => Cursor<T>
|
800
838
|
|
801
839
|
/** Returns a new cursor limited to a number of documents as specified.
|
802
840
|
* @param count Number of documents. */
|
803
|
-
limit: (count: number) => Cursor
|
841
|
+
limit: (count: number) => Cursor<T>
|
804
842
|
|
805
|
-
/** @param key The key of the documents. */ distinct: (
|
843
|
+
/** @param key The key of the documents. */ distinct: { (key: string): MongoValue[], (key: "_id"): MongoId[] }
|
806
844
|
/** Make cursor unusable. */ close: () => null
|
807
845
|
NumberLong: (number: number) => number
|
846
|
+
// TODO what actually is the type here?
|
808
847
|
ObjectId: () => any
|
809
848
|
}
|
810
849
|
|
@@ -815,7 +854,9 @@ type CliContext = {
|
|
815
854
|
/** The number of rows in the caller’s terminal. */ rows: number
|
816
855
|
|
817
856
|
/** The name of the script that directly called this script, or null if called on the command line or as a
|
818
|
-
* scriptor. */
|
857
|
+
* scriptor. */
|
858
|
+
calling_script: null
|
859
|
+
|
819
860
|
is_scriptor?: undefined
|
820
861
|
is_brain?: undefined
|
821
862
|
}
|
@@ -826,245 +867,212 @@ type SubscriptContext = Replace<CliContext, {
|
|
826
867
|
calling_script: string
|
827
868
|
}>
|
828
869
|
|
829
|
-
type ScriptorContext =
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
type
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
/** Subscript space that can call any script. Makes your script NULLSEC (overrides higher security levels). */
|
851
|
-
declare const $ns: Nullsec
|
870
|
+
type ScriptorContext = Replace<CliContext, { /** Whether the script is being run as a scriptor. */ is_scriptor: true }>
|
871
|
+
type BrainContext = Replace<CliContext, { /** Whether the script is being run via a bot brain. */ is_brain: true }>
|
872
|
+
|
873
|
+
// _id is always returned unless _id: false is passed
|
874
|
+
// when anyField: true is given, other fields (except _id) are omitted
|
875
|
+
|
876
|
+
type MongoProject<TDocument, TProjection> =
|
877
|
+
true extends (1 extends TProjection[keyof TProjection] ? true : TProjection[keyof TProjection]) ?
|
878
|
+
(TProjection extends { _id: false | 0 } ? {} : { _id: TDocument extends { _id: infer TId } ? TId : MongoId }) &
|
879
|
+
{
|
880
|
+
[K in
|
881
|
+
keyof TDocument as K extends keyof TProjection ? TProjection[K] extends true | 1 ? K : never : never
|
882
|
+
]: TDocument[K]
|
883
|
+
} &
|
884
|
+
{
|
885
|
+
-readonly [K in
|
886
|
+
keyof TProjection as TProjection[K] extends true | 1 ? K extends keyof TDocument ? never : K : never
|
887
|
+
]?: MongoValue
|
888
|
+
}
|
889
|
+
: { [k: string]: MongoValue } & { [K in keyof TDocument as K extends keyof TProjection ? never : K]: TDocument[K] }
|
852
890
|
|
853
|
-
|
891
|
+
type DeepFreeze<T> = { readonly [P in keyof T]: DeepFreeze<T[P]> }
|
854
892
|
|
855
|
-
|
856
|
-
|
893
|
+
declare global {
|
894
|
+
type Scriptor<TArgs extends any[] = any[]> = { name: string, call: (...args: TArgs) => unknown }
|
895
|
+
type Context = CliContext | SubscriptContext | ScriptorContext | BrainContext
|
896
|
+
type ObjectId = { $oid: string }
|
857
897
|
|
858
|
-
/** Subscript space that can call
|
859
|
-
*/
|
860
|
-
declare const $2s: typeof $ms
|
898
|
+
/** Subscript space that can call FULLSEC scripts. */ const $fs: Fullsec
|
861
899
|
|
862
|
-
/** Subscript space that can call
|
863
|
-
|
864
|
-
declare const $1s: typeof $ls
|
900
|
+
/** Subscript space that can call HIGHSEC and above scripts. Makes your script HIGHSEC (overrides FULLSEC). */
|
901
|
+
const $hs: Highsec
|
865
902
|
|
866
|
-
/** Subscript space that can call
|
867
|
-
|
903
|
+
/** Subscript space that can call MIDSEC and above scripts. Makes your script MIDSEC (overrides higher security levels).
|
904
|
+
*/
|
905
|
+
const $ms: Midsec
|
868
906
|
|
869
|
-
/** Subscript space that can call
|
870
|
-
|
871
|
-
|
872
|
-
* // remove the space betwen "@" and "s", there's only a space because otherwise vscode breaks
|
873
|
-
* export function script() {
|
874
|
-
* $s.foo.bar() // will be converted to #ms.foo.bar()
|
875
|
-
* } */
|
876
|
-
declare const $s: Nullsec
|
907
|
+
/** Subscript space that can call LOWSEC and above scripts. Makes your script LOWSEC (overrides higher security levels).
|
908
|
+
*/
|
909
|
+
const $ls: Lowsec
|
877
910
|
|
878
|
-
|
911
|
+
/** Subscript space that can call any script. Makes your script NULLSEC (overrides higher security levels). */
|
912
|
+
const $ns: Nullsec
|
879
913
|
|
880
|
-
|
881
|
-
/** Insert a document or documents into a collection.
|
882
|
-
* @param documents A document or array of documents to insert into the collection. */
|
883
|
-
i: (documents: object | object[]) => {
|
884
|
-
ok: 1
|
885
|
-
n: number
|
886
|
-
opTime: { ts: "Undefined Conversion", t: number }
|
887
|
-
electionId: "Undefined Conversion"
|
888
|
-
operationTime: "Undefined Conversion"
|
889
|
-
$clusterTime: {
|
890
|
-
clusterTime: "Undefined Conversion"
|
891
|
-
signature: { hash: "Undefined Conversion", keyId: "Undefined Conversion" }
|
892
|
-
}
|
893
|
-
}
|
914
|
+
/** Subscript space that can call FULLSEC scripts. */ const $4s: typeof $fs
|
894
915
|
|
895
|
-
/**
|
896
|
-
|
897
|
-
r: (query: Query) => {
|
898
|
-
ok: 0 | 1
|
899
|
-
n: number
|
900
|
-
opTime: { ts: "Undefined Conversion", t: number }
|
901
|
-
electionId: "Undefined Conversion"
|
902
|
-
operationTime: "Undefined Conversion"
|
903
|
-
$clusterTime: {
|
904
|
-
clusterTime: "Undefined Conversion"
|
905
|
-
signature: { hash: "Undefined Conversion", keyId: "Undefined Conversion" }
|
906
|
-
}
|
907
|
-
}
|
916
|
+
/** Subscript space that can call HIGHSEC and above scripts. Makes your script HIGHSEC (overrides FULLSEC). */
|
917
|
+
const $3s: typeof $hs
|
908
918
|
|
909
|
-
/**
|
910
|
-
|
911
|
-
|
912
|
-
f: (query?: Query, projection?: Projection) => Cursor
|
913
|
-
|
914
|
-
/** Update an existing documents in a collection.
|
915
|
-
* @param query Specifies deletion criteria using query operators.
|
916
|
-
* @param command The modifications to apply.
|
917
|
-
* {@link https://docs.mongodb.com/manual/reference/method/db.collection.update/#parameters} */
|
918
|
-
u: (query: Query | Query[], command: MongoCommand) => {
|
919
|
-
ok: 0 | 1
|
920
|
-
nModified: number
|
921
|
-
n: number
|
922
|
-
opTime: { ts: "Undefined Conversion", t: number }
|
923
|
-
electionId: "Undefined Conversion"
|
924
|
-
operationTime: "Undefined Conversion"
|
925
|
-
$clusterTime: {
|
926
|
-
clusterTime: "Undefined Conversion"
|
927
|
-
signature: { hash: "Undefined Conversion", keyId: "Undefined Conversion" }
|
928
|
-
}
|
929
|
-
}
|
930
|
-
|
931
|
-
/** Updates one document within the collection based on the filter.
|
932
|
-
* @param query Specifies deletion criteria using query operators.
|
933
|
-
* @param command The modifications to apply.
|
934
|
-
* {@link https://docs.mongodb.com/manual/reference/method/db.collection.update/#parameters} */
|
935
|
-
u1: (query: Query | Query[], command: MongoCommand) => {
|
936
|
-
ok: 0 | 1
|
937
|
-
nModified: number
|
938
|
-
n: number
|
939
|
-
opTime: {
|
940
|
-
ts: "Undefined Conversion"
|
941
|
-
t: number
|
942
|
-
}
|
943
|
-
electionId: "Undefined Conversion"
|
944
|
-
operationTime: "Undefined Conversion"
|
945
|
-
$clusterTime: {
|
946
|
-
clusterTime: "Undefined Conversion"
|
947
|
-
signature: {
|
948
|
-
hash: "Undefined Conversion"
|
949
|
-
keyId: "Undefined Conversion"
|
950
|
-
}
|
951
|
-
}
|
952
|
-
}
|
919
|
+
/** Subscript space that can call MIDSEC and above scripts. Makes your script MIDSEC (overrides higher security levels).
|
920
|
+
*/
|
921
|
+
const $2s: typeof $ms
|
953
922
|
|
954
|
-
/**
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
923
|
+
/** Subscript space that can call LOWSEC and above scripts. Makes your script LOWSEC (overrides higher security levels).
|
924
|
+
*/
|
925
|
+
const $1s: typeof $ls
|
926
|
+
|
927
|
+
/** Subscript space that can call any script. Makes your script NULLSEC (overrides higher security levels). */
|
928
|
+
const $0s: typeof $ns
|
929
|
+
|
930
|
+
/** Subscript space that can call any script. Uses seclevel provided in comment before script (defaults to NULLSEC)
|
931
|
+
* @example
|
932
|
+
* // @seclevel MIDSEC
|
933
|
+
* // note, do NOT copy paste the above line because there is a zero-width space inserted between "@" and "s"
|
934
|
+
* export function script() {
|
935
|
+
* $s.foo.bar() // will be converted to #ms.foo.bar()
|
936
|
+
* } */
|
937
|
+
const $s: Nullsec
|
938
|
+
|
939
|
+
const $db: {
|
940
|
+
/** Insert a document or documents into a collection.
|
941
|
+
* @param documents A document or array of documents to insert into the collection. */
|
942
|
+
i: <T extends MongoDocument>(documents: (T & { _id?: MongoId }) | (T & { _id?: MongoId })[]) =>
|
943
|
+
{ n: number, opTime: { t: number }, ok: 0 | 1 }[]
|
944
|
+
|
945
|
+
/** Remove documents from a collection.
|
946
|
+
* @param query Specifies deletion criteria using query operators. */
|
947
|
+
r: <T extends MongoDocument>(query: MongoQuery<T>) => { n: number, opTime: { t: number }, ok: 0 | 1 }[]
|
948
|
+
|
949
|
+
/** Find documents in a collection or view and returns a cursor to the selected documents.
|
950
|
+
* @param query Specifies deletion criteria using query operators.
|
951
|
+
* @param projection Specifies the fields to return in the documents that match the query filter. */
|
952
|
+
f: <
|
953
|
+
const TQuery extends MongoQueryObject & { _id?: MongoQueryId },
|
954
|
+
const TProjection extends { [k: string]: boolean | 0 | 1 } = {}
|
955
|
+
>(query: TQuery, projection?: TProjection) => Cursor<MongoProject<MongoQueryType<TQuery>, TProjection>>
|
956
|
+
|
957
|
+
/** Update existing documents in a collection.
|
958
|
+
* @param query Specifies deletion criteria using query operators.
|
959
|
+
* @param command The modifications to apply.
|
960
|
+
* {@link https://docs.mongodb.com/manual/reference/method/db.collection.update/#parameters} */
|
961
|
+
u: <T extends MongoDocument>(query: MongoQuery<T> | MongoQuery<T>[], command: MongoUpdateCommand<T>) =>
|
962
|
+
{ n: number, opTime: { t: number }, ok: 0 | 1, nModified: number }[]
|
963
|
+
|
964
|
+
/** Updates one document within the collection based on the filter.
|
965
|
+
* @param query Specifies deletion criteria using query operators.
|
966
|
+
* @param command The modifications to apply.
|
967
|
+
* {@link https://docs.mongodb.com/manual/reference/method/db.collection.update/#parameters} */
|
968
|
+
u1: <T extends MongoDocument>(query: MongoQuery<T> | MongoQuery<T>[], command: MongoUpdateCommand<T>) =>
|
969
|
+
{ n: number, ok: 0 | 1, opTime: { t: number }, nModified: number }[]
|
970
|
+
|
971
|
+
/** Update or insert document.
|
972
|
+
* Same as Update, but if no documents match the query, one document will be inserted based on the properties in
|
973
|
+
* both the query and the command.
|
974
|
+
* The `$setOnInsert` operator is useful to set defaults.
|
975
|
+
* @param query Specifies deletion criteria using query operators.
|
976
|
+
* @param command The modifications to apply.
|
977
|
+
* {@link https://docs.mongodb.com/manual/reference/method/db.collection.update/#parameters} */
|
978
|
+
us: <T extends MongoDocument>(query: MongoQuery<T> | MongoQuery<T>[], command: MongoUpdateCommand<T>) =>
|
979
|
+
{ n: number, ok: 0 | 1, opTime: { t: number }, nModified: number }[]
|
980
|
+
|
981
|
+
ObjectId: () => ObjectId
|
972
982
|
}
|
973
983
|
|
974
|
-
|
984
|
+
/** Debug Log.
|
985
|
+
*
|
986
|
+
* If `$D()` is called in a script you own, the `return` value of the top level script is suppressed and instead an
|
987
|
+
* array of every `$D()`’d entry is printed.
|
988
|
+
* This lets you use `$D()` like `console.log()`.
|
989
|
+
*
|
990
|
+
* `$D()` in scripts not owned by you are not shown but the `return` value always is.
|
991
|
+
*
|
992
|
+
* `$D()` returns the first argument so `$D("Hello, World!") evaluates to `"Hello, World!"` as if the `$D` text wasn't
|
993
|
+
* there.
|
994
|
+
*
|
995
|
+
* `$D()`’d items are returned even if the script times out or errors. */
|
996
|
+
function $D<T>(args: T): T
|
997
|
+
|
998
|
+
/** Function Multi-Call Lock.
|
999
|
+
*
|
1000
|
+
* This is used by escrow to ensure that it is only used once in script execution.
|
1001
|
+
*
|
1002
|
+
* The first time (per-script) `$FMCL` is encountered, it returns `undefined`, every other time it `return`s `true`.
|
1003
|
+
*
|
1004
|
+
* @example
|
1005
|
+
* if ($FMCL)
|
1006
|
+
* return { ok: false, msg: "This script can only be used once per script execution." }
|
1007
|
+
*
|
1008
|
+
* // all code here will only run once */
|
1009
|
+
const $FMCL: undefined | true
|
1010
|
+
|
1011
|
+
/** Per-script mutable "global" persistent object that is discarded at the end of top level script execution.
|
1012
|
+
*
|
1013
|
+
* `$G` persists between script calls until the end of the main script run making it useful for caching db entries when
|
1014
|
+
* your script is a subscript.
|
1015
|
+
* @example
|
1016
|
+
* if (!$G.dbCache)
|
1017
|
+
* $G.dbCache = $db.f({ whatever: true }).first() */
|
1018
|
+
const $G: Record<string | symbol, any>
|
1019
|
+
|
1020
|
+
/** This contains a JS timestamp (not Date) set immediately before your code begins running.
|
1021
|
+
* @example
|
1022
|
+
* $D(Date.now() - _START) // milliseconds left of run time
|
1023
|
+
*/
|
1024
|
+
const _START: number
|
1025
|
+
|
1026
|
+
/** This contains a JS timestamp (not Date) set immediately before your code begins running.
|
1027
|
+
* @example
|
1028
|
+
* $D(Date.now() - _ST) // milliseconds left of run time */
|
1029
|
+
const _ST: typeof _START
|
1030
|
+
|
1031
|
+
/** JavaScript timestamp for the end of the script run (`_START + _TIMEOUT`). */ const _END: number
|
1032
|
+
|
1033
|
+
/** The number of milliseconds a script can run for. Normally `5000` though it has been known to change. */
|
1034
|
+
const _TIMEOUT: number
|
1035
|
+
|
1036
|
+
/** The number of milliseconds a script can run for. Normally `5000` though it has been known to change. */
|
1037
|
+
const _TO: typeof _TIMEOUT
|
1038
|
+
|
1039
|
+
/** The source code of this script as a string. */ const _SOURCE: string
|
1040
|
+
/** A unix timestamp of the date this script was built. */ const _BUILD_DATE: number
|
1041
|
+
|
1042
|
+
/** The user this script has been uploaded to.
|
1043
|
+
*
|
1044
|
+
* Shorter alternative to `context.this_script.split(".")[0].
|
1045
|
+
*
|
1046
|
+
* In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
|
1047
|
+
const _SCRIPT_USER: string
|
1048
|
+
|
1049
|
+
/** The name of this script excluding the user and `.`.
|
1050
|
+
*
|
1051
|
+
* e.g. in the script `foo.bar`, `_SCRIPT_NAME` is `bar`.
|
1052
|
+
*
|
1053
|
+
* Shorter alternative to `context.this_script.split(".")[1].
|
1054
|
+
*
|
1055
|
+
* In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
|
1056
|
+
const _SCRIPT_NAME: string
|
1057
|
+
|
1058
|
+
/** The full name of this script equivilent to `context.this_script` but should use less characters.
|
1059
|
+
*
|
1060
|
+
* In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
|
1061
|
+
const _FULL_SCRIPT_NAME: string
|
1062
|
+
|
1063
|
+
/** The seclevel of this script as a number.
|
1064
|
+
*
|
1065
|
+
* In rare cases where it's not known at build time, it's `-1`. */
|
1066
|
+
const _SECLEVEL: -1 | 0 | 1 | 2 | 3 | 4
|
1067
|
+
|
1068
|
+
/** Recursively
|
1069
|
+
* [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
|
1070
|
+
* an object and its properties' objects and its properties' objects and so on.
|
1071
|
+
*
|
1072
|
+
* [Official Hackmud Wiki](https://wiki.hackmud.com/scripting/extensions/deep_freeze) */
|
1073
|
+
const DEEP_FREEZE: <T>(value: T) => DeepFreeze<T>
|
1074
|
+
|
1075
|
+
const _RUN_ID: string
|
975
1076
|
}
|
976
1077
|
|
977
|
-
|
978
|
-
*
|
979
|
-
* If `$D()` is called in a script you own, the `return` value of the top level script is suppressed and instead an
|
980
|
-
* array of every `$D()`’d entry is printed.
|
981
|
-
* This lets you use `$D()` like `console.log()`.
|
982
|
-
*
|
983
|
-
* `$D()` in scripts not owned by you are not shown but the `return` value always is.
|
984
|
-
*
|
985
|
-
* `$D()` returns the first argument so `$D("Hello, World!") evaluates to `"Hello, World!"` as if the `$D` text wasn't
|
986
|
-
* there.
|
987
|
-
*
|
988
|
-
* `$D()`’d items are returned even if the script times out or errors. */
|
989
|
-
declare function $D<T>(args: T): T
|
990
|
-
|
991
|
-
/** Function Multi-Call Lock.
|
992
|
-
*
|
993
|
-
* This is used by escrow to ensure that it is only used once in script execution.
|
994
|
-
*
|
995
|
-
* The first time (per-script) `$FMCL` is encountered, it returns `undefined`, every other time it `return`s `true`.
|
996
|
-
*
|
997
|
-
* @example
|
998
|
-
* if ($FMCL)
|
999
|
-
* return { ok: false, msg: "This script can only be used once per script execution." }
|
1000
|
-
*
|
1001
|
-
* // all code here will only run once */
|
1002
|
-
declare const $FMCL: undefined | true
|
1003
|
-
|
1004
|
-
/** Per-script mutable "global" persistent object that is discarded at the end of top level script execution.
|
1005
|
-
*
|
1006
|
-
* `$G` persists between script calls until the end of the main script run making it useful for caching db entries when
|
1007
|
-
* your script is a subscript.
|
1008
|
-
* @example
|
1009
|
-
* if (!$G.dbCache)
|
1010
|
-
* $G.dbCache = $db.f({ whatever: true }).first() */
|
1011
|
-
declare const $G: Record<string | symbol, any>
|
1012
|
-
|
1013
|
-
/** This contains a JS timestamp (not Date) set immediately before your code begins running.
|
1014
|
-
* @example
|
1015
|
-
* $D(Date.now() - _START) // milliseconds left of run time
|
1016
|
-
*/
|
1017
|
-
declare const _START: number
|
1018
|
-
|
1019
|
-
/** This contains a JS timestamp (not Date) set immediately before your code begins running.
|
1020
|
-
* @example
|
1021
|
-
* $D(Date.now() - _ST) // milliseconds left of run time */
|
1022
|
-
declare const _ST: typeof _START
|
1023
|
-
|
1024
|
-
/** JavaScript timestamp for the end of the script run (`_START + _TIMEOUT`). */ declare const _END: number
|
1025
|
-
|
1026
|
-
/** The number of milliseconds a script can run for. Normally `5000` though it has been known to change. */
|
1027
|
-
declare const _TIMEOUT: number
|
1028
|
-
|
1029
|
-
/** The number of milliseconds a script can run for. Normally `5000` though it has been known to change. */
|
1030
|
-
declare const _TO: typeof _TIMEOUT
|
1031
|
-
|
1032
|
-
/** The source code of this script as a string. */ declare const _SOURCE: string
|
1033
|
-
/** A unix timestamp of the date this script was built. */ declare const _BUILD_DATE: number
|
1034
|
-
|
1035
|
-
/** The user this script has been uploaded to.
|
1036
|
-
*
|
1037
|
-
* Shorter alternative to `context.this_script.split(".")[0].
|
1038
|
-
*
|
1039
|
-
* In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
|
1040
|
-
declare const _SCRIPT_USER: string
|
1041
|
-
|
1042
|
-
/** The name of this script excluding the user and `.`.
|
1043
|
-
*
|
1044
|
-
* e.g. in the script `foo.bar`, `_SCRIPT_NAME` is `bar`.
|
1045
|
-
*
|
1046
|
-
* Shorter alternative to `context.this_script.split(".")[1].
|
1047
|
-
*
|
1048
|
-
* In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
|
1049
|
-
declare const _SCRIPT_NAME: string
|
1050
|
-
|
1051
|
-
/** The full name of this script equivilent to `context.this_script` but should use less characters.
|
1052
|
-
*
|
1053
|
-
* In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
|
1054
|
-
declare const _FULL_SCRIPT_NAME: string
|
1055
|
-
|
1056
|
-
/** The seclevel of this script as a number.
|
1057
|
-
*
|
1058
|
-
* In rare cases where it's not known at build time, it's `-1`. */
|
1059
|
-
declare const _SECLEVEL: -1 | 0 | 1 | 2 | 3 | 4
|
1060
|
-
|
1061
|
-
type DeepFreeze<T> = { readonly [P in keyof T]: DeepFreeze<T[P]> }
|
1062
|
-
|
1063
|
-
/** Recursively
|
1064
|
-
* [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
|
1065
|
-
* an object and its properties' objects and its properties' objects and so on.
|
1066
|
-
*
|
1067
|
-
* [Official Hackmud Wiki](https://wiki.hackmud.com/scripting/extensions/deep_freeze) */
|
1068
|
-
declare const DEEP_FREEZE: <T>(value: T) => DeepFreeze<T>
|
1069
|
-
|
1070
|
-
declare const _RUN_ID: string
|
1078
|
+
export {}
|
package/index.js
CHANGED
@@ -46,7 +46,7 @@ import "import-meta-resolve"
|
|
46
46
|
import "./processScript/transform.js"
|
47
47
|
import "@samual/lib/clearObject"
|
48
48
|
import "@samual/lib/copyFilePersistent"
|
49
|
-
import "@samual/lib/
|
49
|
+
import "@samual/lib/AutoMap"
|
50
50
|
import "@samual/lib/writeFilePersistent"
|
51
51
|
import "fs/promises"
|
52
52
|
import "chokidar"
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "hackmud-script-manager",
|
3
|
-
"version": "0.20.4-
|
3
|
+
"version": "0.20.4-a7d8309",
|
4
4
|
"description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
|
5
5
|
"keywords": [
|
6
6
|
"api",
|
@@ -31,50 +31,50 @@
|
|
31
31
|
"url": "https://github.com/samualtnorman/hackmud-script-manager.git"
|
32
32
|
},
|
33
33
|
"dependencies": {
|
34
|
-
"@babel/generator": "^7.
|
35
|
-
"@babel/parser": "^7.
|
36
|
-
"@babel/plugin-proposal-decorators": "^7.
|
37
|
-
"@babel/plugin-proposal-destructuring-private": "^7.
|
38
|
-
"@babel/plugin-proposal-do-expressions": "^7.
|
39
|
-
"@babel/plugin-proposal-explicit-resource-management": "^7.
|
40
|
-
"@babel/plugin-proposal-function-bind": "^7.
|
41
|
-
"@babel/plugin-proposal-function-sent": "^7.
|
42
|
-
"@babel/plugin-proposal-partial-application": "^7.
|
43
|
-
"@babel/plugin-proposal-pipeline-operator": "^7.
|
44
|
-
"@babel/plugin-proposal-record-and-tuple": "^7.
|
45
|
-
"@babel/plugin-proposal-throw-expressions": "^7.
|
46
|
-
"@babel/plugin-transform-class-properties": "^7.
|
47
|
-
"@babel/plugin-transform-class-static-block": "^7.
|
48
|
-
"@babel/plugin-transform-exponentiation-operator": "^7.
|
49
|
-
"@babel/plugin-transform-json-strings": "^7.
|
50
|
-
"@babel/plugin-transform-logical-assignment-operators": "^7.
|
51
|
-
"@babel/plugin-transform-nullish-coalescing-operator": "^7.
|
52
|
-
"@babel/plugin-transform-numeric-separator": "^7.
|
53
|
-
"@babel/plugin-transform-object-rest-spread": "^7.
|
54
|
-
"@babel/plugin-transform-optional-catch-binding": "^7.
|
55
|
-
"@babel/plugin-transform-optional-chaining": "^7.
|
56
|
-
"@babel/plugin-transform-private-property-in-object": "^7.
|
57
|
-
"@babel/plugin-transform-typescript": "^7.
|
58
|
-
"@babel/plugin-transform-unicode-sets-regex": "^7.
|
59
|
-
"@babel/traverse": "^7.
|
60
|
-
"@babel/types": "^7.
|
34
|
+
"@babel/generator": "^7.26.2",
|
35
|
+
"@babel/parser": "^7.26.2",
|
36
|
+
"@babel/plugin-proposal-decorators": "^7.25.9",
|
37
|
+
"@babel/plugin-proposal-destructuring-private": "^7.26.0",
|
38
|
+
"@babel/plugin-proposal-do-expressions": "^7.25.9",
|
39
|
+
"@babel/plugin-proposal-explicit-resource-management": "^7.25.9",
|
40
|
+
"@babel/plugin-proposal-function-bind": "^7.25.9",
|
41
|
+
"@babel/plugin-proposal-function-sent": "^7.25.9",
|
42
|
+
"@babel/plugin-proposal-partial-application": "^7.25.9",
|
43
|
+
"@babel/plugin-proposal-pipeline-operator": "^7.25.9",
|
44
|
+
"@babel/plugin-proposal-record-and-tuple": "^7.25.9",
|
45
|
+
"@babel/plugin-proposal-throw-expressions": "^7.25.9",
|
46
|
+
"@babel/plugin-transform-class-properties": "^7.25.9",
|
47
|
+
"@babel/plugin-transform-class-static-block": "^7.26.0",
|
48
|
+
"@babel/plugin-transform-exponentiation-operator": "^7.25.9",
|
49
|
+
"@babel/plugin-transform-json-strings": "^7.25.9",
|
50
|
+
"@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
|
51
|
+
"@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
|
52
|
+
"@babel/plugin-transform-numeric-separator": "^7.25.9",
|
53
|
+
"@babel/plugin-transform-object-rest-spread": "^7.25.9",
|
54
|
+
"@babel/plugin-transform-optional-catch-binding": "^7.25.9",
|
55
|
+
"@babel/plugin-transform-optional-chaining": "^7.25.9",
|
56
|
+
"@babel/plugin-transform-private-property-in-object": "^7.25.9",
|
57
|
+
"@babel/plugin-transform-typescript": "^7.25.9",
|
58
|
+
"@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
|
59
|
+
"@babel/traverse": "^7.25.9",
|
60
|
+
"@babel/types": "^7.26.0",
|
61
61
|
"@bloomberg/record-tuple-polyfill": "^0.0.4",
|
62
62
|
"@rollup/plugin-babel": "^6.0.4",
|
63
|
-
"@rollup/plugin-commonjs": "^
|
63
|
+
"@rollup/plugin-commonjs": "^28.0.1",
|
64
64
|
"@rollup/plugin-json": "^6.1.0",
|
65
|
-
"@rollup/plugin-node-resolve": "^15.
|
66
|
-
"@samual/lib": "0.
|
67
|
-
"acorn": "^8.
|
65
|
+
"@rollup/plugin-node-resolve": "^15.3.0",
|
66
|
+
"@samual/lib": "^0.13.0",
|
67
|
+
"acorn": "^8.14.0",
|
68
68
|
"chalk": "^5.3.0",
|
69
|
-
"chokidar": "^
|
70
|
-
"import-meta-resolve": "^4.
|
71
|
-
"prettier": "^3.
|
69
|
+
"chokidar": "^4.0.1",
|
70
|
+
"import-meta-resolve": "^4.1.0",
|
71
|
+
"prettier": "^3.3.3",
|
72
72
|
"proxy-polyfill": "^0.3.2",
|
73
|
-
"rollup": "^4.
|
74
|
-
"terser": "^5.
|
73
|
+
"rollup": "^4.27.4",
|
74
|
+
"terser": "^5.36.0"
|
75
75
|
},
|
76
76
|
"peerDependencies": {
|
77
|
-
"typescript": "5.4.5"
|
77
|
+
"typescript": "^5.4.5"
|
78
78
|
},
|
79
79
|
"type": "module",
|
80
80
|
"exports": {
|
@@ -162,21 +162,25 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
162
162
|
if (program.scope.hasGlobal("_SECLEVEL"))
|
163
163
|
for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
|
164
164
|
referencePath.replaceWith(t.numericLiteral(seclevel))
|
165
|
-
let needGetPrototypeOf = !1
|
165
|
+
let needGetPrototypeOf = !1,
|
166
|
+
needHasOwn = !1
|
166
167
|
if (program.scope.hasGlobal("Object"))
|
167
168
|
for (const referencePath of getReferencePathsToGlobal("Object", program))
|
168
169
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
169
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
170
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:242:64")
|
170
171
|
if ("getPrototypeOf" == referencePath.parent.property.name) {
|
171
172
|
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
|
172
173
|
needGetPrototypeOf = !0
|
174
|
+
} else if ("hasOwn" == referencePath.parent.property.name) {
|
175
|
+
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_HAS_OWN_`))
|
176
|
+
needHasOwn = !0
|
173
177
|
}
|
174
178
|
}
|
175
179
|
const consoleMethodsReferenced = new Set()
|
176
180
|
if (program.scope.hasGlobal("console"))
|
177
181
|
for (const referencePath of getReferencePathsToGlobal("console", program))
|
178
182
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
179
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
183
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:260:64")
|
180
184
|
referencePath.parentPath.replaceWith(
|
181
185
|
t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
|
182
186
|
)
|
@@ -184,13 +188,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
184
188
|
}
|
185
189
|
const lastStatement = program.node.body.at(-1)
|
186
190
|
let exportDefaultName
|
187
|
-
assert(lastStatement, "src/processScript/transform.ts:
|
191
|
+
assert(lastStatement, "src/processScript/transform.ts:274:27 program is empty")
|
188
192
|
if ("ExportNamedDeclaration" == lastStatement.type) {
|
189
193
|
program.node.body.pop()
|
190
194
|
for (const specifier of lastStatement.specifiers) {
|
191
195
|
assert(
|
192
196
|
"ExportSpecifier" == specifier.type,
|
193
|
-
`src/processScript/transform.ts:
|
197
|
+
`src/processScript/transform.ts:280:51 ${specifier.type} is currently unsupported`
|
194
198
|
)
|
195
199
|
if (
|
196
200
|
"default" !=
|
@@ -292,11 +296,11 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
292
296
|
let hoistedGlobalBlockFunctions = 0
|
293
297
|
for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
|
294
298
|
if ("VariableDeclaration" == globalBlockStatement.type) {
|
295
|
-
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:
|
299
|
+
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:394:59")
|
296
300
|
const declarator = globalBlockStatement.declarations[0]
|
297
301
|
assert(
|
298
302
|
"Identifier" == declarator.id.type,
|
299
|
-
`src/processScript/transform.ts:
|
303
|
+
`src/processScript/transform.ts:398:51 declarator.id.type was "${declarator.id.type}"`
|
300
304
|
)
|
301
305
|
program.scope.crawl()
|
302
306
|
if (program.scope.hasGlobal(declarator.id.name)) {
|
@@ -311,9 +315,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
311
315
|
Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
|
312
316
|
) {
|
313
317
|
const binding = program.scope.getBinding(declarator.id.name)
|
314
|
-
assert(binding, "src/processScript/transform.ts:
|
318
|
+
assert(binding, "src/processScript/transform.ts:417:23")
|
315
319
|
for (const referencePath of binding.referencePaths) {
|
316
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
320
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:420:56")
|
317
321
|
referencePath.replaceWith(
|
318
322
|
t.memberExpression(
|
319
323
|
t.identifier(`_${uniqueId}_G_`),
|
@@ -361,16 +365,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
361
365
|
} else globalBlockVariables.add(declarator.id.name)
|
362
366
|
} else if ("ClassDeclaration" == globalBlockStatement.type) {
|
363
367
|
program.scope.crawl()
|
364
|
-
assert(globalBlockStatement.id, "src/processScript/transform.ts:
|
368
|
+
assert(globalBlockStatement.id, "src/processScript/transform.ts:477:37")
|
365
369
|
if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
|
366
370
|
globalBlock.body.splice(globalBlockIndex, 1)
|
367
371
|
const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
|
368
372
|
[globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
|
369
373
|
program.scope.crawl()
|
370
374
|
const binding = program.scope.getBinding(globalBlockStatement.id.name)
|
371
|
-
assert(binding, "src/processScript/transform.ts:
|
375
|
+
assert(binding, "src/processScript/transform.ts:489:22")
|
372
376
|
for (const referencePath of binding.referencePaths) {
|
373
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
377
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:492:55")
|
374
378
|
referencePath.replaceWith(
|
375
379
|
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
|
376
380
|
)
|
@@ -448,6 +452,31 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
448
452
|
)
|
449
453
|
])
|
450
454
|
)
|
455
|
+
needHasOwn &&
|
456
|
+
mainFunction.body.body.unshift(
|
457
|
+
t.variableDeclaration("let", [
|
458
|
+
t.variableDeclarator(
|
459
|
+
t.identifier(`_${uniqueId}_HAS_OWN_`),
|
460
|
+
t.callExpression(
|
461
|
+
t.memberExpression(
|
462
|
+
t.memberExpression(
|
463
|
+
t.identifier(
|
464
|
+
globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
|
465
|
+
),
|
466
|
+
t.identifier("call")
|
467
|
+
),
|
468
|
+
t.identifier("bind")
|
469
|
+
),
|
470
|
+
[
|
471
|
+
t.memberExpression(
|
472
|
+
t.memberExpression(t.identifier("Object"), t.identifier("prototype")),
|
473
|
+
t.identifier("hasOwnProperty")
|
474
|
+
)
|
475
|
+
]
|
476
|
+
)
|
477
|
+
)
|
478
|
+
])
|
479
|
+
)
|
451
480
|
consoleMethodsReferenced.size &&
|
452
481
|
mainFunction.body.body.unshift(
|
453
482
|
t.variableDeclaration(
|
@@ -537,7 +566,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
537
566
|
}
|
538
567
|
},
|
539
568
|
ClassBody({ node: classBody, scope, parent }) {
|
540
|
-
assert(t.isClass(parent), "src/processScript/transform.ts:
|
569
|
+
assert(t.isClass(parent), "src/processScript/transform.ts:687:30")
|
541
570
|
let thisIsReferenced = !1
|
542
571
|
for (const classMethod of classBody.body) {
|
543
572
|
if ("ClassMethod" != classMethod.type) continue
|
@@ -637,23 +666,23 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
637
666
|
}
|
638
667
|
function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
|
639
668
|
for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
|
640
|
-
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:
|
669
|
+
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:793:60")
|
641
670
|
assert("Identifier" == referencePath.parent.property.type)
|
642
671
|
assert(
|
643
672
|
"MemberExpression" == referencePath.parentPath.parentPath?.node.type,
|
644
|
-
"src/processScript/transform.ts:
|
673
|
+
"src/processScript/transform.ts:795:81"
|
645
674
|
)
|
646
675
|
assert(
|
647
676
|
"Identifier" == referencePath.parentPath.parentPath.node.property.type,
|
648
|
-
"src/processScript/transform.ts:
|
677
|
+
"src/processScript/transform.ts:796:83"
|
649
678
|
)
|
650
679
|
assert(
|
651
680
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
|
652
|
-
`src/processScript/transform.ts:
|
681
|
+
`src/processScript/transform.ts:800:8 invalid user "${referencePath.parent.property.name}" in subscript`
|
653
682
|
)
|
654
683
|
assert(
|
655
684
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
|
656
|
-
`src/processScript/transform.ts:
|
685
|
+
`src/processScript/transform.ts:805:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
|
657
686
|
)
|
658
687
|
if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
|
659
688
|
referencePath.parentPath.parentPath.replaceWith(
|
package/push.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { AutoMap } from "@samual/lib/AutoMap"
|
2
2
|
import { ensure, assert } from "@samual/lib/assert"
|
3
3
|
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
4
4
|
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
@@ -84,8 +84,8 @@ async function push(
|
|
84
84
|
return new NoUsersError(
|
85
85
|
"Could not find any users. Either provide the names of your users or log into a user in hackmud"
|
86
86
|
)
|
87
|
-
const usersToScriptsToPush = new
|
88
|
-
scriptNamesToUsers = new
|
87
|
+
const usersToScriptsToPush = new AutoMap(_user => new Map()),
|
88
|
+
scriptNamesToUsers = new AutoMap(_scriptName => new Set())
|
89
89
|
for (const script of scripts) {
|
90
90
|
const [user, scriptName] = script.split(".")
|
91
91
|
assert(user, "src/push.ts:105:16")
|
@@ -121,7 +121,7 @@ async function push(
|
|
121
121
|
for (const user of users)
|
122
122
|
if (!usersToScriptsToPush.get(user).has(scriptName))
|
123
123
|
return new NoScriptsError(`Could not find script ${user}.${scriptName} to push`)
|
124
|
-
const pathsToUsers = new
|
124
|
+
const pathsToUsers = new AutoMap(_path => new Set())
|
125
125
|
for (const [user, scriptsToPush] of usersToScriptsToPush)
|
126
126
|
for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
|
127
127
|
const allInfo = []
|
package/watch.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { AutoMap } from "@samual/lib/AutoMap"
|
2
2
|
import { assert } from "@samual/lib/assert"
|
3
3
|
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
4
4
|
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
@@ -60,7 +60,7 @@ async function watch(
|
|
60
60
|
) {
|
61
61
|
if (!scripts.length) throw Error("scripts option was an empty array")
|
62
62
|
if (!(await stat(sourceDirectory)).isDirectory()) throw Error("Target folder must be a folder")
|
63
|
-
const scriptNamesToUsers = new
|
63
|
+
const scriptNamesToUsers = new AutoMap(_scriptName => new Set()),
|
64
64
|
wildScriptUsers = new Set(),
|
65
65
|
wildUserScripts = new Set()
|
66
66
|
let pushEverything = !1
|
@@ -92,7 +92,7 @@ async function watch(
|
|
92
92
|
)
|
93
93
|
)
|
94
94
|
return
|
95
|
-
const scriptNamesToUsersToSkip = new
|
95
|
+
const scriptNamesToUsersToSkip = new AutoMap(_scriptName => [])
|
96
96
|
await Promise.all(
|
97
97
|
(await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name, path }) => {
|
98
98
|
if (stats.isDirectory())
|