hackmud-script-manager 0.20.4-03d5600 → 0.20.4-0dd1d9b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,6 +20,10 @@ You can read about how HSM works [in my blog post](https://samual.uk/blog/js-cod
20
20
  > ```
21
21
  > You will need to run `Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser` in PowerShell as an administrator. For more information, see [Microsoft's page about Execution Policies](https://learn.microsoft.com/en-gb/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4).
22
22
 
23
+ ![image](https://github.com/samualtnorman/hackmud-script-manager/assets/18307063/69a371fe-f8c8-43fe-b3c7-39f3735ce6fb)
24
+ ![image](https://github.com/samualtnorman/hackmud-script-manager/assets/18307063/08103f9e-74fa-4a56-a739-94858ba8c139)
25
+ ![image](https://github.com/samualtnorman/hackmud-script-manager/assets/18307063/25ccb86d-1fe3-4632-b703-ac47f5b32c9c)
26
+
23
27
  ## Features
24
28
  - Minification
25
29
  - This includes auto quine cheating.
package/bin/hsm.js CHANGED
@@ -13,7 +13,8 @@ import { syncMacros } from "../syncMacros.js"
13
13
  import "@samual/lib/readDirectoryWithStats"
14
14
  import "path/posix"
15
15
  import "@samual/lib/copyFilePersistent"
16
- const version = "0.20.4-03d5600",
16
+ const version = "0.20.4-0dd1d9b",
17
+ formatOption = name => colourN(`-${1 == name.length ? "" : "-"}${name}`),
17
18
  options = new Map(),
18
19
  commands = [],
19
20
  userColours = new Cache(user => {
@@ -46,6 +47,7 @@ const pushModule = import("../push.js"),
46
47
  colourB = chalk.rgb(202, 202, 202),
47
48
  colourC = chalk.rgb(155, 155, 155),
48
49
  colourD = chalk.rgb(255, 0, 0),
50
+ colourF = chalk.rgb(255, 128, 0),
49
51
  colourJ = chalk.rgb(255, 244, 4),
50
52
  colourK = chalk.rgb(243, 249, 152),
51
53
  colourL = chalk.rgb(30, 255, 0),
@@ -54,6 +56,12 @@ const pushModule = import("../push.js"),
54
56
  colourS = chalk.rgb(122, 178, 244),
55
57
  colourV = chalk.rgb(255, 0, 236),
56
58
  colourW = chalk.rgb(255, 150, 224)
59
+ process.version.startsWith("v21.") &&
60
+ console.warn(
61
+ colourF(
62
+ "Warning: Support for Node.js 21 will be dropped in the next minor version of HSM\n You should update your version of Node.js\n https://nodejs.org/en/download/package-manager"
63
+ )
64
+ )
57
65
  if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
58
66
  console.log(version)
59
67
  process.exit()
@@ -76,7 +84,7 @@ switch (commands[0]) {
76
84
  noMinifyIncompatibleOption = mangleNamesOption || forceQuineCheatsOption
77
85
  if (noMinifyOption && noMinifyIncompatibleOption) {
78
86
  logError(
79
- `Options ${colourN(noMinifyOption.name)} and ${colourN(noMinifyIncompatibleOption.name)} are incompatible\n`
87
+ `Options ${formatOption(noMinifyOption.name)} and ${formatOption(noMinifyIncompatibleOption.name)} are incompatible\n`
80
88
  )
81
89
  logHelp()
82
90
  process.exit(1)
@@ -99,6 +107,7 @@ switch (commands[0]) {
99
107
  )
100
108
  process.exit(1)
101
109
  }
110
+ complainAboutUnrecognisedOptions()
102
111
  const { processScript } = await processScriptModule,
103
112
  fileBaseName = basename(target, fileExtension),
104
113
  fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(".src"),
@@ -171,15 +180,15 @@ switch (commands[0]) {
171
180
  }
172
181
  } else scripts.push("*.*")
173
182
  if ("push" == commands[0]) {
174
- const { push, MissingSourceFolderError, MissingHackmudFolderError, NoUsersError } =
175
- await pushModule,
176
- infos = await push(sourcePath, hackmudPath, {
177
- scripts,
178
- onPush: info => logInfo(info, hackmudPath),
179
- minify: noMinifyOption && !noMinifyOption.value,
180
- mangleNames: mangleNamesOption?.value,
181
- forceQuineCheats: forceQuineCheatsOption?.value
182
- })
183
+ const { push, MissingSourceFolderError, MissingHackmudFolderError, NoUsersError } = await pushModule
184
+ complainAboutUnrecognisedOptions()
185
+ const infos = await push(sourcePath, hackmudPath, {
186
+ scripts,
187
+ onPush: info => logInfo(info, hackmudPath),
188
+ minify: noMinifyOption && !noMinifyOption.value,
189
+ mangleNames: mangleNamesOption?.value,
190
+ forceQuineCheats: forceQuineCheatsOption?.value
191
+ })
183
192
  if (infos instanceof Error) {
184
193
  logError(infos.message)
185
194
  if (infos instanceof MissingSourceFolderError || infos instanceof NoUsersError) {
@@ -193,12 +202,13 @@ switch (commands[0]) {
193
202
  } else infos.length || logError("Could not find any scripts to push")
194
203
  } else {
195
204
  const typeDeclarationPathOption = popOption(
196
- "type-declaration-path",
197
- "type-declaration",
198
- "dts",
199
- "gen-types"
200
- ),
201
- { watch } = await watchModule
205
+ "type-declaration-path",
206
+ "type-declaration",
207
+ "dts",
208
+ "gen-types"
209
+ )
210
+ complainAboutUnrecognisedOptions()
211
+ const { watch } = await watchModule
202
212
  watch(sourcePath, hackmudPath, {
203
213
  scripts,
204
214
  onPush: info => logInfo(info, hackmudPath),
@@ -222,6 +232,7 @@ switch (commands[0]) {
222
232
  logHelp()
223
233
  process.exit(1)
224
234
  }
235
+ complainAboutUnrecognisedOptions()
225
236
  const sourcePath = commands[2] || "."
226
237
  await pull(sourcePath, hackmudPath, script).catch(error => {
227
238
  console.error(error)
@@ -231,8 +242,9 @@ switch (commands[0]) {
231
242
  break
232
243
  case "sync-macros":
233
244
  {
234
- const hackmudPath = getHackmudPath(),
235
- { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
245
+ const hackmudPath = getHackmudPath()
246
+ complainAboutUnrecognisedOptions()
247
+ const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
236
248
  log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
237
249
  }
238
250
  break
@@ -248,12 +260,13 @@ switch (commands[0]) {
248
260
  logHelp()
249
261
  process.exit(1)
250
262
  }
263
+ complainAboutUnrecognisedOptions()
251
264
  const sourcePath = resolve(target),
252
265
  outputPath = commands[2] || "./player.d.ts",
253
266
  typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
254
267
  let typeDeclarationPath = resolve(outputPath)
255
268
  await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
256
- assert(error instanceof Error, "src/bin/hsm.ts:321:35")
269
+ assert(error instanceof Error, "src/bin/hsm.ts:343:35")
257
270
  if ("EISDIR" != error.code) throw error
258
271
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
259
272
  return writeFile(typeDeclarationPath, typeDeclaration)
@@ -352,7 +365,7 @@ function getHackmudPath() {
352
365
  }
353
366
  function assertOptionIsBoolean(option) {
354
367
  if ("boolean" != typeof option.value) {
355
- logError(`The value for ${colourN(option.name)} must be ${colourV("true")} or ${colourV("false")}\n`)
368
+ logError(`The value for ${formatOption(option.name)} must be ${colourV("true")} or ${colourV("false")}\n`)
356
369
  logHelp()
357
370
  process.exit(1)
358
371
  }
@@ -360,9 +373,7 @@ function assertOptionIsBoolean(option) {
360
373
  function popOption(...names) {
361
374
  const presentOptionNames = names.filter(name => options.has(name))
362
375
  if (!presentOptionNames.length) return
363
- const presentOptionNamesWithDashDash = presentOptionNames.map(name =>
364
- colourN(`-${1 == name.length ? "" : "-"}${name}`)
365
- )
376
+ const presentOptionNamesWithDashDash = presentOptionNames.map(formatOption)
366
377
  if (presentOptionNames.length > 1) {
367
378
  logError(
368
379
  `The options ${presentOptionNamesWithDashDash.join(", ")} are aliases for each other. Please only specify one`
@@ -373,3 +384,11 @@ function popOption(...names) {
373
384
  options.delete(presentOptionNames[0])
374
385
  return { name: presentOptionNamesWithDashDash[0], value }
375
386
  }
387
+ function complainAboutUnrecognisedOptions() {
388
+ if (options.size) {
389
+ logError(
390
+ `Unrecognised option${options.size > 1 ? "s" : ""}: ${[...options.keys()].map(formatOption).join(", ")}`
391
+ )
392
+ process.exit(1)
393
+ }
394
+ }
package/env.d.ts CHANGED
@@ -3,13 +3,7 @@ type ScriptSuccess<T = object> = { ok: true } & T
3
3
  type ScriptFailure = { ok: false, msg?: string }
4
4
  type ScriptResponse<T = object> = ScriptSuccess<T> | ScriptFailure
5
5
  type ErrorScripts = Record<string, () => ScriptFailure>
6
-
7
- type AllOptional<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? true : false }[keyof T]
8
-
9
- type Scriptor<Args = unknown, Ret = unknown> = {
10
- name: string
11
- call: AllOptional<Args> extends true ? (args?: Args) => Ret : (args: Args) => Ret
12
- }
6
+ type Scriptor<TArgs extends any[] = any[]> = { name: string, call: (...args: TArgs) => unknown }
13
7
 
14
8
  type Subscripts = Record<string, Record<string, (...args: any) => any>> & {
15
9
  accts: ErrorScripts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.20.4-03d5600",
3
+ "version": "0.20.4-0dd1d9b",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -204,6 +204,7 @@ async function processScript(
204
204
  const bundle = await rollup({
205
205
  input: filePathResolved,
206
206
  plugins: [
207
+ rollupPluginJSON({ preferConst: !0 }),
207
208
  {
208
209
  name: "hackmud-script-manager",
209
210
  async transform(code, id) {
@@ -227,8 +228,7 @@ async function processScript(
227
228
  },
228
229
  babel({ babelHelpers: "bundled", plugins, configFile: !1, extensions: supportedExtensions }),
229
230
  rollupPluginCommonJS(),
230
- rollupPluginNodeResolve({ extensions: supportedExtensions }),
231
- rollupPluginJSON()
231
+ rollupPluginNodeResolve({ extensions: supportedExtensions })
232
232
  ],
233
233
  treeshake: { moduleSideEffects: !1 }
234
234
  }),
@@ -98,8 +98,10 @@ async function preprocess(code, { uniqueId = "00000000000" } = {}) {
98
98
  t.stringLiteral(resolve("proxy-polyfill/src/proxy.js", import.meta.url).slice(7))
99
99
  )
100
100
  )
101
- return 1 == program.node.body.length && "FunctionDeclaration" == program.node.body[0].type ?
102
- { code: "export default " + generate(file).code }
103
- : { code: generate(file).code }
101
+ if (1 == program.node.body.length && "FunctionDeclaration" == program.node.body[0].type)
102
+ throw Error(
103
+ "Scripts that only contain a single function declaration are no longer supported.\nPrefix the function declaration with `export default`."
104
+ )
105
+ return { code: generate(file).code }
104
106
  }
105
107
  export { preprocess }
@@ -22,9 +22,7 @@ const { default: traverse } = babelTraverse,
22
22
  "BigInt"
23
23
  ]
24
24
  function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scriptName, seclevel = 4 }) {
25
- const topFunctionName = `_${uniqueId}_SCRIPT_`,
26
- exports = new Map(),
27
- liveExports = new Map()
25
+ const topFunctionName = `_${uniqueId}_SCRIPT_`
28
26
  let program
29
27
  traverse(file, {
30
28
  Program(path) {
@@ -70,30 +68,30 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
70
68
  const referencePath = FunctionReferencePaths[0]
71
69
  assert(
72
70
  "MemberExpression" == referencePath.parent.type,
73
- "src/processScript/transform.ts:105:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
71
+ "src/processScript/transform.ts:103:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
74
72
  )
75
73
  assert(
76
74
  "Identifier" == referencePath.parent.property.type,
77
- "src/processScript/transform.ts:110:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
75
+ "src/processScript/transform.ts:108:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
78
76
  )
79
77
  assert(
80
78
  "prototype" == referencePath.parent.property.name,
81
- "src/processScript/transform.ts:115:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
79
+ "src/processScript/transform.ts:113:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
82
80
  )
83
81
  referencePath.parentPath.replaceWith(createGetFunctionPrototypeNode())
84
82
  } else {
85
83
  for (const referencePath of FunctionReferencePaths) {
86
84
  assert(
87
85
  "MemberExpression" == referencePath.parent.type,
88
- "src/processScript/transform.ts:123:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
86
+ "src/processScript/transform.ts:121:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
89
87
  )
90
88
  assert(
91
89
  "Identifier" == referencePath.parent.property.type,
92
- "src/processScript/transform.ts:128:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
90
+ "src/processScript/transform.ts:126:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
93
91
  )
94
92
  assert(
95
93
  "prototype" == referencePath.parent.property.name,
96
- "src/processScript/transform.ts:133:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
94
+ "src/processScript/transform.ts:131:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
97
95
  )
98
96
  functionDotPrototypeIsReferencedMultipleTimes = !0
99
97
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_FUNCTION_DOT_PROTOTYPE_`))
@@ -129,12 +127,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
129
127
  const neededDbMethodLets = new Set()
