hackmud-script-manager 0.19.1-98e81f8 → 0.19.1-b720a68
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 +1 -1
 - package/bin/hsm.d.ts +0 -0
 - package/bin/hsm.js +146 -300
 - package/generateTypeDeclaration.d.ts +1 -2
 - package/generateTypeDeclaration.js +19 -19
 - package/index.js +2 -1
 - package/package.json +6 -7
 - package/processScript/index.d.ts +15 -25
 - package/processScript/index.js +258 -241
 - package/processScript/minify.d.ts +13 -19
 - package/processScript/minify.js +381 -395
 - package/processScript/postprocess.d.ts +0 -1
 - package/processScript/postprocess.js +1 -1
 - package/processScript/preprocess.d.ts +4 -8
 - package/processScript/preprocess.js +94 -94
 - package/processScript/shared.d.ts +1 -1
 - package/processScript/shared.js +11 -11
 - package/processScript/transform.d.ts +11 -17
 - package/processScript/transform.js +597 -551
 - package/pull.d.ts +5 -9
 - package/pull.js +2 -2
 - package/push.d.ts +22 -31
 - package/push.js +46 -40
 - package/syncMacros.d.ts +1 -2
 - package/syncMacros.js +6 -5
 - package/watch.d.ts +8 -14
 - package/watch.js +22 -23
 - package/tsconfig.tsbuildinfo +0 -1
 
    
        package/README.md
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Hackmud Script Manager
         
     | 
| 
       2 
2 
     | 
    
         
             
            Command made for [hackmud-environment](https://github.com/samualtnorman/hackmud-environment), which is a scripting environment for hackmud with minification, autocompletes / intellisense, and TypeScript support.
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            Install with `npm install hackmud-script-manager 
     | 
| 
      
 4 
     | 
    
         
            +
            Install with `npm install -g hackmud-script-manager` to make the `hsm` command available everywhere.
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            ## Features
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Minification
         
     | 
    
        package/bin/hsm.d.ts
    CHANGED
    
    | 
         
            File without changes
         
     | 
    
        package/bin/hsm.js
    CHANGED
    
    | 
         @@ -3,16 +3,16 @@ import { Cache } from "@samual/lib/Cache" 
     | 
|
| 
       3 
3 
     | 
    
         
             
            import { assert } from "@samual/lib/assert"
         
     | 
| 
       4 
4 
     | 
    
         
             
            import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
         
     | 
| 
       5 
5 
     | 
    
         
             
            import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
         
     | 
| 
       6 
     | 
    
         
            -
            import {  
     | 
| 
      
 6 
     | 
    
         
            +
            import { writeFile, readFile } from "fs/promises"
         
     | 
| 
       7 
7 
     | 
    
         
             
            import { homedir } from "os"
         
     | 
| 
       8 
     | 
    
         
            -
            import {  
     | 
| 
      
 8 
     | 
    
         
            +
            import { extname, basename, resolve, dirname, relative } from "path"
         
     | 
| 
       9 
9 
     | 
    
         
             
            import { supportedExtensions } from "../constants.js"
         
     | 
| 
       10 
10 
     | 
    
         
             
            import { generateTypeDeclaration } from "../generateTypeDeclaration.js"
         
     | 
| 
       11 
11 
     | 
    
         
             
            import { pull } from "../pull.js"
         
     | 
| 
       12 
12 
     | 
    
         
             
            import { syncMacros } from "../syncMacros.js"
         
     | 
| 
      
 13 
     | 
    
         
            +
            import "@samual/lib/readDirectoryWithStats"
         
     | 
| 
       13 
14 
     | 
    
         
             
            import "@samual/lib/copyFilePersistent"
         
     | 
| 
       14 
     | 
    
         
            -
            const  
     | 
| 
       15 
     | 
    
         
            -
            	configFilePath = resolve(configDirectoryPath, "hsm.json"),
         
     | 
| 
      
 15 
     | 
    
         
            +
            const version = "0.19.1-b720a68",
         
     | 
| 
       16 
16 
     | 
    
         
             
            	options = new Map(),
         
     | 
| 
       17 
17 
     | 
    
         
             
            	commands = [],
         
     | 
| 
       18 
18 
     | 
    
         
             
            	userColours = new Cache(user => {
         
     | 
| 
         @@ -20,117 +20,7 @@ const configDirectoryPath = resolve(homedir(), ".config"), 
     | 
|
| 
       20 
20 
     | 
    
         
             
            		for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
         
     | 
| 
       21 
21 
     | 
    
         
             
            		return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
         
     | 
| 
       22 
22 
     | 
    
         
             
            	}),
         
     | 
| 
       23 
     | 
    
         
            -
            	 
     | 
| 
       24 
     | 
    
         
            -
            		console.error(
         
     | 
| 
       25 
     | 
    
         
            -
            			colourS(
         
     | 
| 
       26 
     | 
    
         
            -
            				`${colourD("You need to set hackmudPath in config before you can use this command")}\n\n${colourA("To fix this:")}\nOpen hackmud and run "${colourC("#dir")}"\nThis will open a file browser and print your hackmud user's script directory\nGo up 2 directories and then copy the path\nThen in a terminal run "${colourC("hsm")} ${colourL("config set")} ${colourV("hackmudPath")} ${colourB("<the path you copied>")}"`
         
     | 
| 
       27 
     | 
    
         
            -
            			)
         
     | 
| 
       28 
     | 
    
         
            -
            		),
         
     | 
