hackmud-script-manager 0.21.1-583d190 → 0.21.1-8e6657c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ You can read about how HSM works [in my blog post](https://samual.uk/blog/js-cod
12
12
  ## Usage
13
13
  1. Run `#dir` in game, then `cd` to that folder
14
14
  2. Name your source script file to `<name>.src.js`
15
- 3. Run `hsm golf <name>.src.js` and it will create a minified script file called `<name>.js`
15
+ 3. Run `hsm minify <name>.src.js` and it will create a minified script file called `<name>.js`
16
16
 
17
17
  > **NOTE:** If you get an error message that looks like this:
18
18
  > ```
package/bin/hsm.js CHANGED
@@ -62,7 +62,7 @@ process.version.startsWith("v21.") &&
62
62
  )
63
63
  )
64
64
  if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
65
- console.log("0.21.1-583d190")
65
+ console.log("0.21.1-8e6657c")
66
66
  process.exit()
67
67
  }
68
68
  let warnedDeprecatedEmitDtsAlias = !1
@@ -131,19 +131,19 @@ switch (commands[0]) {
131
131
  fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
132
132
  scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName,
133
133
  scriptUser =
134
- (
135
- "scripts" == basename(resolve(target, "..")) &&
136
- "hackmud" == basename(resolve(target, "../../.."))
137
- ) ?
138
- basename(resolve(target, "../.."))
139
- : void 0
134
+ "scripts" == basename(resolve(target, "..")) &&
135
+ "hackmud" == basename(resolve(target, "../../.."))
136
+ ? basename(resolve(target, "../.."))
137
+ : void 0
140
138
  let outputPath =
141
139
  commands[2] ||
142
140
  resolve(
143
141
  dirname(target),
144
- fileBaseNameEndsWithDotSrc ? scriptName + ".js"
145
- : ".js" == fileExtension ? fileBaseName + ".min.js"
146
- : fileBaseName + ".js"
142
+ fileBaseNameEndsWithDotSrc
143
+ ? scriptName + ".js"
144
+ : ".js" == fileExtension
145
+ ? fileBaseName + ".min.js"
146
+ : fileBaseName + ".js"
147
147
  )
148
148
  const golfFile = () =>
149
149
  readFile(target, { encoding: "utf8" }).then(async source => {
@@ -403,7 +403,7 @@ function logHelp() {
403
403
  default:
404
404
  console.log(
405
405
  colourS(
406
- `${colourJ("Hackmud Script Manager")}\n${colourN("Version") + colourS(": ") + colourV("0.21.1-583d190")}\n\n${colourA("Commands:")}\n${colourL("push")}\n ${pushCommandDescription}\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`
406
+ `${colourJ("Hackmud Script Manager")}\n${colourN("Version") + colourS(": ") + colourV("0.21.1-8e6657c")}\n\n${colourA("Commands:")}\n${colourL("push")}\n ${pushCommandDescription}\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`
407
407
  )
408
408
  )
409
409
  }
@@ -13,9 +13,9 @@ async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
13
13
  await Promise.all(
14
14
  (await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name }) => {
15
15
  if (stats.isFile())
16
- name.endsWith(".ts") ?
17
- name.endsWith(".d.ts") || wildScripts.push(basename(name, ".ts"))
18
- : name.endsWith(".js") && wildAnyScripts.push(basename(name, ".js"))
16
+ name.endsWith(".ts")
17
+ ? name.endsWith(".d.ts") || wildScripts.push(basename(name, ".ts"))
18
+ : name.endsWith(".js") && wildAnyScripts.push(basename(name, ".js"))
19
19
  else if (stats.isDirectory()) {
20
20
  const scripts = [],
21
21
  anyScripts = []
@@ -24,9 +24,9 @@ async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
24
24
  users.add(name)
25
25
  for (const child of await readDirectoryWithStats(resolve(sourceDirectory, name)))
26
26
  child.stats.isFile() &&
27
- (child.name.endsWith(".ts") ?
28
- name.endsWith(".d.ts") || scripts.push(basename(child.name, ".ts"))
29
- : child.name.endsWith(".js") && anyScripts.push(basename(child.name, ".js")))
27
+ (child.name.endsWith(".ts")
28
+ ? name.endsWith(".d.ts") || scripts.push(basename(child.name, ".ts"))
29
+ : child.name.endsWith(".js") && anyScripts.push(basename(child.name, ".js")))
30
30
  }
31
31
  })
32
32
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.21.1-583d190",
3
+ "version": "0.21.1-8e6657c",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -221,10 +221,10 @@ async function processScript(
221
221
  for (const referencePath of getReferencePathsToGlobal("JSON", program))
222
222
  "MemberExpression" == referencePath.parentPath.node.type &&
223
223
  "Identifier" == referencePath.parentPath.node.property.type &&
224
- ("parse" == referencePath.parentPath.node.property.name ?
225
- (referencePath.parentPath.node.property.name = "oparse")
226
- : "stringify" == referencePath.parentPath.node.property.name &&
227
- (referencePath.parentPath.node.property.name = "ostringify"))
224
+ ("parse" == referencePath.parentPath.node.property.name
225
+ ? (referencePath.parentPath.node.property.name = "oparse")
226
+ : "stringify" == referencePath.parentPath.node.property.name &&
227
+ (referencePath.parentPath.node.property.name = "ostringify"))
228
228
  return generate(program.node).code
229
229
  }
230
230
  },
@@ -359,12 +359,9 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
359
359
  }
360
360
  if (1 == forceQuineCheats) return code
361
361
  assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:485:43")
362
- return (
363
- countHackmudCharacters(scriptBeforeJSONValueReplacement) <=
364
- countHackmudCharacters(code) + Number(hasComment)
365
- ) ?
366
- scriptBeforeJSONValueReplacement
367
- : code
362
+ return countHackmudCharacters(scriptBeforeJSONValueReplacement) <= countHackmudCharacters(code) + Number(hasComment)
363
+ ? scriptBeforeJSONValueReplacement
364
+ : code
368
365
  }
369
366
  function parseObjectExpression(node, o) {
370
367
  if (!node.properties.length) return !1
@@ -2,97 +2,169 @@ import babelGenerator from "@babel/generator"
2
2
  import { parse } from "@babel/parser"
3
3
  import babelTraverse from "@babel/traverse"
4
4
  import t from "@babel/types"
5
- import { assert } from "@samual/lib/assert"
5
+ import { assert, ensure } from "@samual/lib/assert"
6
6
  import { spliceString } from "@samual/lib/spliceString"
7
+ import { tokenizer, tokTypes } from "acorn"
7
8
  import { resolve } from "import-meta-resolve"
9
+ import { validDBMethods } from "../constants.js"
8
10
  const { default: traverse } = babelTraverse,
9
- { default: generate } = babelGenerator
11
+ { default: generate } = babelGenerator,
12
+ SUBSCRIPT_PREFIXES = ["s", "fs", "4s", "hs", "3s", "ms", "2s", "ls", "1s", "ns", "0s"],
13
+ PREPROCESSOR_NAMES = [...SUBSCRIPT_PREFIXES, "D", "G", "FMCL", "db"]
10
14
  async function preprocess(code, { uniqueId = "00000000000" } = {}) {
11
- assert(/^\w{11}$/.test(uniqueId), "src/processScript/preprocess.ts:23:36")
12
- const sourceCode = code
13
- let lengthBefore, file, program
14
- do {
15
- lengthBefore = code.length
16
- code = code
17
- .replace(/^\s+/, "")
18
- .replace(/^\/\/.*/, "")
19
- .replace(/^\/\*[\s\S]*?\*\//, "")
20
- } while (code.length != lengthBefore)
21
- code = code.replace(/^function\s*\(/, "export default function (")
22
- for (;;) {
23
- let error
24
- try {
25
- file = parse(code, {
26
- plugins: [
27
- "typescript",
28
- ["decorators", { decoratorsBeforeExport: !0 }],
29
- "doExpressions",
30
- "functionBind",
31
- "functionSent",
32
- "partialApplication",
33
- ["pipelineOperator", { proposal: "hack", topicToken: "%" }],
34
- "throwExpressions",
35
- ["recordAndTuple", { syntaxType: "hash" }],
36
- "classProperties",
37
- "classPrivateProperties",
38
- "classPrivateMethods",
39
- "logicalAssignment",
40
- "numericSeparator",
41
- "nullishCoalescingOperator",
42
- "optionalChaining",
43
- "optionalCatchBinding",
44
- "objectRestSpread"
45
- ],
46
- sourceType: "module"
47
- })
48
- break
49
- } catch (error_) {
50
- assert(error_ instanceof SyntaxError, "src/processScript/preprocess.ts:67:42")
51
- error = error_
52
- }
53
- if ("BABEL_PARSER_SYNTAX_ERROR" != error.code || "PrivateInExpectedIn" != error.reasonCode) {
54
- console.log(/.+/.exec(code.slice(error.pos))?.[0])
55
- throw error
56
- }
57
- const codeSlice = code.slice(error.pos)
58
- let match
59
- if ((match = /^#[0-4fhmln]s\.scripts\.quine\(\)/.exec(codeSlice)))
60
- code = spliceString(code, JSON.stringify(sourceCode), error.pos, match[0].length)
61
- else if ((match = /^#[0-4fhmln]?s\./.exec(codeSlice))) code = spliceString(code, "$", error.pos, 1)
62
- else if ((match = /^#D[^\w$]/.exec(codeSlice))) code = spliceString(code, "$", error.pos, 1)
63
- else if ((match = /^#FMCL/.exec(codeSlice)))
64
- code = spliceString(code, `$${uniqueId}$FMCL$`, error.pos, match[0].length)
65
- else if ((match = /^#G/.exec(codeSlice)))
66
- code = spliceString(code, `$${uniqueId}$GLOBAL$`, error.pos, match[0].length)
67
- else {
68
- if (!(match = /^#db\./.exec(codeSlice))) throw error
69
- code = spliceString(code, "$", error.pos, 1)
15
+ assert(/^\w{11}$/.test(uniqueId), "src/processScript/preprocess.ts:28:36")
16
+ const sourceCode = code,
17
+ tokens = [...tokenizer(code, { ecmaVersion: "latest" })],
18
+ needExportDefault =
19
+ ensure(tokens[0], "src/processScript/preprocess.ts:34:21").type == tokTypes._function &&
20
+ ensure(tokens[1], "src/processScript/preprocess.ts:34:77").type == tokTypes.parenL,
21
+ maybePrivatePrefix = `$${uniqueId}$MAYBE_PRIVATE$`
22
+ for (const token of [...tokens].reverse()) {
23
+ assert("value" in token, "src/processScript/preprocess.ts:39:28")
24
+ if (token.type == tokTypes.privateId) {
25
+ assert("string" == typeof token.value, "src/processScript/preprocess.ts:42:43")
26
+ PREPROCESSOR_NAMES.includes(token.value) &&
27
+ (code = spliceString(code, maybePrivatePrefix + token.value, token.start, token.end - token.start))
70
28
  }
71
29
  }
72
- traverse(file, {
73
- Program(path) {
74
- program = path
75
- path.skip()
30
+ needExportDefault && (code = "export default " + code)
31
+ let program
32
+ traverse(
33
+ parse(code, {
34
+ plugins: [
35
+ "typescript",
36
+ ["decorators", { decoratorsBeforeExport: !0 }],
37
+ "doExpressions",
38
+ "functionBind",
39
+ "functionSent",
40
+ "partialApplication",
41
+ ["pipelineOperator", { proposal: "hack", topicToken: "%" }],
42
+ "throwExpressions",
43
+ ["recordAndTuple", { syntaxType: "hash" }],
44
+ "classProperties",
45
+ "classPrivateProperties",
46
+ "classPrivateMethods",
47
+ "logicalAssignment",
48
+ "numericSeparator",
49
+ "nullishCoalescingOperator",
50
+ "optionalChaining",
51
+ "optionalCatchBinding",
52
+ "objectRestSpread"
53
+ ],
54
+ sourceType: "module"
55
+ }),
56
+ {
57
+ Program(path) {
58
+ program = path
59
+ },
60
+ Identifier(path) {
61
+ if (!path.node.name.startsWith(maybePrivatePrefix)) return
62
+ const name = path.node.name.slice(maybePrivatePrefix.length)
63
+ if ("ClassProperty" == path.parent.type && path.parent.key == path.node)
64
+ path.parentPath.replaceWith(
65
+ t.classPrivateProperty(
66
+ t.privateName(t.identifier(name)),
67
+ path.parent.value,
68
+ path.parent.decorators,
69
+ path.parent.static
70
+ )
71
+ )
72
+ else if ("MemberExpression" == path.parent.type)
73
+ if (path.parent.property == path.node) {
74
+ assert(!path.parent.computed, "src/processScript/preprocess.ts:95:36")
75
+ path.replaceWith(t.privateName(t.identifier(name)))
76
+ } else {
77
+ assert(path.parent.object == path.node, "src/processScript/preprocess.ts:98:46")
78
+ if ("db" == name) {
79
+ if (path.parent.computed)
80
+ throw Error(
81
+ "Index notation cannot be used on #db, must be in the form of #db.<DB method name>"
82
+ )
83
+ if ("Identifier" != path.parent.property.type)
84
+ throw Error(
85
+ `Expected DB method name to be an Identifier, got ${path.parent.property.type} instead`
86
+ )
87
+ if (!validDBMethods.includes(path.parent.property.name))
88
+ throw Error("Invalid DB method #db." + path.parent.property.name)
89
+ path.node.name = "$db"
90
+ } else {
91
+ assert(SUBSCRIPT_PREFIXES.includes(name), "src/processScript/preprocess.ts:112:49")
92
+ if (path.parent.computed)
93
+ throw Error(
94
+ `Index notation cannot be used for subscripts, must be in the form of #${name}.foo.bar`
95
+ )
96
+ if ("Identifier" != path.parent.property.type)
97
+ throw Error(
98
+ `Expected subscript user name to be Identifier but got ${path.parent.property.type} instead`
99
+ )
100
+ if ("MemberExpression" != path.parentPath.parent.type)
101
+ throw Error(`Subscripts must be in the form of #${name}.foo.bar`)
102
+ if (path.parentPath.parent.computed)
103
+ throw Error(
104
+ `Index notation cannot be used for subscripts, must be in the form of #${name}.foo.bar`
105
+ )
106
+ if ("Identifier" != path.parentPath.parent.property.type)
107
+ throw Error(
108
+ `Expected subscript subname to be Identifier but got ${path.parent.property.type} instead`
109
+ )
110
+ "CallExpression" == path.parentPath.parentPath?.parent.type &&
111
+ "scripts" == path.parent.property.name &&
112
+ "quine" == path.parentPath.parent.property.name
113
+ ? ensure(
114
+ path.parentPath.parentPath.parentPath,
115
+ "src/processScript/preprocess.ts:134:54"
116
+ ).replaceWith(t.stringLiteral(sourceCode))
117
+ : (path.node.name = "$" + name)
118
+ }
119
+ }
120
+ else if (
121
+ "BinaryExpression" == path.parent.type &&
122
+ path.parent.left == path.node &&
123
+ "in" == path.parent.operator
124
+ )
125
+ path.replaceWith(t.privateName(t.identifier(name)))
126
+ else if ("ClassMethod" == path.parent.type && path.parent.key == path.node) {
127
+ assert("constructor" != path.parent.kind, "src/processScript/preprocess.ts:142:47")
128
+ path.parentPath.replaceWith(
129
+ t.classPrivateMethod(
130
+ path.parent.kind,
131
+ t.privateName(t.identifier(name)),
132
+ path.parent.params,
133
+ path.parent.body,
134
+ path.parent.static
135
+ )
136
+ )
137
+ } else if ("FMCL" == name) path.node.name = `$${uniqueId}$FMCL$`
138
+ else if ("G" == name) path.node.name = `$${uniqueId}$GLOBAL$`
139
+ else {
140
+ if ("D" != name) {
141
+ if ("db" == name) throw Error("Invalid #db syntax, must be in the form of #db.<DB method name>")
142
+ assert(SUBSCRIPT_PREFIXES.includes(name), "src/processScript/preprocess.ts:161:51 " + name)
143
+ throw Error(`Invalid subscript syntax, must be in the form of #${name}.foo.bar`)
144
+ }
145
+ path.node.name = "$D"
146
+ }
147
+ }
76
148
  }