130
128
  if (program.scope.hasGlobal("$db"))
131
129
  for (const referencePath of getReferencePathsToGlobal("$db", program)) {
132
- assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:187:69")
133
- assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:188:72")
130
+ assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:185:69")
131
+ assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:186:72")
134
132
  const databaseOpMethodName = referencePath.parentPath.node.property.name
135
133
  assert(
136
134
  validDBMethods.includes(databaseOpMethodName),
137
- `src/processScript/transform.ts:194:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
135
+ `src/processScript/transform.ts:192:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
138
136
  )
139
137
  if ("CallExpression" == referencePath.parentPath.parentPath?.type)
140
138
  referencePath.parentPath.replaceWith(t.identifier(`$${uniqueId}$DB$${databaseOpMethodName}$`))
@@ -168,7 +166,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
168
166
  if (program.scope.hasGlobal("Object"))
169
167
  for (const referencePath of getReferencePathsToGlobal("Object", program))
170
168
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
171
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:243:64")
169
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:241:64")
172
170
  if ("getPrototypeOf" == referencePath.parent.property.name) {
173
171
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
174
172
  needGetPrototypeOf = !0
@@ -178,7 +176,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
178
176
  if (program.scope.hasGlobal("console"))
179
177
  for (const referencePath of getReferencePathsToGlobal("console", program))
180
178
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
181
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:258:64")
179
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:256:64")
182
180
  referencePath.parentPath.replaceWith(
183
181
  t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
184
182
  )
@@ -186,19 +184,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
186
184
  }
187
185
  const lastStatement = program.node.body.at(-1)
188
186
  let exportDefaultName
189
- assert(lastStatement, "src/processScript/transform.ts:272:27 program is empty")
187
+ assert(lastStatement, "src/processScript/transform.ts:270:27 program is empty")
190
188
  if ("ExportNamedDeclaration" == lastStatement.type) {
191
189
  program.node.body.pop()
192
190
  for (const specifier of lastStatement.specifiers) {
193
191
  assert(
194
192
  "ExportSpecifier" == specifier.type,
195
- `src/processScript/transform.ts:278:51 ${specifier.type} is currently unsupported`
193
+ `src/processScript/transform.ts:276:51 ${specifier.type} is currently unsupported`
196
194
  )
197
- const exportedName =
198
- "Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value
199
- "default" == exportedName ?
200
- (exportDefaultName = specifier.local.name)
201
- : exports.set(specifier.local.name, exportedName)
195
+ if (
196
+ "default" !=
197
+ ("Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value)
198
+ )
199
+ throw Error("Only default exports are supported")
200
+ exportDefaultName = specifier.local.name
202
201
  }
203
202
  }
204
203
  const globalBlock = t.blockStatement([])
@@ -224,10 +223,6 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
224
223
  t.returnStatement(t.callExpression(t.identifier(exportDefaultName), []))
225
224
  ])
