hackmud-script-manager 0.19.1-003b022 → 0.19.1-07fc9cb
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/bin/hsm.js +125 -290
- package/generateTypeDeclaration.js +1 -1
- package/package.json +5 -7
- package/processScript/index.js +257 -240
- package/processScript/minify.js +380 -394
- package/processScript/preprocess.js +93 -93
- package/processScript/shared.js +11 -11
- package/processScript/transform.js +566 -559
- package/pull.js +1 -1
- package/push.js +2 -2
- package/{bin → src/bin}/hsm.d.ts +0 -0
- package/src/generateTypeDeclaration.d.ts +2 -0
- package/src/processScript/index.d.ts +31 -0
- package/src/processScript/minify.d.ts +18 -0
- package/src/processScript/preprocess.d.ts +9 -0
- package/{processScript → src/processScript}/shared.d.ts +1 -1
- package/src/processScript/transform.d.ts +18 -0
- package/src/pull.d.ts +6 -0
- package/src/push.d.ts +29 -0
- package/{syncMacros.d.ts → src/syncMacros.d.ts} +1 -1
- package/src/watch.d.ts +15 -0
- package/syncMacros.js +1 -1
- package/watch.js +11 -11
- package/generateTypeDeclaration.d.ts +0 -2
- package/processScript/index.d.ts +0 -40
- package/processScript/minify.d.ts +0 -24
- package/processScript/preprocess.d.ts +0 -12
- package/processScript/transform.d.ts +0 -24
- package/pull.d.ts +0 -9
- package/push.d.ts +0 -37
- package/tsconfig.tsbuildinfo +0 -1
- package/watch.d.ts +0 -20
- /package/{constants.d.ts → src/constants.d.ts} +0 -0
- /package/{index.d.ts → src/index.d.ts} +0 -0
- /package/{processScript → src/processScript}/postprocess.d.ts +0 -0
    
        package/bin/hsm.js
    CHANGED
    
    | @@ -3,17 +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 13 | 
             
            import "@samual/lib/readDirectoryWithStats"
         | 
| 14 14 | 
             
            import "@samual/lib/copyFilePersistent"
         | 
| 15 | 
            -
            const  | 
| 16 | 
            -
            	configFilePath = resolve(configDirectoryPath, "hsm.json"),
         | 
| 15 | 
            +
            const version = "0.19.1-07fc9cb",
         | 
| 17 16 | 
             
            	options = new Map(),
         | 
| 18 17 | 
             
            	commands = [],
         | 
| 19 18 | 
             
            	userColours = new Cache(user => {
         | 
| @@ -21,119 +20,7 @@ const configDirectoryPath = resolve(homedir(), ".config"), | |
| 21 20 | 
             
            		for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
         | 
| 22 21 | 
             
            		return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
         | 
| 23 22 | 
             
            	}),
         | 
| 24 | 
            -
            	 | 
| 25 | 
            -
            		console.error(
         | 
| 26 | 
            -
            			colourS(
         | 
| 27 | 
            -
            				`${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>")}"`
         | 
| 28 | 
            -
            			)
         | 
| 29 | 
            -
            		),
         | 
| 30 | 
            -
            	logHelp = () => {
         | 
| 31 | 
            -
            		const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
         | 
| 32 | 
            -
            			mangleNamesOptionDescription =
         | 
| 33 | 
            -
            				"Reduce character count further but lose function names in error call stacks",
         | 
| 34 | 
            -
            			forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off.`
         | 
| 35 | 
            -
            		console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-003b022"))
         | 
| 36 | 
            -
            		switch (commands[0]) {
         | 
| 37 | 
            -
            			case "config":
         | 
| 38 | 
            -
            				switch (commands[1]) {
         | 
| 39 | 
            -
            					case "get":
         | 
| 40 | 
            -
            						console.log(
         | 
| 41 | 
            -
            							`\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
         | 
| 42 | 
            -
            						)
         | 
| 43 | 
            -
            						break
         | 
