hackmud-script-manager 0.19.1-98e81f8 → 0.19.1-bf4dc4a

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.
@@ -111,39 +111,34 @@ const { default: traverse } = babelTraverse,
111
111
  }
112
112
  }
113
113
  let detectedSeclevel = 4
114
- const processFakeSubscriptObject = fakeSubscriptObjectName => {
115
- for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
116
- assert("MemberExpression" == referencePath.parent.type)
117
- assert("Identifier" == referencePath.parent.property.type)
118
- assert("MemberExpression" == referencePath.parentPath.parentPath?.node.type)
119
- assert("Identifier" == referencePath.parentPath.parentPath.node.property.type)
120
- assert(
121
- /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
122
- `invalid user "${referencePath.parent.property.name}" in subscript`
123
- )
124
- assert(
125
- /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
126
- `invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
127
- )
128
- "CallExpression" == referencePath.parentPath.parentPath.parentPath?.type ?
129
- referencePath.parentPath.parentPath.replaceWith(
130
- t.identifier(
131
- `$${uniqueID}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
132
- )
114
+ const neededSubscriptLets = new Set(),
115
+ processFakeSubscriptObject = fakeSubscriptObjectName => {
116
+ for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
117
+ assert("MemberExpression" == referencePath.parent.type)
118
+ assert("Identifier" == referencePath.parent.property.type)
119
+ assert("MemberExpression" == referencePath.parentPath.parentPath?.node.type)
120
+ assert("Identifier" == referencePath.parentPath.parentPath.node.property.type)
121
+ assert(
122
+ /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
123
+ `invalid user "${referencePath.parent.property.name}" in subscript`
133
124
  )
134
- : referencePath.parentPath.parentPath.replaceWith(
135
- t.arrowFunctionExpression(
136
- [t.restElement(t.identifier("args"))],
137
- t.callExpression(
138
- t.identifier(
139
- `$${uniqueID}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
140
- ),
141
- [t.spreadElement(t.identifier("args"))]
125
+ assert(
126
+ /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
127
+ `invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
128
+ )
129
+ if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
130
+ referencePath.parentPath.parentPath.replaceWith(
131
+ t.identifier(
132
+ `$${uniqueID}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
142
133
  )
143
134
  )
144
- )
135
+ else {
136
+ const name = `${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}`
137
+ referencePath.parentPath.parentPath.replaceWith(t.identifier(`_${uniqueID}_SUBSCRIPT_${name}_`))
138
+ neededSubscriptLets.add(name)
139
+ }
140
+ }
145
141
  }
146
- }
147
142
  for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
148
143
  program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName)
149
144
  for (const fakeSubscriptObjectName of ["$hs", "$3s"])
@@ -167,6 +162,7 @@ const { default: traverse } = babelTraverse,
167
162
  processFakeSubscriptObject(fakeSubscriptObjectName)
168
163
  }
169
164
  seclevel = Math.min(seclevel, detectedSeclevel)
165
+ const neededDbMethodLets = new Set()
170
166
  if (program.scope.hasGlobal("$db"))
171
167
  for (const referencePath of getReferencePathsToGlobal("$db", program)) {
172
168
  assert("MemberExpression" == referencePath.parentPath.node.type)
@@ -176,44 +172,24 @@ const { default: traverse } = babelTraverse,
176
172
  validDBMethods.includes(databaseOpMethodName),
177
173
  `invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
178
174
  )
179
- "CallExpression" == referencePath.parentPath.parentPath?.type ?
175
+ if ("CallExpression" == referencePath.parentPath.parentPath?.type)
180
176
  referencePath.parentPath.replaceWith(t.identifier(`$${uniqueID}$DB$${databaseOpMethodName}$`))
181
- : "ObjectId" == databaseOpMethodName ?
182
- referencePath.parentPath.replaceWith(
183
- t.arrowFunctionExpression(
184
- [],
185
- t.callExpression(t.identifier(`$${uniqueID}$DB$${databaseOpMethodName}$`), [])
186
- )
187
- )
188
- : "i" == databaseOpMethodName || "r" == databaseOpMethodName ?
177
+ else {
189
178
  referencePath.parentPath.replaceWith(
190
- t.arrowFunctionExpression(
191
- [t.identifier("a")],
192
- t.callExpression(t.identifier(`$${uniqueID}$DB$${databaseOpMethodName}$`), [
193
- t.identifier("a")
194
- ])
195
- )
196
- )
197
- : referencePath.parentPath.replaceWith(
198
- t.arrowFunctionExpression(
199
- [t.identifier("a"), t.identifier("b")],
200
- t.callExpression(t.identifier(`$${uniqueID}$DB$${databaseOpMethodName}$`), [
201
- t.identifier("a"),
202
- t.identifier("b")
203
- ])
204
- )
179
+ t.identifier(`_${uniqueID}_CONSOLE_METHOD_${databaseOpMethodName}_`)
205
180
  )
181
+ neededDbMethodLets.add(databaseOpMethodName)
182
+ }
206
183
  }
184
+ let needDebugLet = !1
207
185
  if (program.scope.hasGlobal("$D"))
208
186
  for (const referencePath of getReferencePathsToGlobal("$D", program))
209
- "CallExpression" == referencePath.parentPath.type ?
187
+ if ("CallExpression" == referencePath.parentPath.type)
210
188
  referencePath.replaceWith(t.identifier(`$${uniqueID}$DEBUG$`))
211
- : referencePath.replaceWith(
212
- t.arrowFunctionExpression(
213
- [t.identifier("a")],
214
- t.callExpression(t.identifier(`$${uniqueID}$DEBUG$`), [t.identifier("a")])
215
- )
216
- )
189
+ else {
190
+ referencePath.replaceWith(t.identifier(`_${uniqueID}_DEBUG_`))
191
+ needDebugLet = !0
192
+ }
217
193
  if (program.scope.hasGlobal("$FMCL"))
218
194
  for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
219
195
  referencePath.replaceWith(t.identifier(`$${uniqueID}$FMCL$`))
@@ -223,8 +199,7 @@ const { default: traverse } = babelTraverse,
223
199
  if (program.scope.hasGlobal("_SECLEVEL"))
224
200
  for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
225
201
  referencePath.replaceWith(t.numericLiteral(seclevel))
226
- let needGetPrototypeOf = !1,
227
- needSetPrototypeOf = !1
202
+ let needGetPrototypeOf = !1
228
203
  if (program.scope.hasGlobal("Object"))
229
204
  for (const referencePath of getReferencePathsToGlobal("Object", program))
230
205
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
@@ -232,11 +207,18 @@ const { default: traverse } = babelTraverse,
232
207
  if ("getPrototypeOf" == referencePath.parent.property.name) {
233
208
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueID}_GET_PROTOTYPE_OF_`))
234
209
  needGetPrototypeOf = !0
235
- } else if ("setPrototypeOf" == referencePath.parent.property.name) {
236
- referencePath.parentPath.replaceWith(t.identifier(`_${uniqueID}_SET_PROTOTYPE_OF_`))
237
- needSetPrototypeOf = !0
238
210
  }
239
211
  }
212
+ const consoleMethodsReferenced = new Set()
213
+ if (program.scope.hasGlobal("console"))
214
+ for (const referencePath of getReferencePathsToGlobal("console", program))
215
+ if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
216
+ assert("Identifier" == referencePath.parent.property.type)
217
+ referencePath.parentPath.replaceWith(
218
+ t.identifier(`_${uniqueID}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
219
+ )
220
+ consoleMethodsReferenced.add(referencePath.parent.property.name)
221
+ }
240
222
  const lastStatement = program.node.body.at(-1)
241
223
  let exportDefaultName
242
224
  assert(lastStatement, "program is empty")
@@ -410,7 +392,7 @@ const { default: traverse } = babelTraverse,
410
392
  } else globalBlockVariables.add(declarator.id.name)
411
393
  } else if ("ClassDeclaration" == globalBlockStatement.type) {
412
394
  program.scope.crawl()
413
- assert(globalBlockStatement.id, "src/processScript/transform.ts:564:37")
395
+ assert(globalBlockStatement.id, "src/processScript/transform.ts:544:37")
414
396
  if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
415
397
  globalBlock.body.splice(globalBlockIndex, 1)
416
398
  const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
@@ -471,29 +453,31 @@ const { default: traverse } = babelTraverse,
471
453
  )
472
454
  ])