| 
       29 
     | 
    
         
            -
            	logHelp = () => {
         
     | 
| 
       30 
     | 
    
         
            -
            		const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
         
     | 
| 
       31 
     | 
    
         
            -
            			mangleNamesOptionDescription = "Reduce character count further but lose function names in error call stacks"
         
     | 
| 
       32 
     | 
    
         
            -
            		console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-98e81f8"))
         
     | 
| 
       33 
     | 
    
         
            -
            		switch (commands[0]) {
         
     | 
| 
       34 
     | 
    
         
            -
            			case "config":
         
     | 
| 
       35 
     | 
    
         
            -
            				switch (commands[1]) {
         
     | 
| 
       36 
     | 
    
         
            -
            					case "get":
         
     | 
| 
       37 
     | 
    
         
            -
            						console.log(
         
     | 
| 
       38 
     | 
    
         
            -
            							`\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
         
     | 
| 
       39 
     | 
    
         
            -
            						)
         
     | 
| 
       40 
     | 
    
         
            -
            						break
         
     | 
| 
       41 
     | 
    
         
            -
            					case "set":
         
     | 
| 
       42 
     | 
    
         
            -
            						console.log(
         
     | 
| 
       43 
     | 
    
         
            -
            							`\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
         
     | 
| 
       44 
     | 
    
         
            -
            						)
         
     | 
| 
       45 
     | 
    
         
            -
            						break
         
     | 
| 
       46 
     | 
    
         
            -
            					case "delete":
         
     | 
| 
       47 
     | 
    
         
            -
            						console.log(
         
     | 
| 
       48 
     | 
    
         
            -
            							`\n${colourJ("Remove a key and value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
         
     | 
| 
       49 
     | 
    
         
            -
            						)
         
     | 
| 
       50 
     | 
    
         
            -
            						break
         
     | 
| 
       51 
     | 
    
         
            -
            					default:
         
     | 
| 
       52 
     | 
    
         
            -
            						console.log(
         
     | 
| 
       53 
     | 
    
         
            -
            							colourS(
         
     | 
| 
       54 
     | 
    
         
            -
            								`${colourN("Config path")}: ${colourV(configFilePath)}\n\n${colourJ("Modify the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0] + " get")} ${colourB("<key>")}\n    Retrieve a value from the config file\n${colourC("hsm")} ${colourL(commands[0] + " set")} ${colourB("<key> <value>")}\n    Assign a value to the config file\n${colourC("hsm")} ${colourL(commands[0] + " delete")} ${colourB("<key>")}\n    Remove a key and value from the config file`
         
     | 
| 
       55 
     | 
    
         
            -
            							)
         
     | 
| 
       56 
     | 
    
         
            -
            						)
         
     | 
| 
       57 
     | 
    
         
            -
            				}
         
     | 
| 
       58 
     | 
    
         
            -
            				break
         
     | 
| 
       59 
     | 
    
         
            -
            			case "push":
         
     | 
| 
       60 
     | 
    
         
            -
            				console.log(
         
     | 
| 
       61 
     | 
    
         
            -
            					colourS(
         
     | 
| 
       62 
     | 
    
         
            -
            						`\n${colourJ(pushCommandDescription)}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [<script user>.<script name>...]")}\n\n${colourA("Options:")}\n${colourN("--skip-minify")}\n    Skip minification to produce a readable script\n${colourN("--mangle-names")}\n    ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n    Force quine cheats even if the character count is higher`
         
     | 
| 
       63 
     | 
    
         
            -
            					)
         
     | 
| 
       64 
     | 
    
         
            -
            				)
         
     | 
| 
       65 
     | 
    
         
            -
            				break
         
     | 
| 
       66 
     | 
    
         
            -
            			case "dev":
         
     | 
| 
       67 
     | 
    
         
            -
            			case "watch":
         
     | 
| 
       68 
     | 
    
         
            -
            				console.log(
         
     | 
| 
       69 
     | 
    
         
            -
            					colourS(
         
     | 
| 
       70 
     | 
    
         
            -
            						`${colourN("Aliases")}: ${colourV("watch, dev")}\n\n${colourJ("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("Options:")}\n${colourN("--skip-minify")}\n    Skip minification to produce a readable script\n${colourN("--mangle-names")}\n    ${mangleNamesOptionDescription}\n${colourN("--type-declaration-path")}=${colourB("<path>")}\n    Path to generate a type declaration file for the scripts\n${colourN("--force-quine-cheats")}\n    Force quine cheats even if the character count is higher`
         
     | 
| 
       71 
     | 
    
         
            -
            					)
         
     | 
| 
       72 
     | 
    
         
            -
            				)
         
     | 
| 
       73 
     | 
    
         
            -
            				break
         
     | 
| 
       74 
     | 
    
         
            -
            			case "pull":
         
     | 
| 
       75 
     | 
    
         
            -
            				console.log(
         
     | 
| 
       76 
     | 
    
         
            -
            					colourS(
         
     | 
| 
       77 
     | 
    
         
            -
            						`\n${colourJ("Pull a script a from a hackmud user's script directory")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<script user>")}${colourV(".")}${colourB("<script name>")}`
         
     | 
| 
       78 
     | 
    
         
            -
            					)
         
     | 
| 
       79 
     | 
    
         
            -
            				)
         
     | 
| 
       80 
     | 
    
         
            -
            				break
         
     | 
| 
       81 
     | 
    
         
            -
            			case "minify":
         
     | 
| 
       82 
     | 
    
         
            -
            			case "golf":
         
     | 
| 
       83 
     | 
    
         
            -
            				console.log(
         
     | 
| 
       84 
     | 
    
         
            -
            					colourS(
         
     | 
| 
       85 
     | 
    
         
            -
            						`${colourN("Aliases")}: ${colourV("minify, golf")}\n\n${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("--skip-minify")}\n    Skip minification to produce a readable script\n${colourN("--mangle-names")}\n    ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n    Force quine cheats even if the character count is higher\n${colourN("--watch")}\n    Watch for changes`
         
     | 
| 
       86 
     | 
    
         
            -
            					)
         
     | 
| 
       87 
     | 
    
         
            -
            				)
         
     | 
| 
       88 
     | 
    
         
            -
            				break
         
     | 
| 
       89 
     | 
    
         
            -
            			case "generate-type-declaration":
         
     | 
| 
       90 
     | 
    
         
            -
            			case "gen-type-declaration":
         
     | 
| 
       91 
     | 
    
         
            -
            			case "gen-dts":
         
     | 
| 
       92 
     | 
    
         
            -
            			case "gen-types":
         
     | 
| 
       93 
     | 
    
         
            -
            				console.log(
         
     | 
| 
       94 
     | 
    
         
            -
            					colourS(
         
     | 
| 
       95 
     | 
    
         
            -
            						`${colourN("Aliases")}: ${colourV("generate-type-declaration, gen-type-declaration, gen-types, gen-dts")}\n\n${colourJ("Generate a type declaration file for a directory of scripts")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [output path]")}`
         
     | 
| 
       96 
     | 
    
         
            -
            					)
         
     | 
| 
       97 
     | 
    
         
            -
            				)
         
     | 
| 
       98 
     | 
    
         
            -
            				break
         
     | 
| 
       99 
     | 
    
         
            -
            			case "sync-macros":
         
     | 
| 
       100 
     | 
    
         
            -
            				console.log("\n" + colourJ("Sync macros across all hackmud users"))
         
     | 
| 
       101 
     | 
    
         
            -
            				break
         
     | 
| 
       102 
     | 
    
         
            -
            			default:
         
     | 
| 
       103 
     | 
    
         
            -
            				console.log(
         
     | 
| 
       104 
     | 
    
         
            -
            					colourS(
         
     | 
| 
       105 
     | 
    
         
            -
            						`\n${colourJ("Hackmud Script Manager")}\n\n${colourA("Commands:")}\n${colourL("push")}\n    ${pushCommandDescription}\n${colourL("watch")}, ${colourL("dev")}\n    Watch a directory and push a script when modified\n${colourL("minify")}, ${colourL("golf")}\n    Minify a script file on the spot\n${colourL("generate-type-declaration")}, ${colourL("gen-type-declaration")}, ${colourL("gen-types")}, ${colourL("gen-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("config")}\n    Modify and view the config file\n${colourL("pull")}\n    Pull a script a from a hackmud user's script directory`
         
     | 
| 
       106 
     | 
    
         
            -
            					)
         
     | 
| 
       107 
     | 
    
         
            -
            				)
         
     | 
| 
       108 
     | 
    
         
            -
            		}
         
     | 
| 
       109 
     | 
    
         
            -
            	},
         
     | 
| 
       110 
     | 
    
         
            -
            	exploreObject = (object, keys, createPath = !1) => {
         
     | 
| 
       111 
     | 
    
         
            -
            		for (const key of keys)
         
     | 
| 
       112 
     | 
    
         
            -
            			object =
         
     | 
| 
       113 
     | 
    
         
            -
            				createPath ?
         
     | 
| 
       114 
     | 
    
         
            -
            					"object" == typeof object[key] ?
         
     | 
| 
       115 
     | 
    
         
            -
            						object[key]
         
     | 
| 
       116 
     | 
    
         
            -
            					:	(object[key] = {})
         
     | 
| 
       117 
     | 
    
         
            -
            				:	object?.[key]
         
     | 
| 
       118 
     | 
    
         
            -
            		return object
         
     | 
| 
       119 
     | 
    
         
            -
            	},
         
     | 
| 
       120 
     | 
    
         
            -
            	logInfo = ({ file, users, minLength, error }, hackmudPath) => {
         
     | 
| 
       121 
     | 
    
         
            -
            		error ?
         
     | 
| 
       122 
     | 
    
         
            -
            			logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
         
     | 
| 
       123 
     | 
    
         
            -
            		:	console.log(
         
     | 
| 
       124 
     | 
    
         
            -
            				`pushed ${chalk.bold(file)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(minLength + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(file, extname(file))) + ".js")}`
         
     | 
| 
       125 
     | 
    
         
            -
            			)
         
     | 
| 
       126 
     | 
    
         
            -
            	},
         
     | 
| 
       127 
     | 
    
         
            -
            	log = message => {
         
     | 
| 
       128 
     | 
    
         
            -
            		console.log(colourS(message))
         
     | 
| 
       129 
     | 
    
         
            -
            	},
         
     | 
| 
       130 
     | 
    
         
            -
            	logError = message => {
         
     | 
| 
       131 
     | 
    
         
            -
            		console.error(colourD(message))
         
     | 
| 
       132 
     | 
    
         
            -
            		process.exitCode = 1
         
     | 
| 
       133 
     | 
    
         
            -
            	}
         
     | 
| 
      
 23 
     | 
    
         
            +
            	log = message => console.log(colourS(message))
         
     | 
| 
       134 
24 
     | 
    
         
             
            for (const argument of process.argv.slice(2))
         
     | 
| 
       135 
25 
     | 
    
         
             
            	if ("-" == argument[0]) {
         
     | 
| 
       136 
26 
     | 
    
         
             
            		const [key, valueRaw] = argument.split("=")
         
     | 
| 
         @@ -147,35 +37,10 @@ for (const argument of process.argv.slice(2)) 
     | 
|
| 
       147 
37 
     | 
    
         
             
            		else for (const option of key.slice(1)) options.set(option, value)
         
     | 
| 
       148 
38 
     | 
    
         
             
            	} else commands.push(argument)
         
     | 
| 
       149 
39 
     | 
    
         
             
            if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
         
     | 
| 
       150 
     | 
    
         
            -
            	console.log( 
     | 
| 
      
 40 
     | 
    
         
            +
            	console.log(version)
         
     | 
| 
       151 
41 
     | 
    
         
             
            	process.exit()
         
     | 
| 
       152 
42 
     | 
    
         
             
            }
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
            const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
         
     | 
| 
       155 
     | 
    
         
            -
            		configFile => {
         
     | 
| 
       156 
     | 
    
         
            -
            			let temporaryConfig
         
     | 
| 
       157 
     | 
    
         
            -
            			try {
         
     | 
| 
       158 
     | 
    
         
            -
            				temporaryConfig = JSON.parse(configFile)
         
     | 
| 
       159 
     | 
    
         
            -
            			} catch {
         
     | 
| 
       160 
     | 
    
         
            -
            				log("Config file was corrupted, resetting")
         
     | 
| 
       161 
     | 
    
         
            -
            				return {}
         
     | 
| 
       162 
     | 
    
         
            -
            			}
         
     | 
| 
       163 
     | 
    
         
            -
            			if (!temporaryConfig || "object" != typeof temporaryConfig) {
         
     | 
| 
       164 
     | 
    
         
            -
            				log("Config file was corrupted, resetting")
         
     | 
| 
       165 
     | 
    
         
            -
            				return {}
         
     | 
| 
       166 
     | 
    
         
            -
            			}
         
     | 
| 
       167 
     | 
    
         
            -
            			if ("hackmudPath" in temporaryConfig && "string" != typeof temporaryConfig.hackmudPath) {
         
     | 
| 
       168 
     | 
    
         
            -
            				log('Property "hackmudPath" of config file was corrupted, removing')
         
     | 
| 
       169 
     | 
    
         
            -
            				delete temporaryConfig.hackmudPath
         
     | 
| 
       170 
     | 
    
         
            -
            			}
         
     | 
| 
       171 
     | 
    
         
            -
            			return temporaryConfig
         
     | 
| 
       172 
     | 
    
         
            -
            		},
         
     | 
| 
       173 
     | 
    
         
            -
            		() => {
         
     | 
| 
       174 
     | 
    
         
            -
            			configDidNotExist = !0
         
     | 
| 
       175 
     | 
    
         
            -
            			return {}
         
     | 
| 
       176 
     | 
    
         
            -
            		}
         
     | 
| 
       177 
     | 
    
         
            -
            	),
         
     | 