| 44 | 
            -
            					case "set":
         | 
| 45 | 
            -
            						console.log(
         | 
| 46 | 
            -
            							`\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
         | 
| 47 | 
            -
            						)
         | 
| 48 | 
            -
            						break
         | 
| 49 | 
            -
            					case "delete":
         | 
| 50 | 
            -
            						console.log(
         | 
| 51 | 
            -
            							`\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>")}`
         | 
| 52 | 
            -
            						)
         | 
| 53 | 
            -
            						break
         | 
| 54 | 
            -
            					default:
         | 
| 55 | 
            -
            						console.log(
         | 
| 56 | 
            -
            							colourS(
         | 
| 57 | 
            -
            								`${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`
         | 
| 58 | 
            -
            							)
         | 
| 59 | 
            -
            						)
         | 
| 60 | 
            -
            				}
         | 
| 61 | 
            -
            				break
         | 
| 62 | 
            -
            			case "push":
         | 
| 63 | 
            -
            				console.log(
         | 
| 64 | 
            -
            					colourS(
         | 
| 65 | 
            -
            						`\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("--no-minify")}\n    Skip minification to produce a "readable" script\n${colourN("--mangle-names")}\n    ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n    ${forceQuineCheatsOptionDescription}`
         | 
| 66 | 
            -
            					)
         | 
| 67 | 
            -
            				)
         | 
| 68 | 
            -
            				break
         | 
| 69 | 
            -
            			case "dev":
         | 
| 70 | 
            -
            			case "watch":
         | 
| 71 | 
            -
            				console.log(
         | 
| 72 | 
            -
            					colourS(
         | 
| 73 | 
            -
            						`\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("--no-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    ${forceQuineCheatsOptionDescription}`
         | 
| 74 | 
            -
            					)
         | 
| 75 | 
            -
            				)
         | 
| 76 | 
            -
            				break
         | 
| 77 | 
            -
            			case "pull":
         | 
| 78 | 
            -
            				console.log(
         | 
| 79 | 
            -
            					colourS(
         | 
| 80 | 
            -
            						`\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>")}`
         | 
| 81 | 
            -
            					)
         | 
| 82 | 
            -
            				)
         | 
| 83 | 
            -
            				break
         | 
| 84 | 
            -
            			case "minify":
         | 
| 85 | 
            -
            			case "golf":
         | 
| 86 | 
            -
            				console.log(
         | 
| 87 | 
            -
            					colourS(
         | 
| 88 | 
            -
            						`\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    ${mangleNamesOptionDescription}\n${colourN("--force-quine-cheats")}\n    ${forceQuineCheatsOptionDescription}\n${colourN("--watch")}\n    Watch for changes`
         | 
| 89 | 
            -
            					)
         | 
| 90 | 
            -
            				)
         | 
| 91 | 
            -
            				break
         | 
| 92 | 
            -
            			case "generate-type-declaration":
         | 
| 93 | 
            -
            			case "gen-type-declaration":
         | 
| 94 | 
            -
            			case "gen-dts":
         | 
| 95 | 
            -
            			case "gen-types":
         | 
| 96 | 
            -
            				console.log(
         | 
| 97 | 
            -
            					colourS(
         | 
| 98 | 
            -
            						`${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]")}`
         | 
| 99 | 
            -
            					)
         | 
| 100 | 
            -
            				)
         | 
| 101 | 
            -
            				break
         | 
| 102 | 
            -
            			case "sync-macros":
         | 
| 103 | 
            -
            				console.log("\n" + colourJ("Sync macros across all hackmud users"))
         | 
| 104 | 
            -
            				break
         | 
| 105 | 
            -
            			default:
         | 
| 106 | 
            -
            				console.log(
         | 
| 107 | 
            -
            					colourS(
         | 
| 108 | 
            -
            						`\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("config")}\n    Modify and view the config file\n${colourL("pull")}\n    Pull a script a from a hackmud user's script directory`
         | 
| 109 | 
            -
            					)
         | 
| 110 | 
            -
            				)
         | 