473
455
  )
474
- needSetPrototypeOf &&
456
+ needGetPrototypeOf &&
475
457
  mainFunction.body.body.unshift(
476
458
  t.variableDeclaration("let", [
477
459
  t.variableDeclarator(
478
- t.identifier(`_${uniqueID}_SET_PROTOTYPE_OF_`),
460
+ t.objectPattern([
461
+ t.objectProperty(t.identifier("get"), t.identifier(`_${uniqueID}_DUNDER_PROTO_GETTER_`))
462
+ ]),
479
463
  t.callExpression(
480
- t.memberExpression(
481
- t.memberExpression(t.identifier("Object"), t.identifier("call")),
482
- t.identifier("bind")
483
- ),
484
- [t.identifier(`_${uniqueID}_DUNDER_PROTO_SETTER_`)]
464
+ t.memberExpression(t.identifier("Object"), t.identifier("getOwnPropertyDescriptor")),
465
+ [
466
+ t.memberExpression(t.identifier("Object"), t.identifier("prototype")),
467
+ t.stringLiteral("__proto__")
468
+ ]
485
469
  )
486
- )
487
- ])
488
- )
489
- needGetPrototypeOf &&
490
- mainFunction.body.body.unshift(
491
- t.variableDeclaration("let", [
470
+ ),
492
471
  t.variableDeclarator(
493
472
  t.identifier(`_${uniqueID}_GET_PROTOTYPE_OF_`),
494
473
  t.callExpression(
495
474
  t.memberExpression(
496
- t.memberExpression(t.identifier("Object"), t.identifier("call")),
475
+ t.memberExpression(
476
+ t.identifier(
477
+ globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
478
+ ),
479
+ t.identifier("call")
480
+ ),
497
481
  t.identifier("bind")
498
482
  ),
499
483
  [t.identifier(`_${uniqueID}_DUNDER_PROTO_GETTER_`)]
@@ -501,41 +485,69 @@ const { default: traverse } = babelTraverse,
501
485
  )
502
486
  ])
503
487
  )