| 
       178 
     | 
    
         
            -
            	pushModule = import("../push.js"),
         
     | 
| 
      
 43 
     | 
    
         
            +
            const pushModule = import("../push.js"),
         
     | 
| 
       179 
44 
     | 
    
         
             
            	processScriptModule = import("../processScript/index.js"),
         
     | 
| 
       180 
45 
     | 
    
         
             
            	watchModule = import("../watch.js"),
         
     | 
| 
       181 
46 
     | 
    
         
             
            	chokidarModule = import("chokidar"),
         
     | 
| 
         @@ -200,12 +65,8 @@ let autoExit = !0 
     | 
|
| 
       200 
65 
     | 
    
         
             
            switch (commands[0]) {
         
     | 
| 
       201 
66 
     | 
    
         
             
            	case "push":
         
     | 
| 
       202 
67 
     | 
    
         
             
            		{
         
     | 
| 
       203 
     | 
    
         
            -
            			const  
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
            				logNeedHackmudPathMessage()
         
     | 
| 
       206 
     | 
    
         
            -
            				break
         
     | 
| 
       207 
     | 
    
         
            -
            			}
         
     | 
| 
       208 
     | 
    
         
            -
            			const sourcePath = commands[1]
         
     | 
| 
      
 68 
     | 
    
         
            +
            			const hackmudPath = getHackmudPath(),
         
     | 
| 
      
 69 
     | 
    
         
            +
            				sourcePath = commands[1]
         
     | 
| 
       209 
70 
     | 
    
         
             
            			if (!sourcePath) {
         
     | 
| 
       210 
71 
     | 
    
         
             
            				logError("Must provide the directory to push from\n")
         
     | 
| 
       211 
72 
     | 
    
         
             
            				logHelp()
         
     | 
| 
         @@ -222,17 +83,20 @@ switch (commands[0]) { 
     | 
|
| 
       222 
83 
     | 
    
         
             
            					break
         
     | 
| 
       223 
84 
     | 
    
         
             
            				}
         
     | 
| 
       224 
85 
     | 
    
         
             
            			} else scripts.push("*.*")
         
     | 
| 
       225 
     | 
    
         
            -
            			 
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
      
 86 
     | 
    
         
            +
            			const optionsHasNoMinify = options.has("no-minify")
         
     | 
| 
      
 87 
     | 
    
         
            +
            			if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
         
     | 
| 
      
 88 
     | 
    
         
            +
            				logError(
         
     | 
| 
      
 89 
     | 
    
         
            +
            					`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
         
     | 
| 
      
 90 
     | 
    
         
            +
            				)
         
     | 
| 
       227 
91 
     | 
    
         
             
            				logHelp()
         
     | 
| 
       228 
92 
     | 
    
         
             
            				break
         
     | 
| 
       229 
93 
     | 
    
         
             
            			}
         
     | 
| 
       230 
     | 
    
         
            -
            			const shouldSkipMinify = options.get("skip-minify")
         
     | 
| 
      
 94 
     | 
    
         
            +
            			const shouldSkipMinify = options.get("no-minify") || options.get("skip-minify")
         
     | 
| 
       231 
95 
     | 
    
         
             
            			let shouldMinify
         
     | 
| 
       232 
96 
     | 
    
         
             
            			if (null != shouldSkipMinify) {
         
     | 
| 
       233 
97 
     | 
    
         
             
            				if ("boolean" != typeof shouldSkipMinify) {
         
     | 
| 
       234 
98 
     | 
    
         
             
            					logError(
         
     | 
| 
       235 
     | 
    
         
            -
            						`The value for ${colourN("--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
         
     | 
| 
      
 99 
     | 
    
         
            +
            						`The value for ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
         
     | 
| 
       236 
100 
     | 
    
         
             
            					)
         
     | 
| 
       237 
101 
     | 
    
         
             
            					logHelp()
         
     | 
| 
       238 
102 
     | 
    
         
             
            					break
         
     | 
| 
         @@ -270,12 +134,8 @@ switch (commands[0]) { 
     | 
|
| 
       270 
134 
     | 
    
         
             
            	case "dev":
         
     | 
| 
       271 
135 
     | 
    
         
             
            	case "watch":
         
     | 
| 
       272 
136 
     | 
    
         
             
            		{
         
     | 
| 
       273 
     | 
    
         
            -
            			const  
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
            				logNeedHackmudPathMessage()
         
     | 
| 
       276 
     | 
    
         
            -
            				break
         
     | 
| 
       277 
     | 
    
         
            -
            			}
         
     | 
| 
       278 
     | 
    
         
            -
            			const sourcePath = commands[1]
         
     | 
| 
      
 137 
     | 
    
         
            +
            			const hackmudPath = getHackmudPath(),
         
     | 
| 
      
 138 
     | 
    
         
            +
            				sourcePath = commands[1]
         
     | 
| 
       279 
139 
     | 
    
         
             
            			if (!sourcePath) {
         
     | 
| 
       280 
140 
     | 
    
         
             
            				logError("Must provide the directory to watch\n")
         
     | 
| 
       281 
141 
     | 
    
         
             
            				logHelp()
         
     | 
| 
         @@ -292,17 +152,20 @@ switch (commands[0]) { 
     | 
|
| 
       292 
152 
     | 
    
         
             
            					break
         
     | 
| 
       293 
153 
     | 
    
         
             
            				}
         
     | 
| 
       294 
154 
     | 
    
         
             
            			} else scripts.push("*.*")
         
     | 
| 
       295 
     | 
    
         
            -
            			 
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
      
 155 
     | 
    
         
            +
            			const optionsHasNoMinify = options.has("no-minify")
         
     | 
| 
      
 156 
     | 
    
         
            +
            			if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
         
     | 
| 
      
 157 
     | 
    
         
            +
            				logError(
         
     | 
| 
      
 158 
     | 
    
         
            +
            					`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
         
     | 
| 
      
 159 
     | 
    
         
            +
            				)
         
     | 
| 
       297 
160 
     | 
    
         
             
            				logHelp()
         
     | 
| 
       298 
161 
     | 
    
         
             
            				break
         
     | 
| 
       299 
162 
     | 
    
         
             
            			}
         
     | 
| 
       300 
     | 
    
         
            -
            			const shouldSkipMinify = options.get("skip-minify")
         
     | 
| 
      
 163 
     | 
    
         
            +
            			const shouldSkipMinify = options.get("no-minify") || options.get("skip-minify")
         
     | 
| 
       301 
164 
     | 
    
         
             
            			let shouldMinify
         
     | 
| 
       302 
165 
     | 
    
         
             
            			if (null != shouldSkipMinify) {
         
     | 
| 
       303 
166 
     | 
    
         
             
            				if ("boolean" != typeof shouldSkipMinify) {
         
     | 
| 
       304 
167 
     | 
    
         
             
            					logError(
         
     | 
| 
       305 
     | 
    
         
            -
            						`The value for ${colourN("--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
         
     | 
| 
      
 168 
     | 
    
         
            +
            						`The value for ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} must be ${colourV("true")} or ${colourV("false")}\n`
         
     | 
| 
       306 
169 
     | 
    
         
             
            					)
         
     | 
| 
       307 
170 
     | 
    
         
             
            					logHelp()
         
     | 
| 
       308 
171 
     | 
    
         
             
            					break
         
     | 
| 
         @@ -345,34 +208,24 @@ switch (commands[0]) { 
     | 
|
| 
       345 
208 
     | 
    
         
             
            		break
         
     | 
| 
       346 
209 
     | 
    
         
             
            	case "pull":
         
     | 
| 
       347 
210 
     | 
    
         
             
            		{
         
     | 
| 
       348 
     | 
    
         
            -
            			const  
     | 
| 
       349 
     | 
    
         
            -
             
     | 
| 
       350 
     | 
    
         
            -
            				logNeedHackmudPathMessage()
         
     | 
| 
       351 
     | 
    
         
            -
            				break
         
     | 
| 
       352 
     | 
    
         
            -
            			}
         
     | 
| 
       353 
     | 
    
         
            -
            			const script = commands[1]
         
     | 
| 
      
 211 
     | 
    
         
            +
            			const hackmudPath = getHackmudPath(),
         
     | 
| 
      
 212 
     | 
    
         
            +
            				script = commands[1]
         
     | 
| 
       354 
213 
     | 
    
         
             
            			if (!script) {
         
     | 
| 
       355 
214 
     | 
    
         
             
            				logError("Must provide the script to pull\n")
         
     | 
| 
       356 
215 
     | 
    
         
             
            				logHelp()
         
     | 
| 
       357 
216 
     | 
    
         
             
            				break
         
     | 
| 
       358 
217 
     | 
    
         
             
            			}
         
     | 
| 
       359 
218 
     | 
    
         
             
            			const sourcePath = commands[2] || "."
         
     | 
| 
       360 
     | 
    
         
            -
            			 
     | 
| 
       361 
     | 
    
         
            -
            				await pull(sourcePath, hackmudPath, script)
         
     | 
| 
       362 
     | 
    
         
            -
            			} catch (error) {
         
     | 
| 
      
 219 
     | 
    
         
            +
            			await pull(sourcePath, hackmudPath, script).catch(error => {
         
     | 
| 
       363 
220 
     | 
    
         
             
            				console.error(error)
         
     | 
| 
       364 
221 
     | 
    
         
             
            				logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
         
     | 
| 
       365 
     | 
    
         
            -
            			}
         
     | 
| 
      
 222 
     | 
    
         
            +
            			})
         
     | 
| 
       366 
223 
     | 
    
         
             
            		}
         
     | 
| 
       367 
224 
     | 
    
         
             
            		break
         
     | 
| 
       368 
225 
     | 
    
         
             
            	case "sync-macros":
         
     | 
| 
       369 
226 
     | 
    
         
             
            		{
         
     | 
| 
       370 
     | 
    
         
            -
            			const  
     | 
| 
       371 
     | 
    
         
            -
             
     | 
| 
       372 
     | 
    
         
            -
            				logNeedHackmudPathMessage()
         
     | 
| 
       373 
     | 
    
         
            -
            				break
         
     | 
| 
       374 
     | 
    
         
            -
            			}
         
     | 
| 
       375 
     | 
    
         
            -
            			const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
         
     | 
| 
      
 227 
     | 
    
         
            +
            			const hackmudPath = getHackmudPath(),
         
     | 
| 
      
 228 
     | 
    
         
            +
            				{ macrosSynced, usersSynced } = await syncMacros(hackmudPath)
         
     | 
| 
       376 
229 
     | 
    
         
             
            			log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
         
     | 
| 
       377 
230 
     | 
    
         
             
            		}
         
     | 
| 
       378 
231 
     | 
    
         
             
            		break
         
     | 
| 
         @@ -389,100 +242,17 @@ switch (commands[0]) { 
     | 
|
| 
       389 
242 
     | 
    
         
             
            			}
         
     | 
| 
       390 
243 
     | 
    
         
             
            			const sourcePath = resolve(target),
         
     | 
| 
       391 
244 
     | 
    
         
             
            				outputPath = commands[2] || "./player.d.ts",
         
     | 
| 
       392 
     | 
    
         
            -
            				typeDeclaration = await generateTypeDeclaration(sourcePath, ( 
     | 
| 
      
 245 
     | 
    
         
            +
            				typeDeclaration = await generateTypeDeclaration(sourcePath, getHackmudPath())
         
     | 
| 
       393 
246 
     | 
    
         
             
            			let typeDeclarationPath = resolve(outputPath)
         
     | 
| 
       394 
     | 
    
         
            -
            			 
     | 
| 
       395 
     | 
    
         
            -
            				 
     | 
| 
       396 
     | 
    
         
            -
            			} catch (error) {
         
     | 
| 
       397 
     | 
    
         
            -
            				assert(error instanceof Error)
         
     | 
| 
      
 247 
     | 
    
         
            +
            			await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
         
     | 
| 
      
 248 
     | 
    
         
            +
            				assert(error instanceof Error, "src/bin/hsm.ts:327:35")
         
     | 
| 
       398 
249 
     | 
    
         
             
            				if ("EISDIR" != error.code) throw error
         
     | 
| 
       399 
250 
     | 
    
         
             
            				typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
         
     | 
| 
       400 
     | 
    
         
            -
            				 
     | 
| 
       401 
     | 
    
         
            -
            			}
         
     | 
| 
      
 251 
     | 
    
         
            +
            				return writeFile(typeDeclarationPath, typeDeclaration)
         
     | 
| 
      
 252 
     | 
    
         
            +
            			})
         
     | 
| 
       402 
253 
     | 
    
         
             
            			log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
         
     | 
| 
       403 
254 
     | 
    
         
             
            		}
         
     | 
| 
       404 
255 
     | 
    
         
             
            		break
         
     | 
| 
       405 
     | 
    
         
            -
            	case "config":
         
     | 
| 
       406 
     | 
    
         
            -
            		switch (commands[1]) {
         
     | 
| 
       407 
     | 
    
         
            -
            			case "get":
         
     | 
| 
       408 
     | 
    
         
            -
            				{
         
     | 
| 
       409 
     | 
    
         
            -
            					const key = commands[2]
         
     | 
| 
       410 
     | 
    
         
            -
            					key ? log(exploreObject(await configPromise, key.split("."))) : console.log(await configPromise)
         
     | 
| 
       411 
     | 
    
         
            -
            				}
         
     | 
| 
       412 
     | 
    
         
            -
            				break
         
     | 
| 
       413 
     | 
    
         
            -
            			case "delete":
         
     | 
| 
       414 
     | 
    
         
            -
            				{
         
     | 
| 
       415 
     | 
    
         
            -
            					const key = commands[2]
         
     | 
| 
       416 
     | 
    
         
            -
            					if (!key) {
         
     | 
| 
       417 
     | 
    
         
            -
            						logError("Must provide a key to delete\n")
         
     | 
| 
       418 
     | 
    
         
            -
            						logHelp()
         
     | 
| 
       419 
     | 
    
         
            -
            						break
         
     | 
| 
       420 
     | 
    
         
            -
            					}
         
     | 
| 
       421 
     | 
    
         
            -
            					const keyParts = key.split("."),
         
     | 
| 
       422 
     | 
    
         
            -
            						pathName = keyParts
         
     | 
| 
       423 
     | 
    
         
            -
            							.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
         
     | 
| 
       424 
     | 
    
         
            -
            							.join("."),
         
     | 
| 
       425 
     | 
    
         
            -
            						lastKey = keyParts.pop(),
         
     | 
| 
       426 
     | 
    
         
            -
            						config = await configPromise
         
     | 
| 
       427 
     | 
    
         
            -
            					delete exploreObject(config, keyParts)?.[lastKey]
         
     | 
| 
       428 
     | 
    
         
            -
            					log(`Removed ${colourV(pathName)} from config file`)
         
     | 
| 
       429 
     | 
    
         
            -
            				}
         
     | 
| 
       430 
     | 
    
         
            -
            				break
         
     | 
| 
       431 
     | 
    
         
            -
            			case "set":
         
     | 
| 
       432 
     | 
    
         
            -
            				{
         
     | 
| 
       433 
     | 
    
         
            -
            					const key = commands[2],
         
     | 
| 
       434 
     | 
    
         
            -
            						value = commands[3]
         
     | 
| 
       435 
     | 
    
         
            -
            					if (!key) {
         
     | 
| 
       436 
     | 
    
         
            -
            						logError("Must provide a key and value\n")
         
     | 
| 
       437 
     | 
    
         
            -
            						logHelp()
         
     | 
| 
       438 
     | 
    
         
            -
            						break
         
     | 
| 
       439 
     | 
    
         
            -
            					}
         
     | 
| 
       440 
     | 
    
         
            -
            					const keys = key.split("."),
         
     | 
| 
       441 
     | 
    
         
            -
            						pathName = keys
         
     | 
| 
       442 
     | 
    
         
            -
            							.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
         
     | 
| 
       443 
     | 
    
         
            -
            							.join(".")
         
     | 
| 
       444 
     | 
    
         
            -
            					if (!value) {
         
     | 
| 
       445 
     | 
    
         
            -
            						logError(`Must provide a value for the key ${pathName}\n`)
         
     | 
| 
       446 
     | 
    
         
            -
            						logHelp()
         
     | 
| 
       447 
     | 
    
         
            -
            						break
         
     | 
| 
       448 
     | 
    
         
            -
            					}
         
     | 
| 
       449 
     | 
    
         
            -
            					const lastKey = keys.pop(),
         
     | 
| 
       450 
     | 
    
         
            -
            						config = await configPromise
         
     | 
| 
       451 
     | 
    
         
            -
            					if (keys.length || "hackmudPath" != lastKey) {
         
     | 
| 
       452 
     | 
    
         
            -
            						let object = config
         
     | 
| 
       453 
     | 
    
         
            -
            						for (const key of keys)
         
     | 
| 
       454 
     | 
    
         
            -
            							if ("object" == typeof object[key]) object = object[key]
         
     | 
| 
       455 
     | 
    
         
            -
            							else {
         
     | 
| 
       456 
     | 
    
         
            -
            								object[key] = {}
         
     | 
| 
       457 
     | 
    
         
            -
            								object = object[key]
         
     | 
| 
       458 
     | 
    
         
            -
            							}
         
     | 
| 
       459 
     | 
    
         
            -
            						object[lastKey] = value
         
     | 
| 
       460 
     | 
    
         
            -
            					} else config.hackmudPath = resolve(value.startsWith("~/") ? homedir() + value.slice(1) : value)
         
     | 
| 
       461 
     | 
    
         
            -
            					console.log(config)
         
     | 
| 
       462 
     | 
    
         
            -
            					await (async config => {
         
     | 
| 
       463 
     | 
    
         
            -
            						const json = JSON.stringify(config, void 0, "\t")
         
     | 
| 
       464 
     | 
    
         
            -
            						configDidNotExist && log("Creating config file at " + configFilePath)
         
     | 
| 
       465 
     | 
    
         
            -
            						await writeFile(configFilePath, json).catch(async error => {
         
     | 
| 
       466 
     | 
    
         
            -
            							switch (error.code) {
         
     | 
| 
       467 
     | 
    
         
            -
            								case "EISDIR":
         
     | 
| 
       468 
     | 
    
         
            -
            									await rmdir(configFilePath)
         
     | 
| 
       469 
     | 
    
         
            -
            									break
         
     | 
| 
       470 
     | 
    
         
            -
            								case "ENOENT":
         
     | 
| 
       471 
     | 
    
         
            -
            									await mkdir(configDirectoryPath)
         
     | 
| 
       472 
     | 
    
         
            -
            									break
         
     | 
| 
       473 
     | 
    
         
            -
            								default:
         
     | 
| 
       474 
     | 
    
         
            -
            									throw error
         
     | 
| 
       475 
     | 
    
         
            -
            							}
         
     | 
| 
       476 
     | 
    
         
            -
            							await writeFile(configFilePath, json)
         
     | 
| 
       477 
     | 
    
         
            -
            						})
         
     | 
| 
       478 
     | 
    
         
            -
            					})(config)
         
     | 
| 
       479 
     | 
    
         
            -
            				}
         
     | 
| 
       480 
     | 
    
         
            -
            				break
         
     | 
| 
       481 
     | 
    
         
            -
            			default:
         
     | 
| 
       482 
     | 
    
         
            -
            				commands[1] && logError(`Unknown command: ${JSON.stringify(commands[1])}\n`)
         
     | 
| 
       483 
     | 
    
         
            -
            				logHelp()
         
     | 
| 
       484 
     | 
    
         
            -
            		}
         
     | 
| 
       485 
     | 
    
         
            -
            		break
         
     | 
| 
       486 
256 
     | 
    
         
             
            	case "help":
         
     | 
| 
       487 
257 
     | 
    
         
             
            	case "h":
         
     | 
| 
       488 
258 
     | 
    
         
             
            		logHelp()
         
     | 
| 
         @@ -510,10 +280,12 @@ switch (commands[0]) { 
     | 
|
| 
       510 
280 
     | 
    
         
             
            				scriptUser =
         
     | 
| 
       511 
281 
     | 
    
         
             
            					"scripts" == basename(resolve(target, "..")) && "hackmud" == basename(resolve(target, "../../..")) ?
         
     | 
| 
       512 
282 
     | 
    
         
             
            						basename(resolve(target, "../.."))
         
     | 
| 
       513 
     | 
    
         
            -
            					:	 
     | 
| 
       514 
     | 
    
         
            -
            				 
     | 
| 
       515 
     | 
    
         
            -
            			if (options.has("skip-minify") && options.has("mangle-names")) {
         
     | 
| 
       516 
     | 
    
         
            -
            				logError( 
     | 
| 
      
 283 
     | 
    
         
            +
            					:	void 0,
         
     | 
| 
      
 284 
     | 
    
         
            +
            				optionsHasNoMinify = options.has("no-minify")
         
     | 
| 
      
 285 
     | 
    
         
            +
            			if ((optionsHasNoMinify || options.has("skip-minify")) && options.has("mangle-names")) {
         
     | 
| 
      
 286 
     | 
    
         
            +
            				logError(
         
     | 
| 
      
 287 
     | 
    
         
            +
            					`Options ${colourN("--mangle-names")} and ${colourN(optionsHasNoMinify ? "--no-minify" : "--skip-minify")} are incompatible\n`
         
     | 
| 
      
 288 
     | 
    
         
            +
            				)
         
     | 
| 
       517 
289 
     | 
    
         
             
            				logHelp()
         
     | 
| 
       518 
290 
     | 
    
         
             
            				break
         
     | 
| 
       519 
291 
     | 
    
         
             
            			}
         
     | 
| 
         @@ -544,36 +316,31 @@ switch (commands[0]) { 
     | 
|
| 
       544 
316 
     | 
    
         
             
            					: fileBaseName + ".js"
         
     | 
| 
       545 
317 
     | 
    
         
             
            				)
         
     | 
| 
       546 
318 
     | 
    
         
             
            			const golfFile = () =>
         
     | 
| 
       547 
     | 
    
         
            -
            				readFile(target, { encoding: "utf-8" }).then(
         
     | 
| 
       548 
     | 
    
         
            -
            					 
     | 
| 
       549 
     | 
    
         
            -
            						 
     | 
| 
       550 
     | 
    
         
            -
            							 
     | 
| 
       551 
     | 
    
         
            -
             
     | 
| 
       552 
     | 
    
         
            -
             
     | 
| 
       553 
     | 
    
         
            -
             
     | 
| 
       554 
     | 
    
         
            -
             
     | 
| 
       555 
     | 
    
         
            -
             
     | 
| 
       556 
     | 
    
         
            -
             
     | 
| 
       557 
     | 
    
         
            -
             
     | 
| 
       558 
     | 
    
         
            -
             
     | 
| 
       559 
     | 
    
         
            -
            						 
     | 
| 
       560 
     | 
    
         
            -
             
     | 
| 
       561 
     | 
    
         
            -
            						 
     | 
| 
       562 
     | 
    
         
            -
            							 
     | 
| 
       563 
     | 
    
         
            -
             
     | 
| 
       564 
     | 
    
         
            -
             
     | 
| 
       565 
     | 
    
         
            -
             
     | 
| 
       566 
     | 
    
         
            -
             
     | 
| 
       567 
     | 
    
         
            -
            							 
     | 
| 
       568 
     | 
    
         
            -
            								()  
     | 
| 
       569 
     | 
    
         
            -
            									log(
         
     | 
| 
       570 
     | 
    
         
            -
            										`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
         
     | 
| 
       571 
     | 
    
         
            -
            									),
         
     | 
| 
       572 
     | 
    
         
            -
            								error => logError(error.message)
         
     | 
| 
      
 319 
     | 
    
         
            +
            				readFile(target, { encoding: "utf-8" }).then(async source => {
         
     | 
| 
      
 320 
     | 
    
         
            +
            					const timeStart = performance.now(),
         
     | 
| 
      
 321 
     | 
    
         
            +
            						{ script, warnings } = await processScript(source, {
         
     | 
| 
      
 322 
     | 
    
         
            +
            							minify: !(options.get("no-minify") || options.get("skip-minify")),
         
     | 
| 
      
 323 
     | 
    
         
            +
            							scriptUser,
         
     | 
| 
      
 324 
     | 
    
         
            +
            							scriptName,
         
     | 
| 
      
 325 
     | 
    
         
            +
            							filePath: target,
         
     | 
| 
      
 326 
     | 
    
         
            +
            							mangleNames,
         
     | 
| 
      
 327 
     | 
    
         
            +
            							forceQuineCheats
         
     | 
| 
      
 328 
     | 
    
         
            +
            						}),
         
     | 
| 
      
 329 
     | 
    
         
            +
            						timeTook = performance.now() - timeStart
         
     | 
| 
      
 330 
     | 
    
         
            +
            					for (const { message, line } of warnings)
         
     | 
| 
      
 331 
     | 
    
         
            +
            						log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
         
     | 
| 
      
 332 
     | 
    
         
            +
            					await writeFilePersistent(outputPath, script)
         
     | 
| 
      
 333 
     | 
    
         
            +
            						.catch(error => {
         
     | 
| 
      
 334 
     | 
    
         
            +
            							if (!commands[2] || "EISDIR" != error.code) throw error
         
     | 
| 
      
 335 
     | 
    
         
            +
            							outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
         
     | 
| 
      
 336 
     | 
    
         
            +
            							return writeFilePersistent(outputPath, script)
         
     | 
| 
      
 337 
     | 
    
         
            +
            						})
         
     | 
| 
      
 338 
     | 
    
         
            +
            						.then(() =>
         
     | 
| 
      
 339 
     | 
    
         
            +
            							log(
         
     | 
| 
      
 340 
     | 
    
         
            +
            								`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
         
     | 
| 
       573 
341 
     | 
    
         
             
            							)
         
     | 
| 
       574 
     | 
    
         
            -
             
     | 
| 
       575 
     | 
    
         
            -
             
     | 
| 
       576 
     | 
    
         
            -
            				)
         
     | 
| 
      
 342 
     | 
    
         
            +
            						)
         
     | 
| 
      
 343 
     | 
    
         
            +
            				})
         
     | 
| 
       577 
344 
     | 
    
         
             
            			if (options.get("watch")) {
         
     | 
| 
       578 
345 
     | 
    
         
             
            				const { watch: watchFile } = await chokidarModule
         
     | 
| 
       579 
346 
     | 
    
         
             
            				watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
         
     | 
| 
         @@ -584,7 +351,86 @@ switch (commands[0]) { 
     | 
|
| 
       584 
351 
     | 
    
         
             
            		}
         
     | 
| 
       585 
352 
     | 
    
         
             
            		break
         
     | 
| 
       586 
353 
     | 
    
         
             
            	default:
         
     | 
| 
       587 
     | 
    
         
            -
            		commands[0] && logError(`Unknown command: ${ 
     | 
| 
      
 354 
     | 
    
         
            +
            		commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
         
     | 
| 
       588 
355 
     | 
    
         
             
            		logHelp()
         
     | 
| 
       589 
356 
     | 
    
         
             
            }
         
     | 
| 
       590 
357 
     | 
    
         
             
            autoExit && process.exit()
         
     | 
| 
      
 358 
     | 
    
         
            +
            function logHelp() {
         
     | 
| 
      
 359 
     | 
    
         
            +
            	const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
         
     | 
| 
      
 360 
     | 
    
         
            +
            		forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`,
         
     | 
| 
      
 361 
     | 
    
         
            +
            		hackmudPathOption = `${colourN("--hackmud-path")}=${colourB("<path>")}\n    Override hackmud path`
         
     | 
| 
      
 362 
     | 
    
         
            +
            	console.log(colourN("Version") + colourS(": ") + colourV(version))
         
     | 
| 
      
 363 
     | 
    
         
            +
            	switch (commands[0]) {
         
     | 
| 
      
 364 
     | 
    
         
            +
            		case "dev":
         
     | 
| 
      
 365 
     | 
    
         
            +
            		case "watch":
         
     | 
| 
      
 366 
     | 
    
         
            +
            		case "push":
         
     | 
| 
      
 367 
     | 
    
         
            +
            			console.log(
         
     | 
| 
      
 368 
     | 
    
         
            +
            				colourS(
         
     | 
| 
      
 369 
     | 
    
         
            +
            					`\n${colourJ("push" == commands[0] ? pushCommandDescription : "Watch a directory and push a script when modified")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB('<directory> ["<script user>.<script name>"...]')}\n\n${colourA("Arguments:")}\n${colourB("<directory>")}\n    The source directory containing your scripts\n${colourB("<script user>")}\n    A user to push script(s) to. Can be set to wild card (${colourV("*")}) which will try\n    and discover users to push to\n${colourB("<script name>")}\n    Name of a script to push. Can be set to wild card (${colourV("*")}) to find all scripts\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n    Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n    Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n    ${forceQuineCheatsOptionDescription}\n${hackmudPathOption}\n${"push" == commands[0] ? "" : `${colourN("--type-declaration-path")}=${colourB("<path>")}\n    Path to generate a type declaration file for the scripts\n`}\n${colourA("Examples:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourV("src")}\n\tPushes 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\tPushes 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\tPushes 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\tPushes all scripts found in ${colourV("src")} folder to all users`
         
     | 
| 
      
 370 
     | 
    
         
            +
            				)
         
     | 
| 
      
 371 
     | 
    
         
            +
            			)
         
     | 
| 
      
 372 
     | 
    
         
            +
            			break
         
     | 
| 
      
 373 
     | 
    
         
            +
            		case "pull":
         
     | 
| 
      
 374 
     | 
    
         
            +
            			console.log(
         
     | 
| 
      
 375 
     | 
    
         
            +
            				colourS(
         
     | 
| 
      
 376 
     | 
    
         
            +
            					`\n${colourJ("Pull a script a from a hackmud user's script directory")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<script user>")}${colourV(".")}${colourB("<script name>")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
         
     | 
| 
      
 377 
     | 
    
         
            +
            				)
         
     | 
| 
      
 378 
     | 
    
         
            +
            			)
         
     | 
| 
      
 379 
     | 
    
         
            +
            			break
         
     | 
| 
      
 380 
     | 
    
         
            +
            		case "minify":
         
     | 
| 
      
 381 
     | 
    
         
            +
            		case "golf":
         
     | 
| 
      
 382 
     | 
    
         
            +
            			console.log(
         
     | 
| 
      
 383 
     | 
    
         
            +
            				colourS(
         
     | 
| 
      
 384 
     | 
    
         
            +
            					`\n${colourJ("Minify a script file on the spot")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<target> [output path]")}\n\n${colourA("Options:")}\n${colourN("--no-minify")}\n    Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n    Reduce character count further but lose function names in error call stacks\n${colourN("--force-quine-cheats")}\n    ${forceQuineCheatsOptionDescription}\n${colourN("--watch")}\n    Watch for changes`
         
     | 
| 
      
 385 
     | 
    
         
            +
            				)
         
     | 
| 
      
 386 
     | 
    
         
            +
            			)
         
     | 
| 
      
 387 
     | 
    
         
            +
            			break
         
     | 
| 
      
 388 
     | 
    
         
            +
            		case "generate-type-declaration":
         
     | 
| 
      
 389 
     | 
    
         
            +
            		case "gen-type-declaration":
         
     | 
| 
      
 390 
     | 
    
         
            +
            		case "gen-dts":
         
     | 
| 
      
 391 
     | 
    
         
            +
            		case "gen-types":
         
     | 
| 
      
 392 
     | 
    
         
            +
            			console.log(
         
     | 
| 
      
 393 
     | 
    
         
            +
            				colourS(
         
     | 
| 
      
 394 
     | 
    
         
            +
            					`${colourJ("Generate a type declaration file for a directory of scripts")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(commands[0])} ${colourB("<directory> [output path]")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
         
     | 
| 
      
 395 
     | 
    
         
            +
            				)
         
     | 
| 
      
 396 
     | 
    
         
            +
            			)
         
     | 
| 
      
 397 
     | 
    
         
            +
            			break
         
     | 
| 
      
 398 
     | 
    
         
            +
            		case "sync-macros":
         
     | 
| 
      
 399 
     | 
    
         
            +
            			console.log(
         
     | 
| 
      
 400 
     | 
    
         
            +
            				colourS(
         
     | 
| 
      
 401 
     | 
    
         
            +
            					`\n${colourJ("Sync macros across all hackmud users")}\n\n${colourA("Options:")}\n${hackmudPathOption}`
         
     | 
| 
      
 402 
     | 
    
         
            +
            				)
         
     | 
| 
      
 403 
     | 
    
         
            +
            			)
         
     | 
| 
      
 404 
     | 
    
         
            +
            			break
         
     | 
| 
      
 405 
     | 
    
         
            +
            		default:
         
     | 
| 
      
 406 
     | 
    
         
            +
            			console.log(
         
     | 
| 
      
 407 
     | 
    
         
            +
            				colourS(
         
     | 
| 
      
 408 
     | 
    
         
            +
            					`\n${colourJ("Hackmud Script Manager")}\n\n${colourA("Commands:")}\n${colourL("push")}\n    ${pushCommandDescription}\n${colourL("dev")}\n    Watch a directory and push a script when modified\n${colourL("golf")}\n    Minify a script file on the spot\n${colourL("gen-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`
         
     | 
| 
      
 409 
     | 
    
         
            +
            				)
         
     | 
| 
      
 410 
     | 
    
         
            +
            			)
         
     | 
| 
      
 411 
     | 
    
         
            +
            	}
         
     | 
| 
      
 412 
     | 
    
         
            +
            }
         
     | 
| 
      
 413 
     | 
    
         
            +
            function logInfo({ file, users, minLength, error }, hackmudPath) {
         
     | 
| 
      
 414 
     | 
    
         
            +
            	error ?
         
     | 
| 
      
 415 
     | 
    
         
            +
            		logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
         
     | 
| 
      
 416 
     | 
    
         
            +
            	:	console.log(
         
     | 
| 
      
 417 
     | 
    
         
            +
            			`pushed ${chalk.bold(file)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(minLength + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(file, extname(file))) + ".js")}`
         
     | 
| 
      
 418 
     | 
    
         
            +
            		)
         
     | 
| 
      
 419 
     | 
    
         
            +
            }
         
     | 
| 
      
 420 
     | 
    
         
            +
            function logError(message) {
         
     | 
| 
      
 421 
     | 
    
         
            +
            	console.error(colourD(message))
         
     | 
| 
      
 422 
     | 
    
         
            +
            	process.exitCode = 1
         
     | 
| 
      
 423 
     | 
    
         
            +
            }
         
     | 
| 
      
 424 
     | 
    
         
            +
            function getHackmudPath() {
         
     | 
| 
      
 425 
     | 
    
         
            +
            	const hackmudPathOption = options.get("hackmud-path")
         
     | 
| 
      
 426 
     | 
    
         
            +
            	if (null != hackmudPathOption && "string" != typeof hackmudPathOption) {
         
     | 
| 
      
 427 
     | 
    
         
            +
            		logError(`Option ${colourN("--hackmud-path")} must be a string, got ${colourV(hackmudPathOption)}\n`)
         
     | 
| 
      
 428 
     | 
    
         
            +
            		logHelp()
         
     | 
| 
      
 429 
     | 
    
         
            +
            		process.exit(1)
         
     | 
| 
      
 430 
     | 
    
         
            +
            	}
         
     | 
| 
      
 431 
     | 
    
         
            +
            	return (
         
     | 
| 
      
 432 
     | 
    
         
            +
            		hackmudPathOption ||
         
     | 
| 
      
 433 
     | 
    
         
            +
            		process.env.HSM_HACKMUD_PATH ||
         
     | 
| 
      
 434 
     | 
    
         
            +
            		("win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud"))
         
     | 
| 
      
 435 
     | 
    
         
            +
            	)
         
     | 
| 
      
 436 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -1,2 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            export declare  
     | 
| 
       2 
     | 
    
         
            -
            export default generateTypeDeclaration;
         
     | 
| 
      
 1 
     | 
    
         
            +
            export declare function generateTypeDeclaration(sourceDirectory: string, hackmudPath?: string): Promise<string>;
         
     | 
| 
         @@ -1,31 +1,31 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import {  
     | 
| 
      
 1 
     | 
    
         
            +
            import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
         
     | 
| 
       2 
2 
     | 
    
         
             
            import { basename, resolve } from "path"
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
         
     | 
| 
       4 
4 
     | 
    
         
             
            	const users = new Set()
         
     | 
| 
       5 
5 
     | 
    
         
             
            	if (hackmudPath)
         
     | 
| 
       6 
     | 
    
         
            -
            		for (const  
     | 
| 
       7 
     | 
    
         
            -
            			 
     | 
| 
      
 6 
     | 
    
         
            +
            		for (const { stats, name } of await readDirectoryWithStats(hackmudPath))
         
     | 
| 
      
 7 
     | 
    
         
            +
            			stats.isFile() && name.endsWith(".key") && users.add(basename(name, ".key"))
         
     | 
| 
       8 
8 
     | 
    
         
             
            	const wildScripts = [],
         
     | 
| 
       9 
9 
     | 
    
         
             
            		wildAnyScripts = [],
         
     | 
| 
       10 
10 
     | 
    
         
             
            		allScripts = {},
         
     | 
| 
       11 
11 
     | 
    
         
             
            		allAnyScripts = {}
         
     | 
| 
       12 
12 
     | 
    
         
             
            	await Promise.all(
         
     | 
| 
       13 
     | 
    
         
            -
            		(await  
     | 
| 
       14 
     | 
    
         
            -
            			if ( 
     | 
| 
       15 
     | 
    
         
            -
            				 
     | 
| 
       16 
     | 
    
         
            -
            					 
     | 
| 
       17 
     | 
    
         
            -
            				:	 
     | 
| 
       18 
     | 
    
         
            -
            			else if ( 
     | 
| 
      
 13 
     | 
    
         
            +
            		(await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name }) => {
         
     | 
| 
      
 14 
     | 
    
         
            +
            			if (stats.isFile())
         
     | 
| 
      
 15 
     | 
    
         
            +
            				name.endsWith(".ts") ?
         
     | 
| 
      
 16 
     | 
    
         
            +
            					name.endsWith(".d.ts") || wildScripts.push(basename(name, ".ts"))
         
     | 
| 
      
 17 
     | 
    
         
            +
            				:	name.endsWith(".js") && wildAnyScripts.push(basename(name, ".js"))
         
     | 
| 
      
 18 
     | 
    
         
            +
            			else if (stats.isDirectory()) {
         
     | 
| 
       19 
19 
     | 
    
         
             
            				const scripts = [],
         
     | 
| 
       20 
20 
     | 
    
         
             
            					anyScripts = []
         
     | 
| 
       21 
     | 
    
         
            -
            				allScripts[ 
     | 
| 
       22 
     | 
    
         
            -
            				allAnyScripts[ 
     | 
| 
       23 
     | 
    
         
            -
            				users.add( 
     | 
| 
       24 
     | 
    
         
            -
            				for (const  
     | 
| 
       25 
     | 
    
         
            -
            					 
     | 
| 
       26 
     | 
    
         
            -
            						( 
     | 
| 
       27 
     | 
    
         
            -
            							 
     | 
| 
       28 
     | 
    
         
            -
            						:	 
     | 
| 
      
 21 
     | 
    
         
            +
            				allScripts[name] = scripts
         
     | 
| 
      
 22 
     | 
    
         
            +
            				allAnyScripts[name] = anyScripts
         
     | 
| 
      
 23 
     | 
    
         
            +
            				users.add(name)
         
     | 
| 
      
 24 
     | 
    
         
            +
            				for (const child of await readDirectoryWithStats(resolve(sourceDirectory, name)))
         
     | 
| 
      
 25 
     | 
    
         
            +
            					child.stats.isFile() &&
         
     | 
| 
      
 26 
     | 
    
         
            +
            						(child.name.endsWith(".ts") ?
         
     | 
| 
      
 27 
     | 
    
         
            +
            							name.endsWith(".d.ts") || scripts.push(basename(child.name, ".ts"))
         
     | 
| 
      
 28 
     | 
    
         
            +
            						:	child.name.endsWith(".js") && anyScripts.push(basename(child.name, ".js")))
         
     | 
| 
       29 
29 
     | 
    
         
             
            			}
         
     | 
| 
       30 
30 
     | 
    
         
             
            		})
         
     | 
| 
       31 
31 
     | 
    
         
             
            	)
         
     | 
| 
         @@ -65,4 +65,4 @@ const generateTypeDeclaration = async (sourceDirectory, hackmudPath) => { 
     | 
|
| 
       65 
65 
     | 
    
         
             
            	o += "}\n"
         
     | 
| 
       66 
66 
     | 
    
         
             
            	return o
         
     | 
| 
       67 
67 
     | 
    
         
             
            }
         
     | 
| 
       68 
     | 
    
         
            -
            export { generateTypeDeclaration  
     | 
| 
      
 68 
     | 
    
         
            +
            export { generateTypeDeclaration }
         
     | 
    
        package/index.js
    CHANGED
    
    | 
         @@ -5,7 +5,7 @@ export { pull } from "./pull.js" 
     | 
|
| 
       5 
5 
     | 
    
         
             
            export { push } from "./push.js"
         
     | 
| 
       6 
6 
     | 
    
         
             
            export { syncMacros } from "./syncMacros.js"
         
     | 
| 
       7 
7 
     | 
    
         
             
            export { watch } from "./watch.js"
         
     | 
| 
       8 
     | 
    
         
            -
            import " 
     | 
| 
      
 8 
     | 
    
         
            +
            import "@samual/lib/readDirectoryWithStats"
         
     | 
| 
       9 
9 
     | 
    
         
             
            import "path"
         
     | 
| 
       10 
10 
     | 
    
         
             
            import "@babel/generator"
         
     | 
| 
       11 
11 
     | 
    
         
             
            import "@babel/parser"
         
     | 
| 
         @@ -47,4 +47,5 @@ import "@samual/lib/clearObject" 
     | 
|
| 
       47 
47 
     | 
    
         
             
            import "@samual/lib/copyFilePersistent"
         
     | 
| 
       48 
48 
     | 
    
         
             
            import "@samual/lib/Cache"
         
     | 
| 
       49 
49 
     | 
    
         
             
            import "@samual/lib/writeFilePersistent"
         
     | 
| 
      
 50 
     | 
    
         
            +
            import "fs/promises"
         
     | 
| 
       50 
51 
     | 
    
         
             
            import "chokidar"
         
     |