| 111 | 
            -
            		}
         | 
| 112 | 
            -
            	},
         | 
| 113 | 
            -
            	exploreObject = (object, keys, createPath = !1) => {
         | 
| 114 | 
            -
            		for (const key of keys)
         | 
| 115 | 
            -
            			object =
         | 
| 116 | 
            -
            				createPath ?
         | 
| 117 | 
            -
            					"object" == typeof object[key] ?
         | 
| 118 | 
            -
            						object[key]
         | 
| 119 | 
            -
            					:	(object[key] = {})
         | 
| 120 | 
            -
            				:	object?.[key]
         | 
| 121 | 
            -
            		return object
         | 
| 122 | 
            -
            	},
         | 
| 123 | 
            -
            	logInfo = ({ file, users, minLength, error }, hackmudPath) => {
         | 
| 124 | 
            -
            		error ?
         | 
| 125 | 
            -
            			logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
         | 
| 126 | 
            -
            		:	console.log(
         | 
| 127 | 
            -
            				`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")}`
         | 
| 128 | 
            -
            			)
         | 
| 129 | 
            -
            	},
         | 
| 130 | 
            -
            	log = message => {
         | 
| 131 | 
            -
            		console.log(colourS(message))
         | 
| 132 | 
            -
            	},
         | 
| 133 | 
            -
            	logError = message => {
         | 
| 134 | 
            -
            		console.error(colourD(message))
         | 
| 135 | 
            -
            		process.exitCode = 1
         | 
| 136 | 
            -
            	}
         | 
| 23 | 
            +
            	log = message => console.log(colourS(message))
         | 
| 137 24 | 
             
            for (const argument of process.argv.slice(2))
         | 
| 138 25 | 
             
            	if ("-" == argument[0]) {
         | 
| 139 26 | 
             
            		const [key, valueRaw] = argument.split("=")
         | 
| @@ -150,35 +37,10 @@ for (const argument of process.argv.slice(2)) | |
| 150 37 | 
             
            		else for (const option of key.slice(1)) options.set(option, value)
         | 
| 151 38 | 
             
            	} else commands.push(argument)
         | 
| 152 39 | 
             
            if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
         | 
| 153 | 
            -
            	console.log( | 
| 40 | 
            +
            	console.log(version)
         | 
| 154 41 | 
             
            	process.exit()
         | 
| 155 42 | 
             
            }
         | 
| 156 | 
            -
             | 
| 157 | 
            -
            const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
         | 
| 158 | 
            -
            		configFile => {
         | 
| 159 | 
            -
            			let temporaryConfig
         | 
| 160 | 
            -
            			try {
         | 
| 161 | 
            -
            				temporaryConfig = JSON.parse(configFile)
         | 
| 162 | 
            -
            			} catch {
         | 
| 163 | 
            -
            				log("Config file was corrupted, resetting")
         | 
| 164 | 
            -
            				return {}
         | 
| 165 | 
            -
            			}
         | 
| 166 | 
            -
            			if (!temporaryConfig || "object" != typeof temporaryConfig) {
         | 
| 167 | 
            -
            				log("Config file was corrupted, resetting")
         | 
| 168 | 
            -
            				return {}
         | 
| 169 | 
            -
            			}
         | 
| 170 | 
            -
            			if ("hackmudPath" in temporaryConfig && "string" != typeof temporaryConfig.hackmudPath) {
         | 
| 171 | 
            -
            				log('Property "hackmudPath" of config file was corrupted, removing')
         | 
| 172 | 
            -
            				delete temporaryConfig.hackmudPath
         | 
| 173 | 
            -
            			}
         | 
| 174 | 
            -
            			return temporaryConfig
         | 
| 175 | 
            -
            		},
         | 
| 176 | 
            -
            		() => {
         | 
| 177 | 
            -
            			configDidNotExist = !0
         | 
| 178 | 
            -
            			return {}
         | 
| 179 | 
            -
            		}
         | 
| 180 | 
            -
            	),
         | 