504
- ;(needGetPrototypeOf || needSetPrototypeOf) &&
488
+ consoleMethodsReferenced.size &&
489
+ mainFunction.body.body.unshift(
490
+ t.variableDeclaration(
491
+ "let",
492
+ [...consoleMethodsReferenced].map(name =>
493
+ t.variableDeclarator(
494
+ t.identifier(`_${uniqueID}_CONSOLE_METHOD_${name}_`),
495
+ t.arrowFunctionExpression(
496
+ [t.restElement(t.identifier("args"))],
497
+ t.unaryExpression(
498
+ "void",
499
+ t.callExpression(t.identifier(`$${uniqueID}$DEBUG$`), [t.identifier("args")])
500
+ )
501
+ )
502
+ )
503
+ )
504
+ )
505
+ )
506
+ neededDbMethodLets.size &&
507
+ mainFunction.body.body.unshift(
508
+ t.variableDeclaration(
509
+ "let",
510
+ [...neededDbMethodLets].map(name => {
511
+ const getArgs = () =>
512
+ "ObjectId" == name ? []
513
+ : "i" == name || "r" == name ? [t.identifier("a")]
514
+ : [t.identifier("a"), t.identifier("b")]
515
+ return t.variableDeclarator(
516
+ t.identifier(`_${uniqueID}_CONSOLE_METHOD_${name}_`),
517
+ t.arrowFunctionExpression(
518
+ getArgs(),
519
+ t.callExpression(t.identifier(`$${uniqueID}$DB$${name}$`), getArgs())
520
+ )
521
+ )
522
+ })
523
+ )
524
+ )
525
+ needDebugLet &&
505
526
  mainFunction.body.body.unshift(
506
527
  t.variableDeclaration("let", [
507
528
  t.variableDeclarator(
508
- t.objectPattern(
509
- needGetPrototypeOf ?
510
- needSetPrototypeOf ?
511
- [
512
- t.objectProperty(
513
- t.identifier("get"),
514
- t.identifier(`_${uniqueID}_DUNDER_PROTO_GETTER_`)
515
- ),
516
- t.objectProperty(
517
- t.identifier("set"),
518
- t.identifier(`_${uniqueID}_DUNDER_PROTO_SETTER_`)
519
- )
520
- ]
521
- : [
522
- t.objectProperty(
523
- t.identifier("get"),
524
- t.identifier(`_${uniqueID}_DUNDER_PROTO_GETTER_`)
525
- )
526
- ]
527
- : [t.objectProperty(t.identifier("set"), t.identifier(`_${uniqueID}_DUNDER_PROTO_SETTER_`))]
528
- ),
529
- t.callExpression(
530
- t.memberExpression(t.identifier("Object"), t.identifier("getOwnPropertyDescriptor")),
531
- [
532
- t.memberExpression(t.identifier("Object"), t.identifier("prototype")),
533
- t.stringLiteral("__proto__")
534
- ]
535
- )
529
+ t.identifier(`_${uniqueID}_DEBUG_`),
530
+ t.callExpression(t.identifier(`$${uniqueID}$DEBUG$`), [t.identifier("a")])
536
531
  )
537
532
  ])
538
533
  )