77
- })
149
+ )
78
150
  const needRecord = program.scope.hasGlobal("Record"),
79
151
  needTuple = program.scope.hasGlobal("Tuple")
80
152
  ;(needRecord || needTuple) &&
81
- file.program.body.unshift(
153
+ program.node.body.unshift(
82
154
  t.importDeclaration(
83
- needRecord ?
84
- needTuple ?
85
- [
86
- t.importSpecifier(t.identifier("Record"), t.identifier("Record")),
87
- t.importSpecifier(t.identifier("Tuple"), t.identifier("Tuple"))
88
- ]
89
- : [t.importSpecifier(t.identifier("Record"), t.identifier("Record"))]
90
- : [t.importSpecifier(t.identifier("Tuple"), t.identifier("Tuple"))],
155
+ needRecord
156
+ ? needTuple
157
+ ? [
158
+ t.importSpecifier(t.identifier("Record"), t.identifier("Record")),
159
+ t.importSpecifier(t.identifier("Tuple"), t.identifier("Tuple"))
160
+ ]
161
+ : [t.importSpecifier(t.identifier("Record"), t.identifier("Record"))]
162
+ : [t.importSpecifier(t.identifier("Tuple"), t.identifier("Tuple"))],
91
163
  t.stringLiteral("@bloomberg/record-tuple-polyfill")
92
164
  )
93
165
  )
94
166
  program.scope.hasGlobal("Proxy") &&
95
- file.program.body.unshift(
167
+ program.node.body.unshift(
96
168
  t.importDeclaration(
97
169
  [t.importDefaultSpecifier(t.identifier("Proxy"))],
98
170
  t.stringLiteral(resolve("proxy-polyfill/src/proxy.js", import.meta.url).slice(7))
@@ -102,6 +174,6 @@ async function preprocess(code, { uniqueId = "00000000000" } = {}) {
102
174
  throw Error(
103
175
  "Scripts that only contain a single function declaration are no longer supported.\nPrefix the function declaration with `export default`."
104
176
  )
105
- return { code: generate(file).code }
177
+ return { code: generate(program.node).code }
106
178
  }
107
179
  export { preprocess }
@@ -253,29 +253,29 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
253
253
  mainFunction = t.functionDeclaration(
254
254
  t.identifier(topFunctionName),
255
255
  declarator.init.params,
256
- "BlockStatement" == declarator.init.body.type ?
257
- declarator.init.body
258
- : t.blockStatement([t.returnStatement(declarator.init.body)])
256
+ "BlockStatement" == declarator.init.body.type
257
+ ? declarator.init.body
258
+ : t.blockStatement([t.returnStatement(declarator.init.body)])
259
259
  )
260
260
  else
261
- "FunctionDeclaration" == statement.type ?
262
- statement.id.name == exportDefaultName ?
263
- (mainFunction = statement)
264
- : globalBlock.body.push(
265
- t.variableDeclaration("let", [
266
- t.variableDeclarator(
267
- statement.id,
268
- t.functionExpression(
269
- void 0,
270
- statement.params,
271
- statement.body,
272
- statement.generator,
273
- statement.async
261
+ "FunctionDeclaration" == statement.type
262
+ ? statement.id.name == exportDefaultName
263
+ ? (mainFunction = statement)
264
+ : globalBlock.body.push(
265
+ t.variableDeclaration("let", [
266
+ t.variableDeclarator(
267
+ statement.id,
268
+ t.functionExpression(
269
+ void 0,
270
+ statement.params,
271
+ statement.body,
272
+ statement.generator,
273
+ statement.async
274
+ )
274
275
  )
275
- )
276
- ])
277
- )
278
- : globalBlock.body.push(statement)
276
+ ])
277
+ )
278
+ : globalBlock.body.push(statement)
279
279
  mainFunction ||= t.functionDeclaration(
280
280
  t.identifier(topFunctionName),
281
281
  [t.identifier("context"), t.identifier("args")],
@@ -515,9 +515,11 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
515
515
  "let",
516
516
  [...neededDbMethodLets].map(name => {
517
517
  const getArgs = () =>
518
- "ObjectId" == name ? []
519
- : "i" == name || "r" == name ? [t.identifier("a")]
520
- : [t.identifier("a"), t.identifier("b")]
518
+ "ObjectId" == name
519
+ ? []
520
+ : "i" == name || "r" == name
521
+ ? [t.identifier("a")]
522
+ : [t.identifier("a"), t.identifier("b")]
521
523
  return t.variableDeclarator(
522
524
  t.identifier(`_${uniqueId}_CONSOLE_METHOD_${name}_`),
523
525
  t.arrowFunctionExpression(
@@ -663,9 +665,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
663
665
  const bigIntAsNumber = Number(path.node.value)
664
666
  path.replaceWith(
665
667
  t.callExpression(t.identifier("BigInt"), [
666
- BigInt(bigIntAsNumber) == BigInt(path.node.value) ?
667
- t.numericLiteral(bigIntAsNumber)
668
- : t.stringLiteral(path.node.value)
668
+ BigInt(bigIntAsNumber) == BigInt(path.node.value)
669
+ ? t.numericLiteral(bigIntAsNumber)
670
+ : t.stringLiteral(path.node.value)
669
671
  ])
670
672
  )
671
673
  }
package/watch.js CHANGED
@@ -68,12 +68,13 @@ async function watch(
68
68
  let pushEverything = !1
69
69
  for (const fullScriptName of scripts) {
70
70
  const [user, scriptName] = fullScriptName.split(".")
71
- user && "*" != user ?
72
- scriptName && "*" != scriptName ?
73
- scriptNamesToUsers.get(scriptName).add(user)
74
- : wildScriptUsers.add(user)
75
- : scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
76
- : (pushEverything = !0)
71
+ user && "*" != user
72
+ ? scriptName && "*" != scriptName
73
+ ? scriptNamesToUsers.get(scriptName).add(user)
74
+ : wildScriptUsers.add(user)
75
+ : scriptName && "*" != scriptName
76
+ ? wildUserScripts.add(scriptName)
77
+ : (pushEverything = !0)
77
78
  }
78
79
  const watcher = watch$1(".", {
79
80
  cwd: sourceDirectory,
@@ -112,9 +113,9 @@ async function watch(
112
113
  for (const { stats, name } of await readDirectoryWithStats(sourceDirectory))
113
114
  stats.isDirectory() && usersToPushToSet.add(name)
114
115
  for (const { stats, name } of await readDirectoryWithStats(hackmudDirectory))
115
- stats.isDirectory() ?
116
- usersToPushToSet.add(name)
117
- : stats.isFile() && name.endsWith(".key") && usersToPushToSet.add(name.slice(0, -4))
116
+ stats.isDirectory()
117
+ ? usersToPushToSet.add(name)
118
+ : stats.isFile() && name.endsWith(".key") && usersToPushToSet.add(name.slice(0, -4))
118
119
  for (const users of scriptNamesToUsers.values()) for (const user of users) usersToPushToSet.add(user)
119
120
  }
120
121
  for (const user of wildScriptUsers) usersToPushToSet.add(user)