| 181 | 
            -
            	pushModule = import("../push.js"),
         | 
| 43 | 
            +
            const pushModule = import("../push.js"),
         | 
| 182 44 | 
             
            	processScriptModule = import("../processScript/index.js"),
         | 
| 183 45 | 
             
            	watchModule = import("../watch.js"),
         | 
| 184 46 | 
             
            	chokidarModule = import("chokidar"),
         | 
| @@ -203,12 +65,8 @@ let autoExit = !0 | |
| 203 65 | 
             
            switch (commands[0]) {
         | 
| 204 66 | 
             
            	case "push":
         | 
| 205 67 | 
             
            		{
         | 
| 206 | 
            -
            			const  | 
| 207 | 
            -
             | 
| 208 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 209 | 
            -
            				break
         | 
| 210 | 
            -
            			}
         | 
| 211 | 
            -
            			const sourcePath = commands[1]
         | 
| 68 | 
            +
            			const hackmudPath = getHackmudPath(),
         | 
| 69 | 
            +
            				sourcePath = commands[1]
         | 
| 212 70 | 
             
            			if (!sourcePath) {
         | 
| 213 71 | 
             
            				logError("Must provide the directory to push from\n")
         | 
| 214 72 | 
             
            				logHelp()
         | 
| @@ -276,12 +134,8 @@ switch (commands[0]) { | |
| 276 134 | 
             
            	case "dev":
         | 
| 277 135 | 
             
            	case "watch":
         | 
| 278 136 | 
             
            		{
         | 
| 279 | 
            -
            			const  | 
| 280 | 
            -
             | 
| 281 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 282 | 
            -
            				break
         | 
| 283 | 
            -
            			}
         | 
| 284 | 
            -
            			const sourcePath = commands[1]
         | 
| 137 | 
            +
            			const hackmudPath = getHackmudPath(),
         | 
| 138 | 
            +
            				sourcePath = commands[1]
         | 
| 285 139 | 
             
            			if (!sourcePath) {
         | 
| 286 140 | 
             
            				logError("Must provide the directory to watch\n")
         | 
| 287 141 | 
             
            				logHelp()
         | 
| @@ -354,34 +208,24 @@ switch (commands[0]) { | |
| 354 208 | 
             
            		break
         | 
| 355 209 | 
             
            	case "pull":
         | 
| 356 210 | 
             
            		{
         | 
| 357 | 
            -
            			const  | 
| 358 | 
            -
             | 
| 359 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 360 | 
            -
            				break
         | 
| 361 | 
            -
            			}
         | 
| 362 | 
            -
            			const script = commands[1]
         | 
| 211 | 
            +
            			const hackmudPath = getHackmudPath(),
         | 
| 212 | 
            +
            				script = commands[1]
         | 
| 363 213 | 
             
            			if (!script) {
         | 
| 364 214 | 
             
            				logError("Must provide the script to pull\n")
         | 
| 365 215 | 
             
            				logHelp()
         | 
| 366 216 | 
             
            				break
         | 
| 367 217 | 
             
            			}
         | 
| 368 218 | 
             
            			const sourcePath = commands[2] || "."
         | 
| 369 | 
            -
            			 | 
| 370 | 
            -
            				await pull(sourcePath, hackmudPath, script)
         | 
| 371 | 
            -
            			} catch (error) {
         | 
| 219 | 
            +
            			await pull(sourcePath, hackmudPath, script).catch(error => {
         | 
| 372 220 | 
             
            				console.error(error)
         | 
| 373 221 | 
             
            				logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
         | 
| 374 | 
            -
            			}
         | 
| 222 | 
            +
            			})
         | 
| 375 223 | 
             
            		}
         | 
| 376 224 | 
             
            		break
         | 
| 377 225 | 
             
            	case "sync-macros":
         | 
| 378 226 | 
             
            		{
         | 
| 379 | 
            -
            			const  | 
| 380 | 
            -
             | 
| 381 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 382 | 
            -
            				break
         | 
| 383 | 
            -
            			}
         | 
| 384 | 
            -
            			const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
         | 
| 227 | 
            +
            			const hackmudPath = getHackmudPath(),
         | 
| 228 | 
            +
            				{ macrosSynced, usersSynced } = await syncMacros(hackmudPath)
         | 
| 385 229 | 
             
            			log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
         | 
| 386 230 | 
             
            		}
         | 
| 387 231 | 
             
            		break
         | 
| @@ -398,100 +242,17 @@ switch (commands[0]) { | |
| 398 242 | 
             
            			}
         | 
| 399 243 | 
             
            			const sourcePath = resolve(target),
         | 
| 400 244 | 
             
            				outputPath = commands[2] || "./player.d.ts",
         | 
| 401 | 
            -
            				typeDeclaration = await generateTypeDeclaration(sourcePath, ( | 
| 245 | 
            +
            				typeDeclaration = await generateTypeDeclaration(sourcePath, getHackmudPath())
         | 
| 402 246 | 
             
            			let typeDeclarationPath = resolve(outputPath)
         | 
| 403 | 
            -
            			 | 
| 404 | 
            -
            				 | 
| 405 | 
            -
            			} catch (error) {
         | 
| 406 | 
            -
            				assert(error instanceof Error)
         | 
| 247 | 
            +
            			await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
         | 
| 248 | 
            +
            				assert(error instanceof Error, "src/bin/hsm.ts:327:35")
         | 
| 407 249 | 
             
            				if ("EISDIR" != error.code) throw error
         | 
| 408 250 | 
             
            				typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
         | 
| 409 | 
            -
            				 | 
| 410 | 
            -
            			}
         | 
| 251 | 
            +
            				return writeFile(typeDeclarationPath, typeDeclaration)
         | 
| 252 | 
            +
            			})
         | 
| 411 253 | 
             
            			log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
         | 
| 412 254 | 
             
            		}
         | 
