hackmud-script-manager 0.19.1-bd545f5 → 0.19.1-cb8d65f
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 +180 -232
- package/generateTypeDeclaration.js +1 -1
- package/package.json +4 -9
- 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
    
    | @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            #!/usr/bin/env node
         | 
| 2 2 | 
             
            import { Cache } from "@samual/lib/Cache"
         | 
| 3 3 | 
             
            import { assert } from "@samual/lib/assert"
         | 
| 4 | 
            +
            import { catchError } from "@samual/lib/catchError"
         | 
| 4 5 | 
             
            import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
         | 
| 6 | 
            +
            import { getDeepObjectProperty } from "@samual/lib/getDeepObjectProperty"
         | 
| 7 | 
            +
            import { isRecord } from "@samual/lib/isRecord"
         | 
| 8 | 
            +
            import { setDeepObjectProperty } from "@samual/lib/setDeepObjectProperty"
         | 
| 5 9 | 
             
            import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
         | 
| 6 10 | 
             
            import { readFile, writeFile, mkdir, rmdir } from "fs/promises"
         | 
| 7 11 | 
             
            import { homedir } from "os"
         | 
| @@ -21,119 +25,7 @@ const configDirectoryPath = resolve(homedir(), ".config"), | |
| 21 25 | 
             
            		for (const char of user) hash += (hash >> 1) + hash + "xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(char) + 1
         | 
| 22 26 | 
             
            		return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user)
         | 
| 23 27 | 
             
            	}),
         | 
| 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-bd545f5"))
         | 
| 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 | 
            -
            	}
         | 
| 28 | 
            +
            	log = message => console.log(colourS(message))
         | 
| 137 29 | 
             
            for (const argument of process.argv.slice(2))
         | 
| 138 30 | 
             
            	if ("-" == argument[0]) {
         | 
| 139 31 | 
             
            		const [key, valueRaw] = argument.split("=")
         | 
| @@ -150,20 +42,14 @@ for (const argument of process.argv.slice(2)) | |
| 150 42 | 
             
            		else for (const option of key.slice(1)) options.set(option, value)
         | 
| 151 43 | 
             
            	} else commands.push(argument)
         | 
