hackmud-script-manager 0.20.4-1d688c1 → 0.20.4-2a608c4

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,9 +20,9 @@ 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)
23
+ ![image](https://github.com/user-attachments/assets/cc97f8a6-82a4-4a66-9785-accc8d774285)
24
+ ![image](https://github.com/user-attachments/assets/d0ec9450-4e16-4f8d-82b2-734deaf5abe3)
25
+ ![image](https://github.com/user-attachments/assets/a59a6ec4-d268-40f7-8ce2-5fbdbcd40c19)
26
26
 
27
27
  ## Features
28
28
  - Minification
@@ -54,10 +54,9 @@ You can read about how HSM works [in my blog post](https://samual.uk/blog/js-cod
54
54
  - `_BUILD_DATE` is replaced with a unix timestamp (`Date.now()`) of the build date of the script.
55
55
  - `_SCRIPT_USER` is replaced with a string of the user the script was pushed to.
56
56
  - This saves characters compared to `context.this_script.split(".")[0]`.
57
- - `_SCRIPT_NAME` is like `_SCRIPT_USER` but for the name of the script.
57
+ - `_SCRIPT_SUBNAME` is like `_SCRIPT_USER` but for the name of the script.
58
58
  - Saves characters compared to `context.this_script.split(".")[1]`.
59
- - `_FULL_SCRIPT_NAME` is replaced with what would be `context.this_script`.
60
- - `#s.` can be used and it'll automatically have the seclevel inserted.
59
+ - `_FULL_SCRIPT_NAME` is replaced with what would be in `context.this_script`.
61
60
  - Subscript and `#db` methods names are verified.
62
61
  - All references to preprocessor syntax functions not being called are turned into arrow function wrappers e.g. `let debug = #D;` -> `let debug = v => #D(v);`.
63
62
  - `_SECLEVEL` is replaced with a number (`0` to `4`) representing the seclevel of the script.
package/bin/hsm.js CHANGED
@@ -58,11 +58,11 @@ const pushModule = import("../push.js"),
58
58
  process.version.startsWith("v21.") &&
59
59
  console.warn(
60
60
  colourF(
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`
61
+ `${chalk.bold("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`
62
62
  )
63
63
  )
64
64
  if ("v" == commands[0] || "version" == commands[0] || popOption("version", "v")?.value) {
65
- console.log("0.20.4-1d688c1")
65
+ console.log("0.20.4-2a608c4")
66
66
  process.exit()
67
67
  }
68
68
  let warnedDeprecatedEmitDtsAlias = !1
@@ -83,7 +83,7 @@ switch (commands[0]) {
83
83
  "no-minify" != noMinifyOption.name &&
84
84
  console.warn(
85
85
  colourF(
86
- `Warning: ${formatOption(noMinifyOption.name)} is being deprecated and will be removed in the next minor\n release of HSM\n You should switch to using its alias ${colourN("--no-minify")}\n`
86
+ `${chalk.bold("Warning:")} ${formatOption(noMinifyOption.name)} is deprecated and will be removed in the next minor\n release of HSM\n You should switch to using its alias ${colourN("--no-minify")}\n`
87
87
  )
88
88
  )
89
89
  const mangleNamesOption = popOption("mangle-names"),
@@ -108,6 +108,8 @@ switch (commands[0]) {
108
108
  mangleNamesOption && assertOptionIsBoolean(mangleNamesOption)
109
109
  forceQuineCheatsOption && assertOptionIsBoolean(forceQuineCheatsOption)
110
110
  noQuineCheatsOptions && assertOptionIsBoolean(noQuineCheatsOptions)
111
+ const rootFolderPathOption = popOption("root-folder-path"),
112
+ rootFolderPath = rootFolderPathOption && resolve(rootFolderPathOption.value + "")
111
113
  if ("golf" == commands[0] || "minify" == commands[0]) {
112
114
  const watchOption = popOption("watch"),
113
115
  target = commands[1]
@@ -152,11 +154,12 @@ switch (commands[0]) {
152
154
  scriptName,
153
155
  filePath: target,
154
156
  mangleNames: mangleNamesOption?.value,
155
- forceQuineCheats: forceQuineCheatsOption?.value ?? !noQuineCheatsOptions?.value
157
+ forceQuineCheats: forceQuineCheatsOption?.value ?? !noQuineCheatsOptions?.value,
158
+ rootFolderPath
156
159
  }),
157
160
  timeTook = performance.now() - timeStart
158
- for (const { message, line } of warnings)
159
- log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
161
+ for (const { message } of warnings)
162
+ console.warn(colourF(`${chalk.bold("Warning:")} ${message}`))
160
163
  await writeFilePersistent(outputPath, script)
161
164
  .catch(error => {
162
165
  if (!commands[2] || "EISDIR" != error.code) throw error
@@ -209,7 +212,7 @@ switch (commands[0]) {
209
212
  "type-declaration-path" != dtsPathOption.name &&
210
213
  console.warn(
211
214
  colourF(
212
- `Warning: ${formatOption(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`
215
+ `${chalk.bold("Warning:")} ${formatOption(dtsPathOption.name)} is 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`
213
216
  )
214
217
  )
215
218
  complainAboutUnrecognisedOptions()
@@ -221,7 +224,8 @@ switch (commands[0]) {
221
224
  minify: noMinifyOption && !noMinifyOption.value,
222
225
  mangleNames: mangleNamesOption?.value,
223
226
  onReady: () => log("Watching"),
224
- forceQuineCheats: forceQuineCheatsOption?.value ?? !noQuineCheatsOptions?.value
227
+ forceQuineCheats: forceQuineCheatsOption?.value ?? !noQuineCheatsOptions?.value,
228
+ rootFolderPath
225
229
  })
226
230
  autoExit = !1
227
231
  } else {
@@ -240,7 +244,7 @@ switch (commands[0]) {
240
244
  const typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
241
245
  declarationPathPromise = writeFile(typeDeclarationPath, typeDeclaration)
242
246
  .catch(error => {
243
- assert(error instanceof Error, "src/bin/hsm.ts:288:38")
247
+ assert(error instanceof Error, "src/bin/hsm.ts:292:38")
244
248
  if ("EISDIR" != error.code) throw error
245
249
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
246
250
  return writeFile(typeDeclarationPath, typeDeclaration)
@@ -254,7 +258,8 @@ switch (commands[0]) {
254
258
  onPush: info => logInfo(info, hackmudPath),
255
259
  minify: noMinifyOption && !noMinifyOption.value,
256
260
  mangleNames: mangleNamesOption?.value,
257
- forceQuineCheats: forceQuineCheatsOption?.value ?? !noQuineCheatsOptions?.value
261
+ forceQuineCheats: forceQuineCheatsOption?.value ?? !noQuineCheatsOptions?.value,
262
+ rootFolderPath
258
263
  })
259
264
  if (infos instanceof Error) {
260
265
  logError(infos.message)
@@ -308,7 +313,7 @@ switch (commands[0]) {
308
313
  warnedDeprecatedEmitDtsAlias = !0
309
314
  console.warn(
310
315
  colourF(
311
- `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`
316
+ `${chalk.bold("Warning:")} ${colourC("hsm")} ${colourL(commands[0])} is 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`
312
317
  )
313
318
  )
314
319
  }
@@ -325,7 +330,7 @@ switch (commands[0]) {
325
330
  typeDeclaration = await generateTypeDeclaration(sourcePath, hackmudPath)
326
331
  let typeDeclarationPath = resolve(outputPath)
327
332
  await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
328
- assert(error instanceof Error, "src/bin/hsm.ts:422:35")
333
+ assert(error instanceof Error, "src/bin/hsm.ts:428:35")
329
334
  if ("EISDIR" != error.code) throw error
330
335
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
331
336
  return writeFile(typeDeclarationPath, typeDeclaration)
@@ -350,7 +355,7 @@ function logHelp() {
350
355
  case "push":
351
356
  console.log(
352
357
  colourS(
353
- `${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")}, ${colourN("--no-quine-cheats")}\n Force quine cheats on or off\n${hackmudPathOption}\n${colourN("--dts-path")}=${colourB("<path>")}\n Path to generate a type declaration (.d.ts) file for the scripts\n${colourN("--watch")}\n Watch for changes\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`
358
+ `${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")}, ${colourN("--no-quine-cheats")}\n Force quine cheats on or off\n${hackmudPathOption}\n${colourN("--dts-path")}=${colourB("<path>")}\n Path to generate a type declaration (.d.ts) file for the scripts\n${colourN("--watch")}\n Watch for changes\n${colourN("--root-folder-path")}\n The folder that root will be aliased to in import statements\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`
354
359
  )
355
360
  )
356
361
  break
@@ -365,7 +370,7 @@ function logHelp() {
365
370
  case "golf":
366
371
  console.log(
367
372
  colourS(
368
- `${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")}, ${colourN("--no-quine-cheats")}\n Force quine cheats on or off\n${colourN("--watch")}\n Watch for changes`
373
+ `${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")}, ${colourN("--no-quine-cheats")}\n Force quine cheats on or off\n${colourN("--watch")}\n Watch for changes\n${colourN("--root-folder-path")}\n The folder that root will be aliased to in import statements`
369
374
  )
370
375
  )
371
376
  break
@@ -379,7 +384,7 @@ function logHelp() {
379
384
  "gen-dts" == commands[0] ||
380
385
  console.warn(
381
386
  colourF(
382
- `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`
387
+ `${chalk.bold("Warning:")} ${colourC("hsm")} ${colourL(commands[0])} is 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`
383
388
  )
384
389
  )
385
390
  console.log(
@@ -398,18 +403,20 @@ function logHelp() {
398
403
  default:
399
404
  console.log(
400
405
  colourS(
401
- `${colourJ("Hackmud Script Manager")}\n${colourN("Version") + colourS(": ") + colourV("0.20.4-1d688c1")}\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.20.4-2a608c4")}\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`
402
407
  )
403
408
  )
404
409
  }
405
410
  }
406
- function logInfo({ path, users, characterCount, error }, hackmudPath) {
411
+ function logInfo({ path, users, characterCount, error, warnings }, hackmudPath) {
407
412
  path = relative(".", path)
408
- error ?
409
- logError(`Error "${chalk.bold(error.message)}" in ${chalk.bold(path)}`)
410
- : log(
413
+ if (error) logError(`Error "${chalk.bold(error.message)}" in ${chalk.bold(path)}`)
414
+ else {
415
+ for (const warning of warnings) console.warn(colourF(`${chalk.bold("Warning:")} ${warning.message}`))
416
+ log(
411
417
  `Pushed ${chalk.bold(path)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(characterCount + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(path, extname(path))) + ".js")}`
412
418
  )
419
+ }
413
420
  }
414
421
  function logError(message) {
415
422
  console.error(colourD(message))
package/env.d.ts CHANGED
@@ -1,7 +1,4 @@
1
- type Replace<A, B> = Omit<A, keyof B> & B
2
- type ScriptSuccess<T = unknown> = { ok: true } & T
3
- type ScriptFailure = { ok: false, msg?: string }
4
- type ScriptResponse<T = unknown> = ScriptSuccess<T> | ScriptFailure
1
+ type Replace<A, B> = Omit<A, keyof B> & BigInt
5
2
  type ErrorScripts = Record<string, () => ScriptFailure>
6
3
 
7
4
  type Subscripts = Record<string, Record<string, (...args: any) => any>> & {
@@ -20,12 +17,6 @@ type Subscripts = Record<string, Record<string, (...args: any) => any>> & {
20
17
  users: ErrorScripts
21
18
  }
22
19
 
23
- interface PlayerFullsec {}
24
- interface PlayerHighsec {}
25
- interface PlayerMidsec {}
26
- interface PlayerLowsec {}
27
- interface PlayerNullsec {}
28
-
29
20
  type UpgradeRarityString = "`0noob`" | "`1kiddie`" | "`2h4x0r`" | "`3h4rdc0r3`" | "`4|_|b3|2`" | "`531337`"
30
21
  type UpgradeRarityNumber = 0 | 1 | 2 | 3 | 4 | 5
31
22
 
@@ -891,10 +882,19 @@ type MongoProject<TDocument, TProjection> =
891
882
  type DeepFreeze<T> = { readonly [P in keyof T]: DeepFreeze<T[P]> }
892
883
 
893
884
  declare global {
885
+ type ScriptSuccess<T = unknown> = { ok: true } & T
886
+ type ScriptFailure = { ok: false, msg?: string }
887
+ type ScriptResponse<T = unknown> = ScriptSuccess<T> | ScriptFailure
894
888
  type Scriptor<TArgs extends any[] = any[]> = { name: string, call: (...args: TArgs) => unknown }
895
889
  type Context = CliContext | SubscriptContext | ScriptorContext | BrainContext
896
890
  type ObjectId = { $oid: string }
897
891
 
892
+ interface PlayerFullsec {}
893
+ interface PlayerHighsec {}
894
+ interface PlayerMidsec {}
895
+ interface PlayerLowsec {}
896
+ interface PlayerNullsec {}
897
+
898
898
  /** Subscript space that can call FULLSEC scripts. */ const $fs: Fullsec
899
899
 
900
900
  /** Subscript space that can call HIGHSEC and above scripts. Makes your script HIGHSEC (overrides FULLSEC). */
@@ -1046,6 +1046,9 @@ declare global {
1046
1046
  * In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
1047
1047
  const _SCRIPT_USER: string
1048
1048
 
1049
+ /** @deprecated Use `_SCRIPT_SUBNAME` instead. */
1050
+ const _SCRIPT_NAME: string
1051
+
1049
1052
  /** The name of this script excluding the user and `.`.
1050
1053
  *
1051
1054
  * e.g. in the script `foo.bar`, `_SCRIPT_NAME` is `bar`.
@@ -1053,7 +1056,7 @@ declare global {
1053
1056
  * Shorter alternative to `context.this_script.split(".")[1].
1054
1057
  *
1055
1058
  * In rare cases where it's not known at build time, it's `"UNKNOWN"`. */
1056
- const _SCRIPT_NAME: string
1059
+ const _SCRIPT_SUBNAME: string
1057
1060
 
1058
1061
  /** The full name of this script equivilent to `context.this_script` but should use less characters.
1059
1062
  *
package/index.d.ts CHANGED
@@ -10,4 +10,7 @@ export type Info = {
10
10
  users: string[];
11
11
  characterCount: number;
12
12
  error: Error | undefined;
13
+ warnings: {
14
+ message: string;
15
+ }[];
13
16
  };
package/index.js CHANGED
@@ -27,6 +27,7 @@ import "@babel/plugin-transform-private-property-in-object"
27
27
  import "@babel/plugin-transform-unicode-sets-regex"
28
28
  import "@babel/traverse"
29
29
  import "@babel/types"
30
+ import "@rollup/plugin-alias"
30
31
  import "@rollup/plugin-babel"
31
32
  import "@rollup/plugin-commonjs"
32
33
  import "@rollup/plugin-json"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.20.4-1d688c1",
3
+ "version": "0.20.4-2a608c4",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -59,6 +59,7 @@
59
59
  "@babel/traverse": "^7.25.9",
60
60
  "@babel/types": "^7.26.0",
61
61
  "@bloomberg/record-tuple-polyfill": "^0.0.4",
62
+ "@rollup/plugin-alias": "^5.1.1",
62
63
  "@rollup/plugin-babel": "^6.0.4",
63
64
  "@rollup/plugin-commonjs": "^28.0.1",
64
65
  "@rollup/plugin-json": "^6.1.0",
@@ -16,16 +16,16 @@ export type ProcessOptions = LaxPartial<{
16
16
  * when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
17
17
  */
18
18
  forceQuineCheats: boolean;
19
+ rootFolderPath: string;
19
20
  }> & {
20
21
  scriptName: string | true;
21
22
  };
22
23
  /** Minifies a given script
23
24
  * @param code JavaScript or TypeScript code
24
25
  * @param options {@link ProcessOptions details} */
25
- export declare function processScript(code: string, { minify: shouldMinify, uniqueId, scriptUser, scriptName, filePath, mangleNames, forceQuineCheats }: ProcessOptions): Promise<{
26
+ export declare function processScript(code: string, { minify: shouldMinify, uniqueId, scriptUser, scriptName, filePath, mangleNames, forceQuineCheats, rootFolderPath }: ProcessOptions): Promise<{
26
27
  script: string;
27
28
  warnings: {
28
29
  message: string;
29
- line: number;
30
30
  }[];
31
31
  }>;
@@ -17,12 +17,13 @@ import babelPluginTransformPrivatePropertyInObject from "@babel/plugin-transform
17
17
  import babelPluginTransformUnicodeSetsRegex from "@babel/plugin-transform-unicode-sets-regex"
18
18
  import babelTraverse from "@babel/traverse"
19
19
  import t from "@babel/types"
20
+ import rollupPluginAlias from "@rollup/plugin-alias"
20
21
  import { babel } from "@rollup/plugin-babel"
21
22
  import rollupPluginCommonJS from "@rollup/plugin-commonjs"
22
23
  import rollupPluginJSON from "@rollup/plugin-json"
23
24
  import rollupPluginNodeResolve from "@rollup/plugin-node-resolve"
24
25
  import { assert } from "@samual/lib/assert"
25
- import { resolve } from "path"
26
+ import { relative } from "path"
26
27
  import prettier from "prettier"
27
28
  import { rollup } from "rollup"
28
29
  import { supportedExtensions } from "../constants.js"
@@ -51,10 +52,11 @@ async function processScript(
51
52
  scriptName,
52
53
  filePath,
53
54
  mangleNames = !1,
54
- forceQuineCheats
55
+ forceQuineCheats,
56
+ rootFolderPath
55
57
  }
56
58
  ) {
57
- assert(/^\w{11}$/.exec(uniqueId), "src/processScript/index.ts:77:36")
59
+ assert(/^\w{11}$/.exec(uniqueId), "src/processScript/index.ts:81:36")
58
60
  const sourceCode = code
59
61
  let autocomplete, statedSeclevel
60
62
  const autocompleteMatch = /^function\s*\(.+\/\/(?<autocomplete>.+)/.exec(code)
@@ -115,7 +117,7 @@ async function processScript(
115
117
  }
116
118
  }
117
119
  }
118
- assert(/^\w{11}$/.exec(uniqueId), "src/processScript/index.ts:158:36")
120
+ assert(/^\w{11}$/.exec(uniqueId), "src/processScript/index.ts:162:36")
119
121
  const plugins = [
120
122
  [babelPluginProposalDecorators.default, { decoratorsBeforeExport: !0 }],
121
123
  [babelPluginTransformClassProperties.default],
@@ -135,7 +137,7 @@ async function processScript(
135
137
  ]
136
138
  let filePathResolved
137
139
  if (filePath) {
138
- filePathResolved = resolve(filePath)
140
+ filePathResolved = relative(".", filePath)
139
141
  if (filePath.endsWith(".ts"))
140
142
  plugins.push([
141
143
  (await import("@babel/plugin-transform-typescript")).default,
@@ -228,13 +230,14 @@ async function processScript(
228
230
  },
229
231
  babel({ babelHelpers: "bundled", plugins, configFile: !1, extensions: supportedExtensions }),
230
232
  rollupPluginCommonJS(),
231
- rollupPluginNodeResolve({ extensions: supportedExtensions })
233
+ rollupPluginNodeResolve({ extensions: supportedExtensions }),
234
+ !!rootFolderPath && rollupPluginAlias({ entries: [{ find: /^\//, replacement: rootFolderPath + "/" }] })
232
235
  ],
233
236
  treeshake: { moduleSideEffects: !1 }
234
237
  }),
235
238
  seclevelNames = ["NULLSEC", "LOWSEC", "MIDSEC", "HIGHSEC", "FULLSEC"]
236
239
  code = (await bundle.generate({})).output[0].code
237
- const { file, seclevel } = transform(parse(code, { sourceType: "module" }), sourceCode, {
240
+ const { file, seclevel, warnings } = transform(parse(code, { sourceType: "module" }), sourceCode, {
238
241
  uniqueId,
239
242
  scriptUser,
240
243
  scriptName
@@ -249,7 +252,7 @@ async function processScript(
249
252
  traverse(file, {
250
253
  MemberExpression({ node: memberExpression }) {
251
254
  if (!memberExpression.computed) {
252
- assert("Identifier" == memberExpression.property.type, "src/processScript/index.ts:321:60")
255
+ assert("Identifier" == memberExpression.property.type, "src/processScript/index.ts:326:60")
253
256
  if ("prototype" == memberExpression.property.name) {
254
257
  memberExpression.computed = !0
255
258
  memberExpression.property = t.stringLiteral("prototype")
@@ -279,7 +282,7 @@ async function processScript(
279
282
  break
280
283
  case "ObjectPattern":
281
284
  for (const property of lValue.properties) {
282
- assert("ObjectProperty" == property.type, "src/processScript/index.ts:351:51")
285
+ assert("ObjectProperty" == property.type, "src/processScript/index.ts:356:51")
283
286
  renameVariables(property.value)
284
287
  }
285
288
  break
@@ -328,6 +331,6 @@ async function processScript(
328
331
  throw Error(
329
332
  'you found a weird edge case where I wasn\'t able to replace illegal strings like "SC$", please report thx'
330
333
  )
331
- return { script: code, warnings: [] }
334
+ return { script: code, warnings }
332
335
  }
333
336
  export { minify, postprocess, preprocess, processScript, transform }
@@ -8,7 +8,7 @@ import { resolve } from "import-meta-resolve"
8
8
  const { default: traverse } = babelTraverse,
9
9
  { default: generate } = babelGenerator
10
10
  async function preprocess(code, { uniqueId = "00000000000" } = {}) {
11
- assert(/^\w{11}$/.test(uniqueId), "src/processScript/preprocess.ts:22:36")
11
+ assert(/^\w{11}$/.test(uniqueId), "src/processScript/preprocess.ts:23:36")
12
12
  const sourceCode = code
13
13
  let lengthBefore, file, program
14
14
  do {
@@ -47,7 +47,7 @@ async function preprocess(code, { uniqueId = "00000000000" } = {}) {
47
47
  })
48
48
  break
49
49
  } catch (error_) {
50
- assert(error_ instanceof SyntaxError, "src/processScript/preprocess.ts:66:42")
50
+ assert(error_ instanceof SyntaxError, "src/processScript/preprocess.ts:67:42")
51
51
  error = error_
52
52
  }
53
53
  if ("BABEL_PARSER_SYNTAX_ERROR" != error.code || "PrivateInExpectedIn" != error.reasonCode) {
@@ -16,4 +16,7 @@ export type TransformOptions = LaxPartial<{
16
16
  export declare function transform(file: File, sourceCode: string, { uniqueId, scriptUser, scriptName, seclevel }: TransformOptions): {
17
17
  file: File;
18
18
  seclevel: number;
19
+ warnings: {
20
+ message: string;
21
+ }[];
19
22
  };
@@ -22,7 +22,8 @@ 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_`
25
+ const warnings = [],
26
+ topFunctionName = `_${uniqueId}_SCRIPT_`
26
27
  let program
27
28
  traverse(file, {
28
29
  Program(path) {
@@ -44,9 +45,17 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
44
45
  referencePath.replaceWith(t.identifier(`_${uniqueId}_SCRIPT_USER_`))
45
46
  } else
46
47
  referencePath.replaceWith(t.stringLiteral(1 == scriptUser ? `$${uniqueId}$SCRIPT_USER$` : scriptUser))
47
- if (program.scope.hasGlobal("_SCRIPT_NAME"))
48
+ if (program.scope.hasGlobal("_SCRIPT_NAME")) {
49
+ warnings.push({
50
+ message:
51
+ "Global _SCRIPT_NAME is deprecated and will be removed in the next minor release of HSM, use _SCRIPT_SUBNAME instead"
52
+ })
48
53
  for (const referencePath of getReferencePathsToGlobal("_SCRIPT_NAME", program))
49
54
  referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueId}$SCRIPT_NAME$` : scriptName))
55
+ }
56
+ if (program.scope.hasGlobal("_SCRIPT_SUBNAME"))
57
+ for (const referencePath of getReferencePathsToGlobal("_SCRIPT_SUBNAME", program))
58
+ referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueId}$SCRIPT_NAME$` : scriptName))
50
59
  if (program.scope.hasGlobal("_FULL_SCRIPT_NAME"))
51
60
  for (const referencePath of getReferencePathsToGlobal("_FULL_SCRIPT_NAME", program))
52
61
  if (1 == scriptUser || 1 == scriptName)
@@ -68,30 +77,30 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
68
77
  const referencePath = FunctionReferencePaths[0]
69
78
  assert(
70
79
  "MemberExpression" == referencePath.parent.type,
71
- "src/processScript/transform.ts:103:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
80
+ "src/processScript/transform.ts:111:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
72
81
  )
73
82
  assert(
74
83
  "Identifier" == referencePath.parent.property.type,
75
- "src/processScript/transform.ts:108:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
84
+ "src/processScript/transform.ts:116:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
76
85
  )
77
86
  assert(
78
87
  "prototype" == referencePath.parent.property.name,
79
- "src/processScript/transform.ts:113:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
88
+ "src/processScript/transform.ts:121:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
80
89
  )
81
90
  referencePath.parentPath.replaceWith(createGetFunctionPrototypeNode())
82
91
  } else {
83
92
  for (const referencePath of FunctionReferencePaths) {
84
93
  assert(
85
94
  "MemberExpression" == referencePath.parent.type,
86
- "src/processScript/transform.ts:121:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
95
+ "src/processScript/transform.ts:129:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
87
96
  )
88
97
  assert(
89
98
  "Identifier" == referencePath.parent.property.type,
90
- "src/processScript/transform.ts:126:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
99
+ "src/processScript/transform.ts:134:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
91
100
  )
92
101
  assert(
93
102
  "prototype" == referencePath.parent.property.name,
94
- "src/processScript/transform.ts:131:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
103
+ "src/processScript/transform.ts:139:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
95
104
  )
96
105
  functionDotPrototypeIsReferencedMultipleTimes = !0
97
106
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_FUNCTION_DOT_PROTOTYPE_`))
@@ -101,6 +110,11 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
101
110
  }
102
111
  const neededSubscriptLets = new Map()
103
112
  let detectedSeclevel = 4
113
+ program.scope.hasGlobal("$s") &&
114
+ warnings.push({
115
+ message:
116
+ "Subscripts in the form of $s.foo.bar() and #s.foo.bar() are deprecated. Use explicit seclevels instead."
117
+ })
104
118
  for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
105
119
  program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName, 4)
106
120
  for (const fakeSubscriptObjectName of ["$hs", "$3s"])
@@ -127,12 +141,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
127
141
  const neededDbMethodLets = new Set()
128
142
  if (program.scope.hasGlobal("$db"))
129
143
  for (const referencePath of getReferencePathsToGlobal("$db", program)) {
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")
144
+ assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:199:69")
145
+ assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:200:72")
132
146
  const databaseOpMethodName = referencePath.parentPath.node.property.name
133
147
  assert(
134
148
  validDBMethods.includes(databaseOpMethodName),
135
- `src/processScript/transform.ts:192:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
149
+ `src/processScript/transform.ts:206:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
136
150
  )
137
151
  if ("CallExpression" == referencePath.parentPath.parentPath?.type)
138
152
  referencePath.parentPath.replaceWith(t.identifier(`$${uniqueId}$DB$${databaseOpMethodName}$`))
@@ -167,7 +181,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
167
181
  if (program.scope.hasGlobal("Object"))
168
182
  for (const referencePath of getReferencePathsToGlobal("Object", program))
169
183
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
170
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:242:64")
184
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:256:64")
171
185
  if ("getPrototypeOf" == referencePath.parent.property.name) {
172
186
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
173
187
  needGetPrototypeOf = !0
@@ -180,7 +194,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
180
194
  if (program.scope.hasGlobal("console"))
181
195
  for (const referencePath of getReferencePathsToGlobal("console", program))
182
196
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
183
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:260:64")
197
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:274:64")
184
198
  referencePath.parentPath.replaceWith(
185
199
  t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
186
200
  )
@@ -188,13 +202,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
188
202
  }
189
203
  const lastStatement = program.node.body.at(-1)
190
204
  let exportDefaultName
191
- assert(lastStatement, "src/processScript/transform.ts:274:27 program is empty")
205
+ assert(lastStatement, "src/processScript/transform.ts:288:27 program is empty")
192
206
  if ("ExportNamedDeclaration" == lastStatement.type) {
193
207
  program.node.body.pop()
194
208
  for (const specifier of lastStatement.specifiers) {
195
209
  assert(
196
210
  "ExportSpecifier" == specifier.type,
197
- `src/processScript/transform.ts:280:51 ${specifier.type} is currently unsupported`
211
+ `src/processScript/transform.ts:294:51 ${specifier.type} is currently unsupported`
198
212
  )
199
213
  if (
200
214
  "default" !=
@@ -296,11 +310,11 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
296
310
  let hoistedGlobalBlockFunctions = 0
297
311
  for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
298
312
  if ("VariableDeclaration" == globalBlockStatement.type) {
299
- assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:394:59")
313
+ assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:408:59")
300
314
  const declarator = globalBlockStatement.declarations[0]
301
315
  assert(
302
316
  "Identifier" == declarator.id.type,
303
- `src/processScript/transform.ts:398:51 declarator.id.type was "${declarator.id.type}"`
317
+ `src/processScript/transform.ts:412:51 declarator.id.type was "${declarator.id.type}"`
304
318
  )
305
319
  program.scope.crawl()
306
320
  if (program.scope.hasGlobal(declarator.id.name)) {
@@ -315,9 +329,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
315
329
  Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
316
330
  ) {
317
331
  const binding = program.scope.getBinding(declarator.id.name)
318
- assert(binding, "src/processScript/transform.ts:417:23")
332
+ assert(binding, "src/processScript/transform.ts:431:23")
319
333
  for (const referencePath of binding.referencePaths) {
320
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:420:56")
334
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:434:56")
321
335
  referencePath.replaceWith(
322
336
  t.memberExpression(
323
337
  t.identifier(`_${uniqueId}_G_`),
@@ -365,16 +379,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
365
379
  } else globalBlockVariables.add(declarator.id.name)
366
380
  } else if ("ClassDeclaration" == globalBlockStatement.type) {
367
381
  program.scope.crawl()
368
- assert(globalBlockStatement.id, "src/processScript/transform.ts:477:37")
382
+ assert(globalBlockStatement.id, "src/processScript/transform.ts:491:37")
369
383
  if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
370
384
  globalBlock.body.splice(globalBlockIndex, 1)
371
385
  const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
372
386
  [globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
373
387
  program.scope.crawl()
374
388
  const binding = program.scope.getBinding(globalBlockStatement.id.name)
375
- assert(binding, "src/processScript/transform.ts:489:22")
389
+ assert(binding, "src/processScript/transform.ts:503:22")
376
390
  for (const referencePath of binding.referencePaths) {
377
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:492:55")
391
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:506:55")
378
392
  referencePath.replaceWith(
379
393
  t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
380
394
  )
@@ -566,7 +580,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
566
580
  }
567
581
  },
568
582
  ClassBody({ node: classBody, scope, parent }) {
569
- assert(t.isClass(parent), "src/processScript/transform.ts:687:30")
583
+ assert(t.isClass(parent), "src/processScript/transform.ts:701:30")
570
584
  let thisIsReferenced = !1
571
585
  for (const classMethod of classBody.body) {
572
586
  if ("ClassMethod" != classMethod.type) continue
@@ -656,7 +670,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
656
670
  )
657
671
  }
658
672
  })
659
- return { file, seclevel }
673
+ return { file, seclevel, warnings }
660
674
  function createGetFunctionPrototypeNode() {
661
675
  const name = globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
662
676
  return t.memberExpression(
@@ -666,23 +680,23 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
666
680
  }
667
681
  function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
668
682
  for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
669
- assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:793:60")
683
+ assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:807:60")
670
684
  assert("Identifier" == referencePath.parent.property.type)
671
685
  assert(
672
686
  "MemberExpression" == referencePath.parentPath.parentPath?.node.type,
673
- "src/processScript/transform.ts:795:81"
687
+ "src/processScript/transform.ts:809:81"
674
688
  )
675
689
  assert(
676
690
  "Identifier" == referencePath.parentPath.parentPath.node.property.type,
677
- "src/processScript/transform.ts:796:83"
691
+ "src/processScript/transform.ts:810:83"
678
692
  )
679
693
  assert(
680
694
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
681
- `src/processScript/transform.ts:800:8 invalid user "${referencePath.parent.property.name}" in subscript`
695
+ `src/processScript/transform.ts:814:8 invalid user "${referencePath.parent.property.name}" in subscript`
682
696
  )
683
697
  assert(
684
698
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
685
- `src/processScript/transform.ts:805:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
699
+ `src/processScript/transform.ts:819:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
686
700
  )
687
701
  if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
688
702
  referencePath.parentPath.parentPath.replaceWith(
package/push.d.ts CHANGED
@@ -17,6 +17,7 @@ export type PushOptions = LaxPartial<{
17
17
  * when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
18
18
  */
19
19
  forceQuineCheats: boolean;
20
+ rootFolderPath: string;
20
21
  }>;
21
22
  export declare class MissingSourceFolderError extends Error {
22
23
  }
@@ -33,4 +34,4 @@ export declare class NoScriptsError extends Error {
33
34
  * @param hackmudPath directory created by hackmud containing user data including scripts
34
35
  * @param options {@link PushOptions details}
35
36
  * @returns array of info on pushed scripts */
36
- export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;
37
+ export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats, rootFolderPath }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;
package/push.js CHANGED
@@ -25,6 +25,7 @@ import "@babel/plugin-transform-private-property-in-object"
25
25
  import "@babel/plugin-transform-unicode-sets-regex"
26
26
  import "@babel/traverse"
27
27
  import "@babel/types"
28
+ import "@rollup/plugin-alias"
28
29
  import "@rollup/plugin-babel"
29
30
  import "@rollup/plugin-commonjs"
30
31
  import "@rollup/plugin-json"
@@ -53,7 +54,7 @@ Object.defineProperty(NoScriptsError.prototype, "name", { value: "NoScriptsError
53
54
  async function push(
54
55
  sourcePath,
55
56
  hackmudPath,
56
- { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
57
+ { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats, rootFolderPath } = {}
57
58
  ) {
58
59
  const [sourceFolder, hackmudFolder] = await Promise.all([
59
60
  readDirectoryWithStats(sourcePath).catch(error => {
@@ -72,7 +73,7 @@ async function push(
72
73
  const sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
73
74
  allUsers = new Set([
74
75
  ...scripts
75
- .map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:82:65"))
76
+ .map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:85:65"))
76
77
  .filter(name => "*" != name),
77
78
  ...sourceFolderFolders.map(({ name }) => name),
78
79
  ...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
@@ -88,8 +89,8 @@ async function push(
88
89
  scriptNamesToUsers = new AutoMap(_scriptName => new Set())
89
90
  for (const script of scripts) {
90
91
  const [user, scriptName] = script.split(".")
91
- assert(user, "src/push.ts:105:16")
92
- assert(scriptName, "src/push.ts:106:22")
92
+ assert(user, "src/push.ts:108:16")
93
+ assert(scriptName, "src/push.ts:109:22")
93
94
  "*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
94
95
  }
95
96
  const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
@@ -131,16 +132,17 @@ async function push(
131
132
  uniqueId = Math.floor(Math.random() * 2 ** 52)
132
133
  .toString(36)
133
134
  .padStart(11, "0"),
134
- { script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf8" }), {
135
+ { script: minifiedCode, warnings } = await processScript(await readFile(path, { encoding: "utf8" }), {
135
136
  minify,
136
137
  scriptUser: !0,
137
138
  scriptName,
138
139
  uniqueId,
139
140
  filePath: path,
140
141
  mangleNames,
141
- forceQuineCheats
142
+ forceQuineCheats,
143
+ rootFolderPath
142
144
  }),
143
- info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0 }
145
+ info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0, warnings }
144
146
  await Promise.all(
145
147
  users.map(user =>
146
148
  writeFilePersistent(
package/watch.d.ts CHANGED
@@ -6,9 +6,10 @@ export type WatchOptions = PushOptions & LaxPartial<{
6
6
  * writing the type declarations enables interscript type checking and autocompletetes for the args */
7
7
  typeDeclarationPath: string;
8
8
  onReady: () => void;
9
+ rootFolderPath: string;
9
10
  }>;
10
11
  /** Watches target file or folder for updates and builds and pushes updated file.
11
12
  * @param sourceDirectory path to folder containing source files
12
13
  * @param hackmudDirectory path to hackmud directory
13
14
  * @param options {@link WatchOptions details} and {@link PushOptions more details} */
14
- export declare function watch(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats }?: WatchOptions): Promise<void>;
15
+ export declare function watch(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats, rootFolderPath }?: WatchOptions): Promise<void>;
package/watch.js CHANGED
@@ -29,6 +29,7 @@ import "@babel/plugin-transform-private-property-in-object"
29
29
  import "@babel/plugin-transform-unicode-sets-regex"
30
30
  import "@babel/traverse"
31
31
  import "@babel/types"
32
+ import "@rollup/plugin-alias"
32
33
  import "@rollup/plugin-babel"
33
34
  import "@rollup/plugin-commonjs"
34
35
  import "@rollup/plugin-json"
@@ -55,7 +56,8 @@ async function watch(
55
56
  mangleNames = !1,
56
57
  typeDeclarationPath: typeDeclarationPath_,
57
58
  onReady,
58
- forceQuineCheats
59
+ forceQuineCheats,
60
+ rootFolderPath
59
61
  } = {}
60
62
  ) {
61
63
  if (!scripts.length) throw Error("scripts option was an empty array")
@@ -119,27 +121,22 @@ async function watch(
119
121
  for (const user of scriptNamesToUsers.get(scriptName)) usersToPushToSet.add(user)
120
122
  const usersToPushTo = [...usersToPushToSet].filter(user => !scriptNamesToUsersToSkip.has(user))
121
123
  if (!usersToPushTo.length) {
122
- onPush?.({ path, users: [], characterCount: 0, error: Error("no users to push to") })
124
+ onPush?.({ path, users: [], characterCount: 0, error: Error("no users to push to"), warnings: [] })
123
125
  return
124
126
  }
125
127
  const uniqueId = Math.floor(Math.random() * 2 ** 52)
126
128
  .toString(36)
127
129
  .padStart(11, "0"),
128
130
  filePath = resolve(sourceDirectory, path)
129
- let minifiedCode
131
+ let minifiedCode, warnings
130
132
  try {
131
- ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf8" }), {
132
- minify,
133
- scriptUser: !0,
134
- scriptName,
135
- uniqueId,
136
- filePath,
137
- mangleNames,
138
- forceQuineCheats
139
- }))
133
+ ;({ script: minifiedCode, warnings } = await processScript(
134
+ await readFile(filePath, { encoding: "utf8" }),
135
+ { minify, scriptUser: !0, scriptName, uniqueId, filePath, mangleNames, forceQuineCheats }
136
+ ))
140
137
  } catch (error) {
141
- assert(error instanceof Error, "src/watch.ts:148:36")
142
- onPush?.({ path, users: [], characterCount: 0, error })
138
+ assert(error instanceof Error, "src/watch.ts:151:36")
139
+ onPush?.({ path, users: [], characterCount: 0, error, warnings: [] })
143
140
  return
144
141
  }
145
142
  await Promise.all(
@@ -156,7 +153,8 @@ async function watch(
156
153
  path,
157
154
  users: usersToPushTo,
158
155
  characterCount: countHackmudCharacters(minifiedCode),
159
- error: void 0
156
+ error: void 0,
157
+ warnings
160
158
  })
161
159
  return
162
160
  }
@@ -170,25 +168,27 @@ async function watch(
170
168
  )
171
169
  )
172
170
  return
173
- const filePath = resolve(sourceDirectory, path),
171
+ const sourceDirectoryResolved = resolve(sourceDirectory),
172
+ filePath = resolve(sourceDirectoryResolved, path),
174
173
  sourceCode = await readFile(filePath, { encoding: "utf8" })
175
- let script
174
+ let script, warnings
176
175
  try {
177
- ;({ script } = await processScript(sourceCode, {
176
+ ;({ script, warnings } = await processScript(sourceCode, {
178
177
  minify,
179
178
  scriptUser: user,
180
179
  scriptName,
181
180
  filePath,
182
181
  mangleNames,
183
- forceQuineCheats
182
+ forceQuineCheats,
183
+ rootFolderPath
184
184
  }))
185
185
  } catch (error) {
186
- assert(error instanceof Error, "src/watch.ts:184:35")
187
- onPush?.({ path, users: [], characterCount: 0, error })
186
+ assert(error instanceof Error, "src/watch.ts:198:35")
187
+ onPush?.({ path, users: [], characterCount: 0, error, warnings: [] })
188
188
  return
189
189
  }
190
190
  await writeFilePersistent(resolve(hackmudDirectory, user, "scripts", scriptName + ".js"), script)
191
- onPush?.({ path, users: [user], characterCount: countHackmudCharacters(script), error: void 0 })
191
+ onPush?.({ path, users: [user], characterCount: countHackmudCharacters(script), error: void 0, warnings })
192
192
  })
193
193
  onReady && watcher.on("ready", onReady)
194
194
  if (!typeDeclarationPath_) return
@@ -198,7 +198,7 @@ async function watch(
198
198
  try {
199
199
  await writeFile(typeDeclarationPath, typeDeclaration)
200
200
  } catch (error) {
201
- assert(error instanceof Error, "src/watch.ts:217:35")
201
+ assert(error instanceof Error, "src/watch.ts:231:35")
202
202
  if ("EISDIR" != error.code) throw error
203
203
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
204
204
  await writeFile(typeDeclarationPath, typeDeclaration)