| 413 255 | 
             
            		break
         | 
| 414 | 
            -
            	case "config":
         | 
| 415 | 
            -
            		switch (commands[1]) {
         | 
| 416 | 
            -
            			case "get":
         | 
| 417 | 
            -
            				{
         | 
| 418 | 
            -
            					const key = commands[2]
         | 
| 419 | 
            -
            					key ? log(exploreObject(await configPromise, key.split("."))) : console.log(await configPromise)
         | 
| 420 | 
            -
            				}
         | 
| 421 | 
            -
            				break
         | 
| 422 | 
            -
            			case "delete":
         | 
| 423 | 
            -
            				{
         | 
| 424 | 
            -
            					const key = commands[2]
         | 
| 425 | 
            -
            					if (!key) {
         | 
| 426 | 
            -
            						logError("Must provide a key to delete\n")
         | 
| 427 | 
            -
            						logHelp()
         | 
| 428 | 
            -
            						break
         | 
| 429 | 
            -
            					}
         | 
| 430 | 
            -
            					const keyParts = key.split("."),
         | 
| 431 | 
            -
            						pathName = keyParts
         | 
| 432 | 
            -
            							.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
         | 
| 433 | 
            -
            							.join("."),
         | 
| 434 | 
            -
            						lastKey = keyParts.pop(),
         | 
| 435 | 
            -
            						config = await configPromise
         | 
| 436 | 
            -
            					delete exploreObject(config, keyParts)?.[lastKey]
         | 
| 437 | 
            -
            					log(`Removed ${colourV(pathName)} from config file`)
         | 
| 438 | 
            -
            				}
         | 
| 439 | 
            -
            				break
         | 
| 440 | 
            -
            			case "set":
         | 
| 441 | 
            -
            				{
         | 
| 442 | 
            -
            					const key = commands[2],
         | 
| 443 | 
            -
            						value = commands[3]
         | 
| 444 | 
            -
            					if (!key) {
         | 
| 445 | 
            -
            						logError("Must provide a key and value\n")
         | 
| 446 | 
            -
            						logHelp()
         | 
| 447 | 
            -
            						break
         | 
| 448 | 
            -
            					}
         | 
| 449 | 
            -
            					const keys = key.split("."),
         | 
| 450 | 
            -
            						pathName = keys
         | 
| 451 | 
            -
            							.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
         | 
| 452 | 
            -
            							.join(".")
         | 
| 453 | 
            -
            					if (!value) {
         | 
| 454 | 
            -
            						logError(`Must provide a value for the key ${pathName}\n`)
         | 
| 455 | 
            -
            						logHelp()
         | 
| 456 | 
            -
            						break
         | 
| 457 | 
            -
            					}
         | 
| 458 | 
            -
            					const lastKey = keys.pop(),
         | 
| 459 | 
            -
            						config = await configPromise
         | 
| 460 | 
            -
            					if (keys.length || "hackmudPath" != lastKey) {
         | 
| 461 | 
            -
            						let object = config
         | 
| 462 | 
            -
            						for (const key of keys)
         | 
| 463 | 
            -
            							if ("object" == typeof object[key]) object = object[key]
         | 
| 464 | 
            -
            							else {
         | 
| 465 | 
            -
            								object[key] = {}
         | 
| 466 | 
            -
            								object = object[key]
         | 
| 467 | 
            -
            							}
         | 
| 468 | 
            -
            						object[lastKey] = value
         | 
| 469 | 
            -
            					} else config.hackmudPath = resolve(value.startsWith("~/") ? homedir() + value.slice(1) : value)
         | 
| 470 | 
            -
            					console.log(config)
         | 
| 471 | 
            -
            					await (async config => {
         | 
| 472 | 
            -
            						const json = JSON.stringify(config, void 0, "\t")
         | 
| 473 | 
            -
            						configDidNotExist && log("Creating config file at " + configFilePath)
         | 
| 474 | 
            -
            						await writeFile(configFilePath, json).catch(async error => {
         | 
| 475 | 
            -
            							switch (error.code) {
         | 
| 476 | 
            -
            								case "EISDIR":
         | 
| 477 | 
            -
            									await rmdir(configFilePath)
         | 
| 478 | 
            -
            									break
         | 
| 479 | 
            -
            								case "ENOENT":
         | 
| 480 | 
            -
            									await mkdir(configDirectoryPath)
         | 
| 481 | 
            -
            									break
         | 
| 482 | 
            -
            								default:
         | 
| 483 | 
            -
            									throw error
         | 
| 484 | 
            -
            							}
         | 
| 485 | 
            -
            							await writeFile(configFilePath, json)
         | 
| 486 | 
            -
            						})
         | 
| 487 | 
            -
            					})(config)
         | 
| 488 | 
            -
            				}
         | 
| 489 | 
            -
            				break
         | 
| 490 | 
            -
            			default:
         | 
| 491 | 
            -
            				commands[1] && logError(`Unknown command: ${JSON.stringify(commands[1])}\n`)
         | 
| 492 | 
            -
            				logHelp()
         | 
| 493 | 
            -
            		}
         | 