| 152 44 | 
             
            if ("v" == commands[0] || "version" == commands[0] || options.get("version") || options.get("v")) {
         | 
| 153 | 
            -
            	console.log("0.19.1- | 
| 45 | 
            +
            	console.log("0.19.1-cb8d65f")
         | 
| 154 46 | 
             
            	process.exit()
         | 
| 155 47 | 
             
            }
         | 
| 156 48 | 
             
            let configDidNotExist = !1
         | 
| 157 49 | 
             
            const configPromise = readFile(configFilePath, { encoding: "utf-8" }).then(
         | 
| 158 50 | 
             
            		configFile => {
         | 
| 159 | 
            -
            			 | 
| 160 | 
            -
            			 | 
| 161 | 
            -
            				temporaryConfig = JSON.parse(configFile)
         | 
| 162 | 
            -
            			} catch {
         | 
| 163 | 
            -
            				log("Config file was corrupted, resetting")
         | 
| 164 | 
            -
            				return {}
         | 
| 165 | 
            -
            			}
         | 
| 166 | 
            -
            			if (!temporaryConfig || "object" != typeof temporaryConfig) {
         | 
| 51 | 
            +
            			const [temporaryConfig, error] = catchError(() => JSON.parse(configFile))
         | 
| 52 | 
            +
            			if (error || !isRecord(temporaryConfig)) {
         | 
| 167 53 | 
             
            				log("Config file was corrupted, resetting")
         | 
| 168 54 | 
             
            				return {}
         | 
| 169 55 | 
             
            			}
         | 
| @@ -200,15 +86,13 @@ if (options.get("help") || options.get("h")) { | |
| 200 86 | 
             
            	process.exit()
         | 
| 201 87 | 
             
            }
         | 
| 202 88 | 
             
            let autoExit = !0
         | 
| 89 | 
            +
            const getDefaultHackmudPath = () =>
         | 
| 90 | 
            +
            	"win32" == process.platform ? resolve(process.env.APPDATA, "hackmud") : resolve(homedir(), ".config/hackmud")
         | 
| 203 91 | 
             
            switch (commands[0]) {
         | 
| 204 92 | 
             
            	case "push":
         | 
| 205 93 | 
             
            		{
         | 
| 206 | 
            -
            			const { hackmudPath } = await configPromise
         | 
| 207 | 
            -
             | 
| 208 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 209 | 
            -
            				break
         | 
| 210 | 
            -
            			}
         | 
| 211 | 
            -
            			const sourcePath = commands[1]
         | 
| 94 | 
            +
            			const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
         | 
| 95 | 
            +
            				sourcePath = commands[1]
         | 
| 212 96 | 
             
            			if (!sourcePath) {
         | 
| 213 97 | 
             
            				logError("Must provide the directory to push from\n")
         | 
| 214 98 | 
             
            				logHelp()
         | 
| @@ -276,12 +160,8 @@ switch (commands[0]) { | |
| 276 160 | 
             
            	case "dev":
         | 
| 277 161 | 
             
            	case "watch":
         | 
| 278 162 | 
             
            		{
         | 
| 279 | 
            -
            			const { hackmudPath } = await configPromise
         | 
| 280 | 
            -
             | 
| 281 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 282 | 
            -
            				break
         | 
| 283 | 
            -
            			}
         | 
| 284 | 
            -
            			const sourcePath = commands[1]
         | 
| 163 | 
            +
            			const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
         | 
| 164 | 
            +
            				sourcePath = commands[1]
         | 
| 285 165 | 
             
            			if (!sourcePath) {
         | 
| 286 166 | 
             
            				logError("Must provide the directory to watch\n")
         | 
| 287 167 | 
             
            				logHelp()
         | 
| @@ -354,34 +234,24 @@ switch (commands[0]) { | |
| 354 234 | 
             
            		break
         | 
| 355 235 | 
             
            	case "pull":
         | 
| 356 236 | 
             
            		{
         | 
| 357 | 
            -
            			const { hackmudPath } = await configPromise
         | 
| 358 | 
            -
             | 
| 359 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 360 | 
            -
            				break
         | 
| 361 | 
            -
            			}
         | 
| 362 | 
            -
            			const script = commands[1]
         | 
| 237 | 
            +
            			const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
         | 
| 238 | 
            +
            				script = commands[1]
         | 
| 363 239 | 
             
            			if (!script) {
         | 
| 364 240 | 
             
            				logError("Must provide the script to pull\n")
         | 
| 365 241 | 
             
            				logHelp()
         | 
| 366 242 | 
             
            				break
         | 
| 367 243 | 
             
            			}
         | 
| 368 244 | 
             
            			const sourcePath = commands[2] || "."
         | 
| 369 | 
            -
            			 | 
| 370 | 
            -
            				await pull(sourcePath, hackmudPath, script)
         | 
| 371 | 
            -
            			} catch (error) {
         | 
| 245 | 
            +
            			await pull(sourcePath, hackmudPath, script).catch(error => {
         | 
| 372 246 | 
             
            				console.error(error)
         | 
| 373 247 | 
             
            				logError(`Something went wrong, did you forget to ${colourC("#down")} the script?`)
         | 
| 374 | 
            -
            			}
         | 
| 248 | 
            +
            			})
         | 
| 375 249 | 
             
            		}
         | 
| 376 250 | 
             
            		break
         | 
| 377 251 | 
             
            	case "sync-macros":
         | 
| 378 252 | 
             
            		{
         | 
| 379 | 
            -
            			const { hackmudPath } = await configPromise
         | 
| 380 | 
            -
             | 
| 381 | 
            -
            				logNeedHackmudPathMessage()
         | 
| 382 | 
            -
            				break
         | 
| 383 | 
            -
            			}
         | 
| 384 | 
            -
            			const { macrosSynced, usersSynced } = await syncMacros(hackmudPath)
         | 
| 253 | 
            +
            			const { hackmudPath = getDefaultHackmudPath() } = await configPromise,
         | 
| 254 | 
            +
            				{ macrosSynced, usersSynced } = await syncMacros(hackmudPath)
         | 
| 385 255 | 
             
            			log(`Synced ${macrosSynced} macros to ${usersSynced} users`)
         | 
| 386 256 | 
             
            		}
         | 
| 387 257 | 
             
            		break
         | 
| @@ -398,16 +268,17 @@ switch (commands[0]) { | |
| 398 268 | 
             
            			}
         | 
| 399 269 | 
             
            			const sourcePath = resolve(target),
         | 
| 400 270 | 
             
            				outputPath = commands[2] || "./player.d.ts",
         | 
| 401 | 
            -
            				typeDeclaration = await generateTypeDeclaration( | 
| 271 | 
            +
            				typeDeclaration = await generateTypeDeclaration(
         | 
| 272 | 
            +
            					sourcePath,
         | 
| 273 | 
            +
            					(await configPromise).hackmudPath || getDefaultHackmudPath()
         | 
| 274 | 
            +
            				)
         | 
| 402 275 | 
             
            			let typeDeclarationPath = resolve(outputPath)
         | 
| 403 | 
            -
            			 | 
| 404 | 
            -
            				 | 
| 405 | 
            -
            			} catch (error) {
         | 
| 406 | 
            -
            				assert(error instanceof Error)
         | 
| 276 | 
            +
            			await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
         | 
| 277 | 
            +
            				assert(error instanceof Error, "src/bin/hsm.ts:365:35")
         | 
| 407 278 | 
             
            				if ("EISDIR" != error.code) throw error
         | 
| 408 279 | 
             
            				typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
         | 
| 409 | 
            -
            				 | 
| 410 | 
            -
            			}
         | 
| 280 | 
            +
            				return writeFile(typeDeclarationPath, typeDeclaration)
         | 
| 281 | 
            +
            			})
         | 
| 411 282 | 
             
            			log("Wrote type declaration to " + chalk.bold(typeDeclarationPath))
         | 
| 412 283 | 
             
            		}
         | 
| 413 284 | 
             
            		break
         | 
| @@ -415,8 +286,14 @@ switch (commands[0]) { | |
| 415 286 | 
             
            		switch (commands[1]) {
         | 
| 416 287 | 
             
            			case "get":
         | 
| 417 288 | 
             
            				{
         | 
| 418 | 
            -
            					const key = commands[2]
         | 
| 419 | 
            -
             | 
| 289 | 
            +
            					const key = commands[2],
         | 
| 290 | 
            +
            						config = await configPromise
         | 
| 291 | 
            +
            					if (key) {
         | 
| 292 | 
            +
            						const [value, error] = catchError(() => getDeepObjectProperty(config, key.split(".")))
         | 
| 293 | 
            +
            						error ? logError("Could not get key " + colourV(key))
         | 
| 294 | 
            +
            						: "string" == typeof value ? log(value)
         | 
| 295 | 
            +
            						: console.log(value)
         | 
| 296 | 
            +
            					} else console.log(config)
         | 
| 420 297 | 
             
            				}
         | 
| 421 298 | 
             
            				break
         | 
| 422 299 | 
             
            			case "delete":
         | 
| @@ -427,14 +304,16 @@ switch (commands[0]) { | |
| 427 304 | 
             
            						logHelp()
         | 
| 428 305 | 
             
            						break
         | 
| 429 306 | 
             
            					}
         | 
| 430 | 
            -
            					const  | 
| 431 | 
            -
            						 | 
| 432 | 
            -
             | 
| 433 | 
            -
             | 
| 434 | 
            -
             | 
| 435 | 
            -
            						 | 
| 436 | 
            -
             | 
| 437 | 
            -
             | 
| 307 | 
            +
            					const keys = key.split("."),
         | 
| 308 | 
            +
            						lastKey = keys.pop(),
         | 
| 309 | 
            +
            						config = await configPromise,
         | 
| 310 | 
            +
            						object = getDeepObjectProperty(config, keys)
         | 
| 311 | 
            +
            					if (isRecord(object)) {
         | 
| 312 | 
            +
            						delete object[lastKey]
         | 
| 313 | 
            +
            						await updateConfig(config)
         | 
| 314 | 
            +
            						log(`Removed ${colourV(key)} from config file:`)
         | 
| 315 | 
            +
            						console.log(config)
         | 
| 316 | 
            +
            					} else log("Could not delete " + colourV(key))
         | 
| 438 317 | 
             
            				}
         | 
| 439 318 | 
             
            				break
         | 
| 440 319 | 
             
            			case "set":
         | 
| @@ -446,49 +325,20 @@ switch (commands[0]) { | |
| 446 325 | 
             
            						logHelp()
         | 
| 447 326 | 
             
            						break
         | 
| 448 327 | 
             
            					}
         | 
| 449 | 
            -
            					const keys = key.split("."),
         | 
| 450 | 
            -
            						pathName = keys
         | 
| 451 | 
            -
            							.map(name => (/^[a-z_$][\w$]*$/i.test(name) ? name : JSON.stringify(name)))
         | 
| 452 | 
            -
            							.join(".")
         | 
| 453 328 | 
             
            					if (!value) {
         | 
| 454 | 
            -
            						logError(`Must provide a value for the key ${ | 
| 329 | 
            +
            						logError(`Must provide a value for the key ${colourV(key)}\n`)
         | 
| 455 330 | 
             
            						logHelp()
         | 
| 456 331 | 
             
            						break
         | 
| 457 332 | 
             
            					}
         | 
| 458 | 
            -
            					const  | 
| 459 | 
            -
             | 
| 460 | 
            -
            					 | 
| 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)
         | 
| 333 | 
            +
            					const config = await configPromise
         | 
| 334 | 
            +
            					setDeepObjectProperty(config, key.split("."), value)
         | 
| 335 | 
            +
            					log(`Set ${colourV(key)} to ${colourV(value)}:`)
         | 
| 470 336 | 
             
            					console.log(config)
         | 
| 471 | 
            -
            					await ( | 
| 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)
         | 
| 337 | 
            +
            					await updateConfig(config)
         | 
| 488 338 | 
             
            				}
         | 
| 489 339 | 
             
            				break
         | 
| 490 340 | 
             
            			default:
         | 
| 491 | 
            -
            				commands[1] && logError(`Unknown command: ${ | 
| 341 | 
            +
            				commands[1] && logError(`Unknown command: ${colourL(commands[1])}\n`)
         | 
| 492 342 | 
             
            				logHelp()
         | 
| 493 343 | 
             
            		}
         | 
| 494 344 | 
             
            		break
         | 
| @@ -555,36 +405,31 @@ switch (commands[0]) { | |
| 555 405 | 
             
            					: fileBaseName + ".js"
         | 
| 556 406 | 
             
            				)
         | 
| 557 407 | 
             
            			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)
         | 
| 408 | 
            +
            				readFile(target, { encoding: "utf-8" }).then(async source => {
         | 
| 409 | 
            +
            					const timeStart = performance.now(),
         | 
| 410 | 
            +
            						{ script, warnings } = await processScript(source, {
         | 
| 411 | 
            +
            							minify: !(options.get("no-minify") || options.get("skip-minify")),
         | 
| 412 | 
            +
            							scriptUser,
         | 
| 413 | 
            +
            							scriptName,
         | 
| 414 | 
            +
            							filePath: target,
         | 
| 415 | 
            +
            							mangleNames,
         | 
| 416 | 
            +
            							forceQuineCheats
         | 
| 417 | 
            +
            						}),
         | 
| 418 | 
            +
            						timeTook = performance.now() - timeStart
         | 
| 419 | 
            +
            					for (const { message, line } of warnings)
         | 
| 420 | 
            +
            						log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(line + "")}`)
         | 
| 421 | 
            +
            					await writeFilePersistent(outputPath, script)
         | 
| 422 | 
            +
            						.catch(error => {
         | 
| 423 | 
            +
            							if (!commands[2] || "EISDIR" != error.code) throw error
         | 
| 424 | 
            +
            							outputPath = resolve(outputPath, basename(target, fileExtension) + ".js")
         | 
| 425 | 
            +
            							return writeFilePersistent(outputPath, script)
         | 
| 426 | 
            +
            						})
         | 
| 427 | 
            +
            						.then(() =>
         | 
| 428 | 
            +
            							log(
         | 
| 429 | 
            +
            								`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(".", outputPath))} | took ${Math.round(100 * timeTook) / 100}ms`
         | 
| 584 430 | 
             
            							)
         | 
| 585 | 
            -
             | 
| 586 | 
            -
             | 
| 587 | 
            -
            				)
         | 
| 431 | 
            +
            						)
         | 
| 432 | 
            +
            				})
         | 
| 588 433 | 
             
            			if (options.get("watch")) {
         | 
| 589 434 | 
             
            				const { watch: watchFile } = await chokidarModule
         | 
| 590 435 | 
             
            				watchFile(target, { awaitWriteFinish: { stabilityThreshold: 100 } })
         | 
| @@ -595,7 +440,110 @@ switch (commands[0]) { | |
| 595 440 | 
             
            		}
         | 
| 596 441 | 
             
            		break
         | 
| 597 442 | 
             
            	default:
         | 
| 598 | 
            -
            		commands[0] && logError(`Unknown command: ${ | 
| 443 | 
            +
            		commands[0] && logError(`Unknown command: ${colourL(commands[0])}\n`)
         | 
| 599 444 | 
             
            		logHelp()
         | 
| 600 445 | 
             
            }
         | 
| 601 446 | 
             
            autoExit && process.exit()
         | 
| 447 | 
            +
            function logHelp() {
         | 
| 448 | 
            +
            	const pushCommandDescription = "Push scripts from a directory to hackmud user's scripts directories",
         | 
| 449 | 
            +
            		forceQuineCheatsOptionDescription = `Force quine cheats on. Use ${colourN("--force-quine-cheats")}=${colourV("false")} to force off`
         | 
| 450 | 
            +
            	console.log(colourN("Version") + colourS(": ") + colourV("0.19.1-cb8d65f"))
         | 
| 451 | 
            +
            	switch (commands[0]) {
         | 
| 452 | 
            +
            		case "config":
         | 
| 453 | 
            +
            			switch (commands[1]) {
         | 
| 454 | 
            +
            				case "get":
         | 
| 455 | 
            +
            					console.log(
         | 
| 456 | 
            +
            						`\n${colourJ("Retrieve a value from the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key>")}`
         | 
| 457 | 
            +
            					)
         | 
| 458 | 
            +
            					break
         | 
| 459 | 
            +
            				case "set":
         | 
| 460 | 
            +
            					console.log(
         | 
| 461 | 
            +
            						`\n${colourJ("Assign a value to the config file")}\n\n${colourA("Usage:")}\n${colourC("hsm")} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB("<key> <value>")}`
         | 
| 462 | 
            +
            					)
         | 
| 463 | 
            +
            					break
         | 
| 464 | 
            +
            				case "delete":
         | 
| 465 | 
            +
            					console.log(
         | 
| 466 | 
            +
            						`\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>")}`
         | 
| 467 | 
            +
            					)
         | 
| 468 | 
            +
            					break
         | 
| 469 | 
            +
            				default:
         | 
| 470 | 
            +
            					console.log(
         | 
| 471 | 
            +
            						colourS(
         | 
| 472 | 
            +
            							`${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`
         | 
| 473 | 
            +
            						)
         | 
| 474 | 
            +
            					)
         | 
| 475 | 
            +
            			}
         | 
| 476 | 
            +
            			break
         | 
| 477 | 
            +
            		case "dev":
         | 
| 478 | 
            +
            		case "watch":
         | 
| 479 | 
            +
            		case "push":
         | 
| 480 | 
            +
            			console.log(
         | 
| 481 | 
            +
            				colourS(
         | 
| 482 | 
            +
            					`\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${"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`
         | 
| 483 | 
            +
            				)
         | 
| 484 | 
            +
            			)
         | 
| 485 | 
            +
            			break
         | 
| 486 | 
            +
            		case "pull":
         | 
| 487 | 
            +
            			console.log(
         | 
| 488 | 
            +
            				colourS(
         | 
| 489 | 
            +
            					`\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>")}`
         | 
| 490 | 
            +
            				)
         | 
| 491 | 
            +
            			)
         | 
| 492 | 
            +
            			break
         | 
| 493 | 
            +
            		case "minify":
         | 
| 494 | 
            +
            		case "golf":
         | 
| 495 | 
            +
            			console.log(
         | 
| 496 | 
            +
            				colourS(
         | 
| 497 | 
            +
            					`\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`
         | 
| 498 | 
            +
            				)
         | 
| 499 | 
            +
            			)
         | 
| 500 | 
            +
            			break
         | 
| 501 | 
            +
            		case "generate-type-declaration":
         | 
| 502 | 
            +
            		case "gen-type-declaration":
         | 
| 503 | 
            +
            		case "gen-dts":
         | 
| 504 | 
            +
            		case "gen-types":
         | 
| 505 | 
            +
            			console.log(
         | 
| 506 | 
            +
            				colourS(
         | 
| 507 | 
            +
            					`${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]")}`
         | 
| 508 | 
            +
            				)
         | 
| 509 | 
            +
            			)
         | 
| 510 | 
            +
            			break
         | 
| 511 | 
            +
            		case "sync-macros":
         | 
| 512 | 
            +
            			console.log("\n" + colourJ("Sync macros across all hackmud users"))
         | 
| 513 | 
            +
            			break
         | 
| 514 | 
            +
            		default:
         | 
| 515 | 
            +
            			console.log(
         | 
| 516 | 
            +
            				colourS(
         | 
| 517 | 
            +
            					`\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`
         | 
| 518 | 
            +
            				)
         | 
| 519 | 
            +
            			)
         | 
| 520 | 
            +
            	}
         | 
| 521 | 
            +
            }
         | 
| 522 | 
            +
            async function updateConfig(config) {
         | 
| 523 | 
            +
            	const json = JSON.stringify(config, void 0, "\t")
         | 
| 524 | 
            +
            	configDidNotExist && log("Creating config file at " + configFilePath)
         | 
| 525 | 
            +
            	await writeFile(configFilePath, json).catch(async error => {
         | 
| 526 | 
            +
            		switch (error.code) {
         | 
| 527 | 
            +
            			case "EISDIR":
         | 
| 528 | 
            +
            				await rmdir(configFilePath)
         | 
| 529 | 
            +
            				break
         | 
| 530 | 
            +
            			case "ENOENT":
         | 
| 531 | 
            +
            				await mkdir(configDirectoryPath)
         | 
| 532 | 
            +
            				break
         | 
| 533 | 
            +
            			default:
         | 
| 534 | 
            +
            				throw error
         | 
| 535 | 
            +
            		}
         | 
| 536 | 
            +
            		await writeFile(configFilePath, json)
         | 
| 537 | 
            +
            	})
         | 
| 538 | 
            +
            }
         | 
| 539 | 
            +
            function logInfo({ file, users, minLength, error }, hackmudPath) {
         | 
| 540 | 
            +
            	error ?
         | 
| 541 | 
            +
            		logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
         | 
| 542 | 
            +
            	:	console.log(
         | 
| 543 | 
            +
            			`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")}`
         | 
| 544 | 
            +
            		)
         | 
| 545 | 
            +
            }
         | 
| 546 | 
            +
            function logError(message) {
         | 
| 547 | 
            +
            	console.error(colourD(message))
         | 
| 548 | 
            +
            	process.exitCode = 1
         | 
| 549 | 
            +
            }
         | 
| @@ -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-cb8d65f",
         | 
| 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,12 @@ | |
| 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 | 
            -
              " | 
| 82 | 
            -
                " | 
| 83 | 
            -
                "hsm": "bin/hsm.js"
         | 
| 77 | 
            +
              "engines": {
         | 
| 78 | 
            +
                "node": "^18 || >=20"
         | 
| 84 79 | 
             
              }
         | 
| 85 80 | 
             
            }
         |