534
+ neededSubscriptLets.size &&
535
+ mainFunction.body.body.unshift(
536
+ t.variableDeclaration(
537
+ "let",
538
+ [...neededSubscriptLets].map(name =>
539
+ t.variableDeclarator(
540
+ t.identifier(`_${uniqueID}_SUBSCRIPT_${name}_`),
541
+ t.arrowFunctionExpression(
542
+ [t.restElement(t.identifier("args"))],
543
+ t.callExpression(t.identifier(`$${uniqueID}$SUBSCRIPT$${name}$`), [
544
+ t.spreadElement(t.identifier("args"))
545
+ ])
546
+ )
547
+ )
548
+ )
549
+ )
550
+ )
539
551
  traverse(file, {
540
552
  BlockStatement({ node: blockStatement }) {
541
553
  for (const [index, functionDeclaration] of blockStatement.body.entries())
package/push.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { Cache } from "@samual/lib/Cache"
2
2
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
3
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
3
4
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
4
- import { readdir, readFile } from "fs/promises"
5
- import { resolve, extname, basename } from "path"
5
+ import { readFile } from "fs/promises"
6
+ import { basename, resolve, extname } from "path"
6
7
  import { supportedExtensions } from "./constants.js"
7
8
  import { processScript } from "./processScript/index.js"
8
9
  import "@babel/generator"
@@ -64,18 +65,20 @@ const push = async (
64
65
  scriptNamesAlreadyPushedByUser = new Cache(_user => new Set())
65
66
  let sourceDirectoryDirents
66
67
  if (wildUserScripts.size || pushEverything) {
67
- const hackmudDirectoryDirents = await readdir(resolve(hackmudDirectory), { withFileTypes: !0 }),
68
- allUsers = new Set([
69
- ...(sourceDirectoryDirents = await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))
70
- .filter(dirent => dirent.isDirectory())
71
- .map(dirent => dirent.name),
72
- ...hackmudDirectoryDirents.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name),
73
- ...hackmudDirectoryDirents
74
- .filter(dirent => dirent.isFile() && dirent.name.endsWith(".key"))
75
- .map(dirent => dirent.name.slice(0, -4)),
76
- ...scriptNamesByUser.keys(),
77
- ...wildScriptUsers
78
- ])
68
+ let hackmudDirectoryEntries
69
+ ;[hackmudDirectoryEntries, sourceDirectoryDirents] = await Promise.all([
70
+ readDirectoryWithStats(hackmudDirectory),
71
+ readDirectoryWithStats(sourceDirectory)
72
+ ])
73
+ const allUsers = new Set([
74
+ ...sourceDirectoryDirents.filter(({ stats }) => stats.isDirectory()).map(({ path }) => basename(path)),
75
+ ...hackmudDirectoryEntries.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
76
+ ...hackmudDirectoryEntries
77
+ .filter(({ name, stats }) => stats.isFile() && name.endsWith(".key"))
78
+ .map(({ name }) => name.slice(0, -4)),
79
+ ...scriptNamesByUser.keys(),
80
+ ...wildScriptUsers
81
+ ])
79
82
  if (pushEverything) for (const user of allUsers) wildScriptUsers.add(user)
80
83
  else
81
84
  for (const user of allUsers) {
@@ -85,28 +88,27 @@ const push = async (
85
88
  }
86
89
  await Promise.all(
87
90
  [...wildScriptUsers].map(async user => {
88
- await readdir(resolve(sourceDirectory, user), { withFileTypes: !0 }).then(
89
- async dirents => {
91
+ await readDirectoryWithStats(resolve(sourceDirectory, user)).then(
92
+ async entries => {
90
93
  await Promise.all(
91
- dirents.map(async dirent => {
92
- if (dirent.name.endsWith(".d.ts")) return
93
- const extension = extname(dirent.name)
94
- if (dirent.isFile() && supportedExtensions.includes(extension)) {
95
- const scriptName = basename(dirent.name, extension),
96
- filePath = resolve(sourceDirectory, user, dirent.name),
94
+ entries.map(async ({ stats, name, path }) => {
95
+ if (name.endsWith(".d.ts")) return
96
+ const extension = extname(name)
97
+ if (stats.isFile() && supportedExtensions.includes(extension)) {
98
+ const scriptName = basename(name, extension),
97
99
  { script: minifiedCode } = await processScript(
98
- await readFile(filePath, { encoding: "utf-8" }),
100
+ await readFile(path, { encoding: "utf-8" }),
99
101
  {
100
102
  minify,
101
103
  scriptUser: user,
102
104
  scriptName,
103
- filePath,
105
+ filePath: path,
104
106
  mangleNames,
105
107
  forceQuineCheats
106
108
  }
107
109
  ),
108
110
  info = {
109
- file: `${user}/${dirent.name}`,
111
+ file: `${user}/${name}`,
110
112
  users: [user],
111
113
  minLength: countHackmudCharacters(minifiedCode),
112
114
  error: void 0
@@ -170,12 +172,12 @@ const push = async (
170
172
  )
171
173
  await (wildScriptUsers.size ?
172
174
  Promise.all(
173
- (sourceDirectoryDirents || (await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))).map(
174
- async dirent => {
175
- if (dirent.name.endsWith(".d.ts")) return
176
- const extension = extname(dirent.name)
177
- if (!dirent.isFile() || !supportedExtensions.includes(extension)) return
178
- const scriptName = basename(dirent.name, extension),
175
+ (sourceDirectoryDirents || (await readDirectoryWithStats(sourceDirectory))).map(
176
+ async ({ path, stats, name }) => {
177
+ if (name.endsWith(".d.ts")) return
178
+ const extension = extname(name)
179
+ if (!stats.isFile() || !supportedExtensions.includes(extension)) return
180
+ const scriptName = basename(name, extension),
179
181
  usersToPushTo = [...wildScriptUsers, ...usersByGlobalScriptsToPush.get(scriptName)].filter(
180
182
  user => !scriptNamesAlreadyPushedByUser.get(user).has(scriptName)
181
183
  )
@@ -183,13 +185,17 @@ const push = async (
183
185
  const uniqueID = Math.floor(Math.random() * 2 ** 52)
184
186
  .toString(36)
185
187
  .padStart(11, "0"),
186
- filePath = resolve(sourceDirectory, dirent.name),
187
- { script: minifiedCode } = await processScript(
188
- await readFile(filePath, { encoding: "utf-8" }),
189
- { minify, scriptUser: !0, scriptName, uniqueID, filePath, mangleNames, forceQuineCheats }
190
- ),
188
+ { script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf-8" }), {
189
+ minify,
190
+ scriptUser: !0,
191
+ scriptName,
192
+ uniqueID,
193
+ filePath: path,
194
+ mangleNames,
195
+ forceQuineCheats
196
+ }),
191
197
  info = {
192
- file: dirent.name,
198
+ file: name,
193
199
  users: usersToPushTo,
194
200
  minLength: countHackmudCharacters(minifiedCode),
195
201
  error: void 0
package/syncMacros.js CHANGED
@@ -1,12 +1,13 @@
1
- import { readdir, readFile, stat, writeFile } from "fs/promises"
1
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
2
+ import { readFile, stat, writeFile } from "fs/promises"
2
3
  import { extname, basename, resolve } from "path"
3
4
  const syncMacros = async hackmudPath => {
4
- const files = await readdir(hackmudPath, { withFileTypes: !0 }),
5
+ const files = await readDirectoryWithStats(hackmudPath),
5
6
  macros = new Map(),
6
7
  users = []
7
8
  await Promise.all(
8
9
  files.map(async file => {
9
- if (file.isFile())
10
+ if (file.stats.isFile())
10
11
  switch (extname(file.name)) {
11
12
  case ".macros":
12
13
  {