| 494 | 
            -
            		break
         | 
| 495 256 | 
             
            	case "help":
         | 
| 496 257 | 
             
            	case "h":
         | 
| 497 258 | 
             
            		logHelp()
         | 
| @@ -555,36 +316,31 @@ switch (commands[0]) { | |
| 555 316 | 
             
            					: fileBaseName + ".js"
         | 
| 556 317 | 
             
            				)
         | 
| 557 318 | 
             
            			const golfFile = () =>
         | 
| 558 | 
            -
            				readFile(target, { encoding: "utf-8" }).then(
         | 
| 559 | 
            -
            					 | 
| 560 | 
            -
            						 | 
| 561 | 
            -
            							 | 
| 562 | 
            -
             | 
| 563 | 
            -
             | 
| 564 | 
            -
             | 
| 565 | 
            -
             | 
| 566 | 
            -
             | 
| 567 | 
            -
             | 
| 568 | 
            -
             | 
| 569 | 
            -
             | 
| 570 | 
            -
            						 | 
| 571 | 
            -
             | 
| 572 | 
            -
            						 | 
| 573 | 
            -
            							 | 
| 574 | 
            -
             | 
| 575 | 
            -
             | 
| 576 | 
            -
             | 
| 577 | 
            -
             | 
| 578 | 
            -
            							 | 
| 579 | 
            -
            								()  | 
| 580 | 
            -
            									log(
         | 
| 581 | 
            -
            										`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
         | 
| 582 | 
            -
            									),
         | 
| 583 | 
            -
            								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`
         | 
| 584 341 | 
             
            							)
         | 
| 585 | 
            -
             | 
| 586 | 
            -
             | 
| 587 | 
            -
            				)
         | 