226
225
  ))
227
- if ("const" != statement.kind && exports.has(identifierName)) {
228
- liveExports.set(identifierName, exports.get(identifierName))
229
- exports.delete(identifierName)
230
- }
231
226
  globalBlock.body.push(
232
227
  t.variableDeclaration("let", [t.variableDeclarator(t.identifier(identifierName))])
233
228
  )
@@ -292,34 +287,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
292
287
  }
293
288
  program.node.body = [mainFunction]
294
289
  if (globalBlock.body.length) {
295
- ;(exports.size || liveExports.size) &&
296
- mainFunction.body.body.push(
297
- t.returnStatement(
298
- t.objectExpression([
299
- ...[...exports].map(([local, exported]) =>
300
- t.objectProperty(t.identifier(exported), t.identifier(local))
301
- ),
302
- ...[...liveExports].map(([local, exported]) =>
303
- t.objectMethod(
304
- "get",
305
- t.identifier(exported),
306
- [],
307
- t.blockStatement([t.returnStatement(t.identifier(local))])
308
- )
309
- )
310
- ])
311
- )
312
- )
313
290
  program.scope.crawl()
314
291
  const globalBlockVariables = new Set()
315
292
  let hoistedGlobalBlockFunctions = 0
316
293
  for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
317
294
  if ("VariableDeclaration" == globalBlockStatement.type) {
318
- assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:412:59")
295
+ assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:390:59")
319
296
  const declarator = globalBlockStatement.declarations[0]
320
297
  assert(
321
298
  "Identifier" == declarator.id.type,
322
- `src/processScript/transform.ts:416:51 declarator.id.type was "${declarator.id.type}"`
299
+ `src/processScript/transform.ts:394:51 declarator.id.type was "${declarator.id.type}"`
323
300
  )
324
301
  program.scope.crawl()
325
302
  if (program.scope.hasGlobal(declarator.id.name)) {
@@ -334,9 +311,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
334
311
  Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
335
312
  ) {
336
313
  const binding = program.scope.getBinding(declarator.id.name)
337
- assert(binding, "src/processScript/transform.ts:435:23")
314
+ assert(binding, "src/processScript/transform.ts:413:23")
338
315
  for (const referencePath of binding.referencePaths) {
339
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:438:56")
316
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:416:56")
340
317
  referencePath.replaceWith(
341
318
  t.memberExpression(
342
319
  t.identifier(`_${uniqueId}_G_`),
@@ -384,16 +361,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
384
361
  } else globalBlockVariables.add(declarator.id.name)
385
362
  } else if ("ClassDeclaration" == globalBlockStatement.type) {
386
363
  program.scope.crawl()
387
- assert(globalBlockStatement.id, "src/processScript/transform.ts:495:37")
364
+ assert(globalBlockStatement.id, "src/processScript/transform.ts:473:37")
388
365
  if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
389
366
  globalBlock.body.splice(globalBlockIndex, 1)
390
367
  const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
391
368
  [globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
392
369
  program.scope.crawl()
393
370
  const binding = program.scope.getBinding(globalBlockStatement.id.name)
394
- assert(binding, "src/processScript/transform.ts:507:22")
371
+ assert(binding, "src/processScript/transform.ts:485:22")
395
372
  for (const referencePath of binding.referencePaths) {
396
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:510:55")
373
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:488:55")
397
374
  referencePath.replaceWith(
398
375
  t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
399
376
  )
@@ -423,11 +400,6 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
423
400
  needG = !0
424
401
  }
425
402
  }
426
- if (program.scope.hasGlobal("_EXPORTS"))
427
- for (const referencePath of getReferencePathsToGlobal("_EXPORTS", program))
428
- referencePath.replaceWith(
429
- t.arrayExpression([...exports.keys(), ...liveExports.keys()].map(name => t.stringLiteral(name)))
430
- )
431
403
  globalBlock.body.length &&
432
404
  mainFunction.body.body.splice(
433
405
  hoistedGlobalBlockFunctions,
@@ -565,7 +537,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
565
537
  }
566
538
  },
567
539
  ClassBody({ node: classBody, scope, parent }) {
568
- assert(t.isClass(parent), "src/processScript/transform.ts:688:30")
540
+ assert(t.isClass(parent), "src/processScript/transform.ts:658:30")
569
541
  let thisIsReferenced = !1
570
542
  for (const classMethod of classBody.body) {
571
543
  if ("ClassMethod" != classMethod.type) continue
@@ -657,39 +629,31 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
657
629
  })
658
630
  return { file, seclevel }
659
631
  function createGetFunctionPrototypeNode() {
660
- for (const globalFunction of globalFunctionsUnder7Characters)
661
- if (!program.scope.hasOwnBinding(globalFunction))
662
- return t.memberExpression(
663
- t.memberExpression(t.identifier(globalFunction), t.identifier("constructor")),
664
- t.identifier("prototype")
665
- )
632
+ const name = globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
666
633
  return t.memberExpression(
667
- t.memberExpression(
668
- t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
669
- t.identifier("constructor")
670
- ),
671
- t.identifier("prototype")
634
+ name ? t.identifier(name) : t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
635
+ t.identifier("__proto__")
672
636
  )
673
637
  }
674
638
  function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
675
639
  for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
676
- assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:804:60")
640
+ assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:764:60")
677
641
  assert("Identifier" == referencePath.parent.property.type)
678
642
  assert(
679
643
  "MemberExpression" == referencePath.parentPath.parentPath?.node.type,
680
- "src/processScript/transform.ts:806:81"
644
+ "src/processScript/transform.ts:766:81"
681
645
  )
682
646
  assert(
683
647
  "Identifier" == referencePath.parentPath.parentPath.node.property.type,
684
- "src/processScript/transform.ts:807:83"
648
+ "src/processScript/transform.ts:767:83"
685
649
  )
686
650
  assert(
687
651
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
688
- `src/processScript/transform.ts:811:8 invalid user "${referencePath.parent.property.name}" in subscript`
652
+ `src/processScript/transform.ts:771:8 invalid user "${referencePath.parent.property.name}" in subscript`
689
653
  )
690
654
  assert(
691
655
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
692
- `src/processScript/transform.ts:816:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
656
+ `src/processScript/transform.ts:776:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
693
657
  )
694
658
  if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
695
659
  referencePath.parentPath.parentPath.replaceWith(
package/watch.js CHANGED
@@ -4,7 +4,7 @@ import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
4
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
5
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
6
6
  import { watch as watch$1 } from "chokidar"
7
- import { readFile, writeFile } from "fs/promises"
7
+ import { stat, readFile, writeFile } from "fs/promises"
8
8
  import { extname, basename, resolve } from "path"
9
9
  import { supportedExtensions } from "./constants.js"
10
10
  import { generateTypeDeclaration } from "./generateTypeDeclaration.js"
@@ -59,6 +59,7 @@ async function watch(
59
59
  } = {}
60
60
  ) {
61
61
  if (!scripts.length) throw Error("scripts option was an empty array")
62
+ if (!(await stat(sourceDirectory)).isDirectory()) throw Error("Target folder must be a folder")
62
63
  const scriptNamesToUsers = new Cache(_scriptName => new Set()),
63
64
  wildScriptUsers = new Set(),
64
65
  wildUserScripts = new Set()
@@ -136,7 +137,7 @@ async function watch(
136
137
  forceQuineCheats
137
138
  }))
138
139
  } catch (error) {
139
- assert(error instanceof Error, "src/watch.ts:141:36")
140
+ assert(error instanceof Error, "src/watch.ts:146:36")
140
141
  onPush?.({ path, users: [], characterCount: 0, error })
141
142
  return
142
143
  }
@@ -181,7 +182,7 @@ async function watch(
181
182
  forceQuineCheats
182
183
  }))
183
184
  } catch (error) {
184
- assert(error instanceof Error, "src/watch.ts:177:35")
185
+ assert(error instanceof Error, "src/watch.ts:182:35")
185
186
  onPush?.({ path, users: [], characterCount: 0, error })
186
187
  return
187
188
  }
@@ -196,7 +197,7 @@ async function watch(
196
197
  try {
197
198
  await writeFile(typeDeclarationPath, typeDeclaration)
198
199
  } catch (error) {
199
- assert(error instanceof Error, "src/watch.ts:210:35")
200
+ assert(error instanceof Error, "src/watch.ts:215:35")
200
201
  if ("EISDIR" != error.code) throw error
201
202
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
202
203
  await writeFile(typeDeclarationPath, typeDeclaration)