| 342 | 
            +
            						)
         | 
| 343 | 
            +
            				})
         | 
| 588 344 | 
             
            			if (options.get("watch")) {
         | 
| 589 345 | 
             
            				const { watch: watchFile } = await chokidarModule
         | 
| 590 346 | 
             
            				watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
         | 
| @@ -595,7 +351,86 @@ switch (commands[0]) { | |
| 595 351 | 
             
            		}
         | 
| 596 352 | 
             
            		break
         | 
| 597 353 | 
             
            	default:
         | 
| 598 | 
            -
            		commands[0] && logError(`Unknown command: ${ | 
| 354 | 
            +
            		commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
         | 
| 599 355 | 
             
            		logHelp()
         | 
| 600 356 | 
             
            }
         | 
| 601 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,6 +1,6 @@ | |
| 1 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 6 | 
             
            		for (const { stats, name } of await readDirectoryWithStats(hackmudPath))
         | 
    
        package/package.json
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            {
         | 
| 2 2 | 
             
              "name": "hackmud-script-manager",
         | 
| 3 | 
            -
              "version": "0.19.1- | 
| 3 | 
            +
              "version": "0.19.1-07fc9cb",
         | 
| 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,7 +59,7 @@ | |
| 59 59 | 
             
                "@rollup/plugin-commonjs": "^25.0.7",
         | 
| 60 60 | 
             
                "@rollup/plugin-json": "^6.1.0",
         | 
| 61 61 | 
             
                "@rollup/plugin-node-resolve": "^15.2.3",
         | 
| 62 | 
            -
                "@samual/lib": "0.10.2- | 
| 62 | 
            +
                "@samual/lib": "0.10.2-e64c5bc",
         | 
| 63 63 | 
             
                "acorn": "^8.11.3",
         | 
| 64 64 | 
             
                "chalk": "^5.3.0",
         | 
| 65 65 | 
             
                "chokidar": "^3.6.0",
         | 
| @@ -69,17 +69,15 @@ | |
| 69 69 | 
             
                "rollup": "^4.14.2",
         | 
| 70 70 | 
             
                "terser": "^5.30.3"
         | 
| 71 71 | 
             
              },
         | 
| 72 | 
            -
              "engines": {
         | 
| 73 | 
            -
                "node": "^18 || >=20",
         | 
| 74 | 
            -
                "pnpm": "^9.0.1"
         | 
| 75 | 
            -
              },
         | 
| 76 72 | 
             
              "type": "module",
         | 
| 77 73 | 
             
              "exports": {
         | 
| 78 74 | 
             
                "./*": "./*.js",
         | 
| 79 75 | 
             
                "./*.js": "./*.js"
         | 
| 80 76 | 
             
              },
         | 
| 81 77 | 
             
              "bin": {
         | 
| 82 | 
            -
                "hsm.d": "bin/hsm.d.ts",
         | 
| 83 78 | 
             
                "hsm": "bin/hsm.js"
         | 
| 79 | 
            +
              },
         | 
| 80 | 
            +
              "engines": {
         | 
| 81 | 
            +
                "node": "^18 || >=20"
         | 
| 84 82 | 
             
              }
         | 
| 85 83 | 
             
            }
         |