hackmud-script-manager 0.19.0-43367ba → 0.19.0-c12fd7c
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.d.ts +0 -1
- package/bin/hsm.js +687 -1
- package/constants.d.ts +2 -0
- package/constants.js +4 -0
- package/generateTypeDeclaration.js +94 -1
- package/index.d.ts +2 -2
- package/index.js +47 -1
- package/package.json +36 -78
- package/processScript/index.d.ts +2 -2
- package/processScript/index.js +310 -1
- package/processScript/minify.d.ts +3 -3
- package/processScript/minify.js +376 -1
- package/processScript/postprocess.js +5 -1
- package/processScript/preprocess.d.ts +1 -1
- package/processScript/preprocess.js +84 -1
- package/processScript/shared.d.ts +3 -3
- package/processScript/shared.js +18 -1
- package/processScript/transform.d.ts +3 -3
- package/processScript/transform.js +394 -1
- package/pull.js +17 -1
- package/push.d.ts +3 -3
- package/push.js +251 -1
- package/syncMacros.js +53 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/watch.d.ts +3 -3
- package/watch.js +228 -1
- package/assert-22a7ef8a.js +0 -1
- package/constants-9bb78688.js +0 -1
- package/countHackmudCharacters-a08a265f.js +0 -1
- package/spliceString-0e6b5d6d.js +0 -1
- package/writeFilePersistent-ee9c9bfd.js +0 -1
package/bin/hsm.js
CHANGED
@@ -1,2 +1,688 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import{readFile as e,writeFile as t,mkdir as n,rmdir as a}from"fs/promises";import{homedir as s}from"os";import{s as o}from"../constants-9bb78688.js";import{generateTypeDeclaration as i}from"../generateTypeDeclaration.js";import{pull as r}from"../pull.js";import{syncMacros as c}from"../syncMacros.js";import{resolve as l,extname as f,basename as $,dirname as p,relative as h}from"path";import{D as m,w as d}from"../writeFilePersistent-ee9c9bfd.js";import{a as g}from"../assert-22a7ef8a.js";import{c as u}from"../countHackmudCharacters-a08a265f.js";import"fs";const y=l(s(),".config"),b=l(y,"hsm.json"),k=new Map,w=[],v=new m((e=>{let t=0;for(const n of e)t+=(t>>1)+t+"xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj".indexOf(n)+1;return[W,_,I,D,x,q][t%6](e)})),logNeedHackmudPathMessage=()=>console.error(R(`${C("You need to set hackmudPath in config before you can use this command")}\n\n${T("To fix this:")}\nOpen hackmud and run "${z("#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 "${z("hsm")} ${x("config set")} ${A("hackmudPath")} ${q("<the path you copied>")}"`)),logHelp=()=>{const e="Push scripts from a directory to hackmud user's scripts directories",t="Watch a directory and push a script when modified",n="Minify a script file on the spot",a="Generate a type declaration file for a directory of scripts",s="Sync macros across all hackmud users",o="Retrieve a value from the config file",i="Assign a value to the config file",r="Remove a key and value from the config file",c="Pull a script a from a hackmud user's script directory",l="Skip minification to produce a readable script",f="Reduce character count further but lose function names in error call stacks",$="Force quine cheats even if the character count is higher";switch(console.log(J("Version")+R(": ")+A("0.19.0-43367ba")),w[0]){case"config":switch(w[1]){case"get":console.log(`\n${W(o)}\n\n${T("Usage:")}\n${z("hsm")} ${x(`${w[0]} ${w[1]}`)} ${q("<key>")}`);break;case"set":console.log(`\n${W(i)}\n\n${T("Usage:")}\n${z("hsm")} ${x(`${w[0]} ${w[1]}`)} ${q("<key> <value>")}`);break;case"delete":console.log(`\n${W(r)}\n\n${T("Usage:")}\n${z("hsm")} ${x(`${w[0]} ${w[1]}`)} ${q("<key>")}`);break;default:console.log(R(`${J("Config path")}: ${A(b)}\n\n${W("Modify the config file")}\n\n${T("Usage:")}\n${z("hsm")} ${x(`${w[0]} get`)} ${q("<key>")}\n ${o}\n${z("hsm")} ${x(`${w[0]} set`)} ${q("<key> <value>")}\n ${i}\n${z("hsm")} ${x(`${w[0]} delete`)} ${q("<key>")}\n ${r}`))}break;case"push":console.log(R(`\n${W(e)}\n\n${T("Usage:")}\n${z("hsm")} ${x(w[0])} ${q("<directory> [<script user>.<script name>...]")}\n\n${T("Options:")}\n${J("--skip-minify")}\n ${l}\n${J("--mangle-names")}\n ${f}\n${J("--force-quine-cheats")}\n ${$}`));break;case"dev":case"watch":console.log(R(`${J("Aliases")}: ${A("watch, dev")}\n\n${W(t)}\n\n${T("Usage:")}\n${z("hsm")} ${x(w[0])} ${q("<directory> [<script user>.<script name>...]")}\n\n${T("Options:")}\n${J("--skip-minify")}\n ${l}\n${J("--mangle-names")}\n ${f}\n${J("--type-declaration-path")}=${q("<path>")}\n Path to generate a type declaration file for the scripts\n${J("--force-quine-cheats")}\n ${$}`));break;case"pull":console.log(R(`\n${W(c)}\n\n${T("Usage:")}\n${z("hsm")} ${x(w[0])} ${q("<script user>")}${A(".")}${q("<script name>")}`));break;case"minify":case"golf":console.log(R(`${J("Aliases")}: ${A("minify, golf")}\n\n${W(n)}\n\n${T("Usage:")}\n${z("hsm")} ${x(w[0])} ${q("<target> [output path]")}\n\n${T("Options:")}\n${J("--skip-minify")}\n ${l}\n${J("--mangle-names")}\n ${f}\n${J("--force-quine-cheats")}\n ${$}\n${J("--watch")}\n Watch for changes`));break;case"generate-type-declaration":case"gen-type-declaration":case"gen-dts":case"gen-types":console.log(R(`${J("Aliases")}: ${A("generate-type-declaration, gen-type-declaration, gen-types, gen-dts")}\n\n${W(a)}\n\n${T("Usage:")}\n${z("hsm")} ${x(w[0])} ${q("<directory> [output path]")}`));break;case"sync-macros":console.log(`\n${W(s)}`);break;default:console.log(R(`\n${W("Hackmud Script Manager")}\n\n${T("Commands:")}\n${x("push")}\n ${e}\n${x("watch")}, ${x("dev")}\n ${t}\n${x("minify")}, ${x("golf")}\n ${n}\n${x("generate-type-declaration")}, ${x("gen-type-declaration")}, ${x("gen-types")}, ${x("gen-dts")}\n ${a}\n${x("sync-macros")}\n ${s}\n${x("config")}\n Modify and view the config file\n${x("pull")}\n ${c}`))}},exploreObject=(e,t,n=!1)=>{for(const s of t){var a;e=n?"object"==typeof e[s]?e[s]:e[s]={}:null===(a=e)||void 0===a?void 0:a[s]}return e},logInfo=({file:e,users:t,minLength:n,error:a},s)=>{a?logError(`error "${U.bold(a.message)}" in ${U.bold(e)}`):console.log(`pushed ${U.bold(e)} to ${t.map((e=>U.bold(v.get(e)))).join(", ")} | ${U.bold(String(n))} chars | ${U.bold(`${l(s,t[0],"scripts",$(e,f(e)))}.js`)}`)},log=e=>{console.log(R(e))},logError=e=>{console.error(C(e)),process.exitCode=1};for(const e of process.argv.slice(2))if("-"==e[0]){const[t,n]=e.split("=");let a=n;if(a)if("true"==a)a=!0;else if("false"==a)a=!1;else{const e=Number(a);isFinite(e)&&(a=e)}else a=!0;if("-"==e[1])k.set(t.slice(2),a);else for(const e of t.slice(1))k.set(e,a)}else w.push(e);("v"==w[0]||"version"==w[0]||k.get("version")||k.get("v"))&&(console.log("0.19.0-43367ba"),process.exit());let j=!1;const S=e(b,{encoding:"utf-8"}).then((e=>{let t;try{t=JSON.parse(e)}catch{return log("Config file was corrupted, resetting"),{}}return t&&"object"==typeof t?("hackmudPath"in t&&"string"!=typeof t.hackmudPath&&(log('Property "hackmudPath" of config file was corrupted, removing'),delete t.hackmudPath),t):(log("Config file was corrupted, resetting"),{})}),(()=>(j=!0,{}))),P=import("../push.js"),N=import("../processScript/index.js"),O=import("../watch.js"),M=import("chokidar"),{default:U}=await import("chalk"),T=U.rgb(255,255,255),q=U.rgb(202,202,202),z=U.rgb(155,155,155),C=U.rgb(255,0,0),W=U.rgb(255,244,4),_=U.rgb(243,249,152),x=U.rgb(30,255,0),I=U.rgb(179,255,155),J=U.rgb(0,255,255),R=U.rgb(122,178,244),A=U.rgb(255,0,236),D=U.rgb(255,150,224);(k.get("help")||k.get("h"))&&(logHelp(),process.exit());let E=!0;switch(w[0]){case"push":{const{hackmudPath:e}=await S;if(!e){logNeedHackmudPathMessage();break}const t=w[1];if(!t){logError("Must provide the directory to push from\n"),logHelp();break}const n=w.slice(2);if(n.length){const e=n.find((e=>!/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(e)));if(e){logError(`Invalid script name: ${JSON.stringify(e)}\n`),logHelp();break}}else n.push("*.*");if(k.has("skip-minify")&&k.has("mangle-names")){logError(`Option ${J("--mangle-names")} is not compatible with ${J("--skip-minify")}\n`),logHelp();break}const a=k.get("skip-minify");let s;if(null!=a){if("boolean"!=typeof a){logError(`The value for ${J("--skip-minify")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}s=!a}const o=k.get("mangle-names");if(null!=o&&"boolean"!=typeof o){logError(`The value for ${J("--mangle-names")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}const i=k.get("force-quine-cheats");if(null!=i&&"boolean"!=typeof i){logError(`The value for ${J("--force-quine-cheats")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}const{push:r}=await P;(await r(t,e,{scripts:n,onPush:t=>logInfo(t,e),minify:s,mangleNames:o,forceQuineCheats:i})).length||logError("Could not find any scripts to push")}break;case"dev":case"watch":{var F;const{hackmudPath:e}=await S;if(!e){logNeedHackmudPathMessage();break}const t=w[1];if(!t){logError("Must provide the directory to watch\n"),logHelp();break}const n=w.slice(2);if(n.length){const e=n.find((e=>!/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(e)));if(e){logError(`Invalid script name: ${JSON.stringify(e)}\n`),logHelp();break}}else n.push("*.*");if(k.has("skip-minify")&&k.has("mangle-names")){logError(`Option ${J("--mangle-names")} is not compatible with ${J("--skip-minify")}\n`),logHelp();break}const a=k.get("skip-minify");let s;if(null!=a){if("boolean"!=typeof a){logError(`The value for ${J("--skip-minify")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}s=!a}const o=k.get("mangle-names");if(null!=o&&"boolean"!=typeof o){logError(`The value for ${J("--mangle-names")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}const i=k.get("force-quine-cheats");if(null!=i&&"boolean"!=typeof i){logError(`The value for ${J("--force-quine-cheats")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}const{watch:r}=await O;r(t,e,{scripts:n,onPush:t=>logInfo(t,e),typeDeclarationPath:null===(F=k.get("type-declaration-path")||k.get("type-declaration")||k.get("dts")||k.get("gen-types"))||void 0===F?void 0:F.toString(),minify:s,mangleNames:o,onReady:()=>log("Watching"),forceQuineCheats:i}),E=!1}break;case"pull":{const{hackmudPath:e}=await S;if(!e){logNeedHackmudPathMessage();break}const t=w[1];if(!t){logError("Must provide the script to pull\n"),logHelp();break}const n=w[2]||".";try{await r(n,e,t)}catch(e){console.error(e),logError(`Something went wrong, did you forget to ${z("#down")} the script?`)}}break;case"sync-macros":{const{hackmudPath:e}=await S;if(!e){logNeedHackmudPathMessage();break}const{macrosSynced:t,usersSynced:n}=await c(e);log(`Synced ${t} macros to ${n} users`)}break;case"generate-type-declaration":case"gen-type-declaration":case"gen-dts":case"gen-types":{const e=w[1];if(!e){logError("Must provide target directory\n"),logHelp();break}const n=l(e),a=w[2]||"./player.d.ts",s=await i(n,(await S).hackmudPath);let o=l(a);try{await t(o,s)}catch(e){if(g(e instanceof Error),"EISDIR"!=e.code)throw e;o=l(o,"player.d.ts"),await t(o,s)}log(`Wrote type declaration to ${U.bold(o)}`)}break;case"config":switch(w[1]){case"get":{const e=w[2];e?log(exploreObject(await S,e.split("."))):console.log(await S)}break;case"delete":{var Q;const e=w[2];if(!e){logError("Must provide a key to delete\n"),logHelp();break}const t=e.split("."),n=t.map((e=>/^[A-Za-z_$][\w$]*$/.test(e)?e:JSON.stringify(e))).join("."),a=t.pop();null===(Q=exploreObject(await S,t))||void 0===Q||delete Q[a],log(`Removed ${A(n)} from config file`)}break;case"set":{const e=w[2],o=w[3];if(!e){logError("Must provide a key and value\n"),logHelp();break}const i=e.split("."),r=i.map((e=>/^[A-Za-z_$][\w$]*$/.test(e)?e:JSON.stringify(e))).join(".");if(!o){logError(`Must provide a value for the key ${r}\n`),logHelp();break}const c=i.pop(),f=await S;if(i.length||"hackmudPath"!=c){let e=f;for(const t of i)"object"==typeof e[t]||(e[t]={}),e=e[t];e[c]=o}else f.hackmudPath=l(o.startsWith("~/")?s()+o.slice(1):o);console.log(f),await(async e=>{const s=JSON.stringify(e,void 0,"\t");j&&log(`Creating config file at ${b}`),await t(b,s).catch((async e=>{switch(e.code){case"EISDIR":await a(b);break;case"ENOENT":await n(y);break;default:throw e}await t(b,s)}))})(f)}break;default:w[1]&&logError(`Unknown command: ${JSON.stringify(w[1])}\n`),logHelp()}break;case"help":case"h":logHelp();break;case"golf":case"minify":{const t=w[1];if(!t){logError("Must provide target\n"),logHelp();break}const n=f(t);if(!o.includes(n)){logError(`Unsupported file extension "${U.bold(n)}"\nSupported extensions are "${o.map((e=>U.bold(e))).join('", "')}"`);break}const{processScript:a}=await N,s=$(t,n),i=s.endsWith(".src"),r=i?s.slice(0,-4):s,c="scripts"==$(l(t,".."))&&"hackmud"==$(l(t,"../../.."))?$(l(t,"../..")):"UNKNOWN",m=!k.get("skip-minify");if(k.has("skip-minify")&&k.has("mangle-names")){logError(`Option ${J("--mangle-names")} would have no effect if minification is skipped\n`),logHelp();break}const g=k.get("mangle-names");if(null!=g&&"boolean"!=typeof g){logError(`The value for ${J("--mangle-names")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}const y=g,b=k.get("force-quine-cheats");if(null!=b&&"boolean"!=typeof b){logError(`the value for ${J("--force-quine-cheats")} must be ${A("true")} or ${A("false")}\n`),logHelp();break}const v=b;let j=w[2]||l(p(t),i?`${r}.js`:".js"==n?`${s}.min.js`:`${s}.js`);const golfFile=()=>e(t,{encoding:"utf-8"}).then((async e=>{const s=performance.now(),{script:o,warnings:i}=await a(e,{minify:m,scriptUser:c,scriptName:r,filePath:t,mangleNames:y,forceQuineCheats:v}),f=performance.now()-s;for(const{message:e,line:t}of i)log(`Warning "${U.bold(e)}" on line ${U.bold(String(t))}`);await d(j,o).catch((async e=>{if(!w[2]||"EISDIR"!=e.code)throw e;j=l(j,`${$(t,n)}.js`),await d(j,o)})).then((()=>log(`Wrote ${U.bold(u(o))} chars to ${U.bold(h(".",j))} | took ${Math.round(100*f)/100}ms`)),(e=>logError(e.message)))}),(e=>logError(e.message)));if(k.get("watch")){const{watch:e}=await M;e(t,{awaitWriteFinish:{stabilityThreshold:100}}).on("ready",(()=>log(`Watching ${t}`))).on("change",golfFile),E=!1}else await golfFile()}break;default:w[0]&&logError(`Unknown command: ${JSON.stringify(w[0])}\n`),logHelp()}E&&process.exit();
|
2
|
+
import { DynamicMap } from '@samual/lib/DynamicMap';
|
3
|
+
import { assert } from '@samual/lib/assert';
|
4
|
+
import { countHackmudCharacters } from '@samual/lib/countHackmudCharacters';
|
5
|
+
import { writeFilePersistent } from '@samual/lib/writeFilePersistent';
|
6
|
+
import { readFile, writeFile, mkdir, rmdir } from 'fs/promises';
|
7
|
+
import { homedir } from 'os';
|
8
|
+
import { supportedExtensions } from '../constants.js';
|
9
|
+
import { generateTypeDeclaration } from '../generateTypeDeclaration.js';
|
10
|
+
import { pull } from '../pull.js';
|
11
|
+
import { syncMacros } from '../syncMacros.js';
|
12
|
+
import { resolve, extname, basename, dirname, relative } from 'path';
|
13
|
+
import '@samual/lib/copyFilePersistent';
|
14
|
+
|
15
|
+
var version = "0.19.0-c12fd7c";
|
16
|
+
|
17
|
+
/* eslint-disable unicorn/no-process-exit */
|
18
|
+
|
19
|
+
/* | ArgValue[]*/
|
20
|
+
|
21
|
+
const configDirectoryPath = resolve(homedir(), `.config`);
|
22
|
+
const configFilePath = resolve(configDirectoryPath, `hsm.json`);
|
23
|
+
const options = new Map();
|
24
|
+
const commands = [];
|
25
|
+
const userColours = new DynamicMap(user => {
|
26
|
+
let hash = 0;
|
27
|
+
for (const char of user) hash += (hash >> 1) + hash + `xi1_8ratvsw9hlbgm02y5zpdcn7uekof463qj`.indexOf(char) + 1;
|
28
|
+
return [colourJ, colourK, colourM, colourW, colourL, colourB][hash % 6](user);
|
29
|
+
});
|
30
|
+
const logNeedHackmudPathMessage = () => console.error(colourS(`\
|
31
|
+
${colourD(`You need to set hackmudPath in config before you can use this command`)}
|
32
|
+
|
33
|
+
${colourA(`To fix this:`)}
|
34
|
+
Open hackmud and run "${colourC(`#dir`)}"
|
35
|
+
This will open a file browser and print your hackmud user's script directory
|
36
|
+
Go up 2 directories and then copy the path
|
37
|
+
Then in a terminal run "${colourC(`hsm`)} ${colourL(`config set`)} ${colourV(`hackmudPath`)} ${colourB(`<the path you copied>`)}"`));
|
38
|
+
const logHelp = () => {
|
39
|
+
const pushCommandDescription = `Push scripts from a directory to hackmud user's scripts directories`;
|
40
|
+
const watchCommandDescription = `Watch a directory and push a script when modified`;
|
41
|
+
const minifyCommandDescription = `Minify a script file on the spot`;
|
42
|
+
const generateTypeDeclarationCommandDescription = `Generate a type declaration file for a directory of scripts`;
|
43
|
+
const syncMacrosCommandDescription = `Sync macros across all hackmud users`;
|
44
|
+
const configCommandDescription = `Modify and view the config file`;
|
45
|
+
const configGetCommandDescription = `Retrieve a value from the config file`;
|
46
|
+
const configSetCommandDescription = `Assign a value to the config file`;
|
47
|
+
const configDeleteCommandDescription = `Remove a key and value from the config file`;
|
48
|
+
const pullCommandDescription = `Pull a script a from a hackmud user's script directory`;
|
49
|
+
const skipMinifyOptionDescription = `Skip minification to produce a readable script`;
|
50
|
+
const mangleNamesOptionDescription = `Reduce character count further but lose function names in error call stacks`;
|
51
|
+
const forceQuineCheatsOptionDescription = `Force quine cheats even if the character count is higher`;
|
52
|
+
console.log(colourN(`Version`) + colourS(`: `) + colourV(version));
|
53
|
+
switch (commands[0]) {
|
54
|
+
case `config`:
|
55
|
+
{
|
56
|
+
switch (commands[1]) {
|
57
|
+
case `get`:
|
58
|
+
{
|
59
|
+
console.log(`
|
60
|
+
${colourJ(configGetCommandDescription)}
|
61
|
+
|
62
|
+
${colourA(`Usage:`)}
|
63
|
+
${colourC(`hsm`)} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB(`<key>`)}`);
|
64
|
+
}
|
65
|
+
break;
|
66
|
+
case `set`:
|
67
|
+
{
|
68
|
+
console.log(`
|
69
|
+
${colourJ(configSetCommandDescription)}
|
70
|
+
|
71
|
+
${colourA(`Usage:`)}
|
72
|
+
${colourC(`hsm`)} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB(`<key> <value>`)}`);
|
73
|
+
}
|
74
|
+
break;
|
75
|
+
case `delete`:
|
76
|
+
{
|
77
|
+
console.log(`
|
78
|
+
${colourJ(configDeleteCommandDescription)}
|
79
|
+
|
80
|
+
${colourA(`Usage:`)}
|
81
|
+
${colourC(`hsm`)} ${colourL(`${commands[0]} ${commands[1]}`)} ${colourB(`<key>`)}`);
|
82
|
+
}
|
83
|
+
break;
|
84
|
+
default:
|
85
|
+
{
|
86
|
+
console.log(colourS(`\
|
87
|
+
${colourN(`Config path`)}: ${colourV(configFilePath)}
|
88
|
+
|
89
|
+
${colourJ(`Modify the config file`)}
|
90
|
+
|
91
|
+
${colourA(`Usage:`)}
|
92
|
+
${colourC(`hsm`)} ${colourL(`${commands[0]} get`)} ${colourB(`<key>`)}
|
93
|
+
${configGetCommandDescription}
|
94
|
+
${colourC(`hsm`)} ${colourL(`${commands[0]} set`)} ${colourB(`<key> <value>`)}
|
95
|
+
${configSetCommandDescription}
|
96
|
+
${colourC(`hsm`)} ${colourL(`${commands[0]} delete`)} ${colourB(`<key>`)}
|
97
|
+
${configDeleteCommandDescription}`));
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
break;
|
102
|
+
case `push`:
|
103
|
+
{
|
104
|
+
console.log(colourS(`
|
105
|
+
${colourJ(pushCommandDescription)}
|
106
|
+
|
107
|
+
${colourA(`Usage:`)}
|
108
|
+
${colourC(`hsm`)} ${colourL(commands[0])} ${colourB(`<directory> [<script user>.<script name>...]`)}
|
109
|
+
|
110
|
+
${colourA(`Options:`)}
|
111
|
+
${colourN(`--skip-minify`)}
|
112
|
+
${skipMinifyOptionDescription}
|
113
|
+
${colourN(`--mangle-names`)}
|
114
|
+
${mangleNamesOptionDescription}
|
115
|
+
${colourN(`--force-quine-cheats`)}
|
116
|
+
${forceQuineCheatsOptionDescription}`));
|
117
|
+
}
|
118
|
+
break;
|
119
|
+
case `dev`:
|
120
|
+
case `watch`:
|
121
|
+
{
|
122
|
+
console.log(colourS(`\
|
123
|
+
${colourN(`Aliases`)}: ${colourV(`watch, dev`)}
|
124
|
+
|
125
|
+
${colourJ(watchCommandDescription)}
|
126
|
+
|
127
|
+
${colourA(`Usage:`)}
|
128
|
+
${colourC(`hsm`)} ${colourL(commands[0])} ${colourB(`<directory> [<script user>.<script name>...]`)}
|
129
|
+
|
130
|
+
${colourA(`Options:`)}
|
131
|
+
${colourN(`--skip-minify`)}
|
132
|
+
${skipMinifyOptionDescription}
|
133
|
+
${colourN(`--mangle-names`)}
|
134
|
+
${mangleNamesOptionDescription}
|
135
|
+
${colourN(`--type-declaration-path`)}=${colourB(`<path>`)}
|
136
|
+
Path to generate a type declaration file for the scripts
|
137
|
+
${colourN(`--force-quine-cheats`)}
|
138
|
+
${forceQuineCheatsOptionDescription}`));
|
139
|
+
}
|
140
|
+
break;
|
141
|
+
case `pull`:
|
142
|
+
{
|
143
|
+
console.log(colourS(`
|
144
|
+
${colourJ(pullCommandDescription)}
|
145
|
+
|
146
|
+
${colourA(`Usage:`)}
|
147
|
+
${colourC(`hsm`)} ${colourL(commands[0])} ${colourB(`<script user>`)}${colourV(`.`)}${colourB(`<script name>`)}`));
|
148
|
+
}
|
149
|
+
break;
|
150
|
+
case `minify`:
|
151
|
+
case `golf`:
|
152
|
+
{
|
153
|
+
console.log(colourS(`\
|
154
|
+
${colourN(`Aliases`)}: ${colourV(`minify, golf`)}
|
155
|
+
|
156
|
+
${colourJ(minifyCommandDescription)}
|
157
|
+
|
158
|
+
${colourA(`Usage:`)}
|
159
|
+
${colourC(`hsm`)} ${colourL(commands[0])} ${colourB(`<target> [output path]`)}
|
160
|
+
|
161
|
+
${colourA(`Options:`)}
|
162
|
+
${colourN(`--skip-minify`)}
|
163
|
+
${skipMinifyOptionDescription}
|
164
|
+
${colourN(`--mangle-names`)}
|
165
|
+
${mangleNamesOptionDescription}
|
166
|
+
${colourN(`--force-quine-cheats`)}
|
167
|
+
${forceQuineCheatsOptionDescription}
|
168
|
+
${colourN(`--watch`)}
|
169
|
+
Watch for changes`));
|
170
|
+
}
|
171
|
+
break;
|
172
|
+
case `generate-type-declaration`:
|
173
|
+
case `gen-type-declaration`:
|
174
|
+
case `gen-dts`:
|
175
|
+
case `gen-types`:
|
176
|
+
{
|
177
|
+
console.log(colourS(`\
|
178
|
+
${colourN(`Aliases`)}: ${colourV(`generate-type-declaration, gen-type-declaration, gen-types, gen-dts`)}
|
179
|
+
|
180
|
+
${colourJ(generateTypeDeclarationCommandDescription)}
|
181
|
+
|
182
|
+
${colourA(`Usage:`)}
|
183
|
+
${colourC(`hsm`)} ${colourL(commands[0])} ${colourB(`<directory> [output path]`)}`));
|
184
|
+
}
|
185
|
+
break;
|
186
|
+
case `sync-macros`:
|
187
|
+
{
|
188
|
+
console.log(`\n${colourJ(syncMacrosCommandDescription)}`);
|
189
|
+
}
|
190
|
+
break;
|
191
|
+
default:
|
192
|
+
{
|
193
|
+
console.log(colourS(`
|
194
|
+
${colourJ(`Hackmud Script Manager`)}
|
195
|
+
|
196
|
+
${colourA(`Commands:`)}
|
197
|
+
${colourL(`push`)}
|
198
|
+
${pushCommandDescription}
|
199
|
+
${colourL(`watch`)}, ${colourL(`dev`)}
|
200
|
+
${watchCommandDescription}
|
201
|
+
${colourL(`minify`)}, ${colourL(`golf`)}
|
202
|
+
${minifyCommandDescription}
|
203
|
+
${colourL(`generate-type-declaration`)}, ${colourL(`gen-type-declaration`)}, ${colourL(`gen-types`)}, ${colourL(`gen-dts`)}
|
204
|
+
${generateTypeDeclarationCommandDescription}
|
205
|
+
${colourL(`sync-macros`)}
|
206
|
+
${syncMacrosCommandDescription}
|
207
|
+
${colourL(`config`)}
|
208
|
+
${configCommandDescription}
|
209
|
+
${colourL(`pull`)}
|
210
|
+
${pullCommandDescription}`));
|
211
|
+
}
|
212
|
+
}
|
213
|
+
};
|
214
|
+
const exploreObject = (object, keys, createPath = false) => {
|
215
|
+
for (const key of keys) {
|
216
|
+
var _object;
|
217
|
+
if (createPath) object = typeof object[key] == `object` ? object[key] : object[key] = {};else object = (_object = object) === null || _object === void 0 ? void 0 : _object[key];
|
218
|
+
}
|
219
|
+
return object;
|
220
|
+
};
|
221
|
+
const updateConfig = async config => {
|
222
|
+
const json = JSON.stringify(config, undefined, `\t`);
|
223
|
+
if (configDidNotExist) log(`Creating config file at ${configFilePath}`);
|
224
|
+
await writeFile(configFilePath, json).catch(async error => {
|
225
|
+
switch (error.code) {
|
226
|
+
case `EISDIR`:
|
227
|
+
{
|
228
|
+
await rmdir(configFilePath);
|
229
|
+
}
|
230
|
+
break;
|
231
|
+
case `ENOENT`:
|
232
|
+
{
|
233
|
+
await mkdir(configDirectoryPath);
|
234
|
+
}
|
235
|
+
break;
|
236
|
+
default:
|
237
|
+
throw error;
|
238
|
+
}
|
239
|
+
await writeFile(configFilePath, json);
|
240
|
+
});
|
241
|
+
};
|
242
|
+
const logInfo = ({
|
243
|
+
file,
|
244
|
+
users,
|
245
|
+
minLength,
|
246
|
+
error
|
247
|
+
}, hackmudPath) => {
|
248
|
+
if (error) {
|
249
|
+
logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`);
|
250
|
+
return;
|
251
|
+
}
|
252
|
+
console.log(`pushed ${chalk.bold(file)} to ${users.map(user => chalk.bold(userColours.get(user))).join(`, `)} | ${chalk.bold(String(minLength))} chars | ${chalk.bold(`${resolve(hackmudPath, users[0], `scripts`, basename(file, extname(file)))}.js`)}`);
|
253
|
+
};
|
254
|
+
const log = message => {
|
255
|
+
console.log(colourS(message));
|
256
|
+
};
|
257
|
+
const logError = message => {
|
258
|
+
console.error(colourD(message));
|
259
|
+
process.exitCode = 1;
|
260
|
+
};
|
261
|
+
for (const argument of process.argv.slice(2)) {
|
262
|
+
if (argument[0] == `-`) {
|
263
|
+
const [key, valueRaw] = argument.split(`=`);
|
264
|
+
let value = valueRaw;
|
265
|
+
if (value) {
|
266
|
+
if (value == `true`) value = true;else if (value == `false`) value = false;else {
|
267
|
+
const number = Number(value);
|
268
|
+
if (isFinite(number)) value = number;
|
269
|
+
}
|
270
|
+
} else value = true;
|
271
|
+
if (argument[1] == `-`) options.set(key.slice(2), value);else {
|
272
|
+
for (const option of key.slice(1)) options.set(option, value);
|
273
|
+
}
|
274
|
+
} else commands.push(argument);
|
275
|
+
}
|
276
|
+
if (commands[0] == `v` || commands[0] == `version` || options.get(`version`) || options.get(`v`)) {
|
277
|
+
console.log(version);
|
278
|
+
process.exit();
|
279
|
+
}
|
280
|
+
let configDidNotExist = false;
|
281
|
+
const configPromise = readFile(configFilePath, {
|
282
|
+
encoding: `utf-8`
|
283
|
+
}).then(configFile => {
|
284
|
+
let temporaryConfig;
|
285
|
+
try {
|
286
|
+
temporaryConfig = JSON.parse(configFile);
|
287
|
+
} catch {
|
288
|
+
// TODO log to error log file
|
289
|
+
log(`Config file was corrupted, resetting`);
|
290
|
+
return {};
|
291
|
+
}
|
292
|
+
if (!temporaryConfig || typeof temporaryConfig != `object`) {
|
293
|
+
log(`Config file was corrupted, resetting`);
|
294
|
+
return {};
|
295
|
+
}
|
296
|
+
if (`hackmudPath` in temporaryConfig && typeof temporaryConfig.hackmudPath != `string`) {
|
297
|
+
log(`Property "hackmudPath" of config file was corrupted, removing`);
|
298
|
+
delete temporaryConfig.hackmudPath;
|
299
|
+
}
|
300
|
+
return temporaryConfig;
|
301
|
+
}, () => {
|
302
|
+
configDidNotExist = true;
|
303
|
+
return {};
|
304
|
+
});
|
305
|
+
const pushModule = import('../push.js');
|
306
|
+
const processScriptModule = import('../processScript/index.js');
|
307
|
+
const watchModule = import('../watch.js');
|
308
|
+
const chokidarModule = import('chokidar');
|
309
|
+
const {
|
310
|
+
default: chalk
|
311
|
+
} = await import('chalk');
|
312
|
+
const colourA = chalk.rgb(0xFF, 0xFF, 0xFF);
|
313
|
+
const colourB = chalk.rgb(0xCA, 0xCA, 0xCA);
|
314
|
+
const colourC = chalk.rgb(0x9B, 0x9B, 0x9B);
|
315
|
+
const colourD = chalk.rgb(0xFF, 0x00, 0x00);
|
316
|
+
const colourJ = chalk.rgb(0xFF, 0xF4, 0x04);
|
317
|
+
const colourK = chalk.rgb(0xF3, 0xF9, 0x98);
|
318
|
+
const colourL = chalk.rgb(0x1E, 0xFF, 0x00);
|
319
|
+
const colourM = chalk.rgb(0xB3, 0xFF, 0x9B);
|
320
|
+
const colourN = chalk.rgb(0x00, 0xFF, 0xFF);
|
321
|
+
const colourS = chalk.rgb(0x7A, 0xB2, 0xF4);
|
322
|
+
const colourV = chalk.rgb(0xFF, 0x00, 0xEC);
|
323
|
+
const colourW = chalk.rgb(0xFF, 0x96, 0xE0);
|
324
|
+
if (options.get(`help`) || options.get(`h`)) {
|
325
|
+
logHelp();
|
326
|
+
process.exit();
|
327
|
+
}
|
328
|
+
let autoExit = true;
|
329
|
+
switch (commands[0]) {
|
330
|
+
case `push`:
|
331
|
+
{
|
332
|
+
const {
|
333
|
+
hackmudPath
|
334
|
+
} = await configPromise;
|
335
|
+
if (!hackmudPath) {
|
336
|
+
logNeedHackmudPathMessage();
|
337
|
+
break;
|
338
|
+
}
|
339
|
+
const sourcePath = commands[1];
|
340
|
+
if (!sourcePath) {
|
341
|
+
logError(`Must provide the directory to push from\n`);
|
342
|
+
logHelp();
|
343
|
+
break;
|
344
|
+
}
|
345
|
+
const scripts = commands.slice(2);
|
346
|
+
if (scripts.length) {
|
347
|
+
const invalidScript = scripts.find(script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script));
|
348
|
+
if (invalidScript) {
|
349
|
+
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`);
|
350
|
+
logHelp();
|
351
|
+
break;
|
352
|
+
}
|
353
|
+
} else scripts.push(`*.*`);
|
354
|
+
if (options.has(`skip-minify`) && options.has(`mangle-names`)) {
|
355
|
+
logError(`Option ${colourN(`--mangle-names`)} is not compatible with ${colourN(`--skip-minify`)}\n`);
|
356
|
+
logHelp();
|
357
|
+
break;
|
358
|
+
}
|
359
|
+
const shouldSkipMinify = options.get(`skip-minify`);
|
360
|
+
let shouldMinify;
|
361
|
+
if (shouldSkipMinify != undefined) {
|
362
|
+
if (typeof shouldSkipMinify != `boolean`) {
|
363
|
+
logError(`The value for ${colourN(`--skip-minify`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
364
|
+
logHelp();
|
365
|
+
break;
|
366
|
+
}
|
367
|
+
shouldMinify = !shouldSkipMinify;
|
368
|
+
}
|
369
|
+
const shouldMangleNames = options.get(`mangle-names`);
|
370
|
+
if (shouldMangleNames != undefined && typeof shouldMangleNames != `boolean`) {
|
371
|
+
logError(`The value for ${colourN(`--mangle-names`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
372
|
+
logHelp();
|
373
|
+
break;
|
374
|
+
}
|
375
|
+
const shouldforceQuineCheats = options.get(`force-quine-cheats`);
|
376
|
+
if (shouldforceQuineCheats != undefined && typeof shouldforceQuineCheats != `boolean`) {
|
377
|
+
logError(`The value for ${colourN(`--force-quine-cheats`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
378
|
+
logHelp();
|
379
|
+
break;
|
380
|
+
}
|
381
|
+
const {
|
382
|
+
push
|
383
|
+
} = await pushModule;
|
384
|
+
const infos = await push(sourcePath, hackmudPath, {
|
385
|
+
scripts,
|
386
|
+
onPush: info => logInfo(info, hackmudPath),
|
387
|
+
minify: shouldMinify,
|
388
|
+
mangleNames: shouldMangleNames,
|
389
|
+
forceQuineCheats: shouldforceQuineCheats
|
390
|
+
});
|
391
|
+
if (!infos.length) logError(`Could not find any scripts to push`);
|
392
|
+
}
|
393
|
+
break;
|
394
|
+
case `dev`:
|
395
|
+
case `watch`:
|
396
|
+
{
|
397
|
+
var _ref;
|
398
|
+
const {
|
399
|
+
hackmudPath
|
400
|
+
} = await configPromise;
|
401
|
+
if (!hackmudPath) {
|
402
|
+
logNeedHackmudPathMessage();
|
403
|
+
break;
|
404
|
+
}
|
405
|
+
const sourcePath = commands[1];
|
406
|
+
if (!sourcePath) {
|
407
|
+
logError(`Must provide the directory to watch\n`);
|
408
|
+
logHelp();
|
409
|
+
break;
|
410
|
+
}
|
411
|
+
const scripts = commands.slice(2);
|
412
|
+
if (scripts.length) {
|
413
|
+
const invalidScript = scripts.find(script => !/^(?:[a-z_][a-z\d_]{0,24}|\*)\.(?:[a-z_][a-z\d_]{0,24}|\*)$/.test(script));
|
414
|
+
if (invalidScript) {
|
415
|
+
logError(`Invalid script name: ${JSON.stringify(invalidScript)}\n`);
|
416
|
+
logHelp();
|
417
|
+
break;
|
418
|
+
}
|
419
|
+
} else scripts.push(`*.*`);
|
420
|
+
if (options.has(`skip-minify`) && options.has(`mangle-names`)) {
|
421
|
+
logError(`Option ${colourN(`--mangle-names`)} is not compatible with ${colourN(`--skip-minify`)}\n`);
|
422
|
+
logHelp();
|
423
|
+
break;
|
424
|
+
}
|
425
|
+
const shouldSkipMinify = options.get(`skip-minify`);
|
426
|
+
let shouldMinify;
|
427
|
+
if (shouldSkipMinify != undefined) {
|
428
|
+
if (typeof shouldSkipMinify != `boolean`) {
|
429
|
+
logError(`The value for ${colourN(`--skip-minify`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
430
|
+
logHelp();
|
431
|
+
break;
|
432
|
+
}
|
433
|
+
shouldMinify = !shouldSkipMinify;
|
434
|
+
}
|
435
|
+
const shouldMangleNames = options.get(`mangle-names`);
|
436
|
+
if (shouldMangleNames != undefined && typeof shouldMangleNames != `boolean`) {
|
437
|
+
logError(`The value for ${colourN(`--mangle-names`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
438
|
+
logHelp();
|
439
|
+
break;
|
440
|
+
}
|
441
|
+
const shouldforceQuineCheats = options.get(`force-quine-cheats`);
|
442
|
+
if (shouldforceQuineCheats != undefined && typeof shouldforceQuineCheats != `boolean`) {
|
443
|
+
logError(`The value for ${colourN(`--force-quine-cheats`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
444
|
+
logHelp();
|
445
|
+
break;
|
446
|
+
}
|
447
|
+
const {
|
448
|
+
watch
|
449
|
+
} = await watchModule;
|
450
|
+
watch(sourcePath, hackmudPath, {
|
451
|
+
scripts,
|
452
|
+
onPush: info => logInfo(info, hackmudPath),
|
453
|
+
typeDeclarationPath: (_ref = options.get(`type-declaration-path`) || options.get(`type-declaration`) || options.get(`dts`) || options.get(`gen-types`)) === null || _ref === void 0 ? void 0 : _ref.toString(),
|
454
|
+
minify: shouldMinify,
|
455
|
+
mangleNames: shouldMangleNames,
|
456
|
+
onReady: () => log(`Watching`),
|
457
|
+
forceQuineCheats: shouldforceQuineCheats
|
458
|
+
});
|
459
|
+
autoExit = false;
|
460
|
+
}
|
461
|
+
break;
|
462
|
+
case `pull`:
|
463
|
+
{
|
464
|
+
const {
|
465
|
+
hackmudPath
|
466
|
+
} = await configPromise;
|
467
|
+
if (!hackmudPath) {
|
468
|
+
logNeedHackmudPathMessage();
|
469
|
+
break;
|
470
|
+
}
|
471
|
+
const script = commands[1];
|
472
|
+
if (!script) {
|
473
|
+
logError(`Must provide the script to pull\n`);
|
474
|
+
logHelp();
|
475
|
+
break;
|
476
|
+
}
|
477
|
+
const sourcePath = commands[2] || `.`;
|
478
|
+
try {
|
479
|
+
await pull(sourcePath, hackmudPath, script);
|
480
|
+
} catch (error) {
|
481
|
+
console.error(error);
|
482
|
+
logError(`Something went wrong, did you forget to ${colourC(`#down`)} the script?`);
|
483
|
+
}
|
484
|
+
}
|
485
|
+
break;
|
486
|
+
case `sync-macros`:
|
487
|
+
{
|
488
|
+
const {
|
489
|
+
hackmudPath
|
490
|
+
} = await configPromise;
|
491
|
+
if (!hackmudPath) {
|
492
|
+
logNeedHackmudPathMessage();
|
493
|
+
break;
|
494
|
+
}
|
495
|
+
const {
|
496
|
+
macrosSynced,
|
497
|
+
usersSynced
|
498
|
+
} = await syncMacros(hackmudPath);
|
499
|
+
log(`Synced ${macrosSynced} macros to ${usersSynced} users`);
|
500
|
+
}
|
501
|
+
break;
|
502
|
+
case `generate-type-declaration`:
|
503
|
+
case `gen-type-declaration`:
|
504
|
+
case `gen-dts`:
|
505
|
+
case `gen-types`:
|
506
|
+
{
|
507
|
+
const target = commands[1];
|
508
|
+
if (!target) {
|
509
|
+
logError(`Must provide target directory\n`);
|
510
|
+
logHelp();
|
511
|
+
break;
|
512
|
+
}
|
513
|
+
const sourcePath = resolve(target);
|
514
|
+
const outputPath = commands[2] || `./player.d.ts`;
|
515
|
+
const typeDeclaration = await generateTypeDeclaration(sourcePath, (await configPromise).hackmudPath);
|
516
|
+
let typeDeclarationPath = resolve(outputPath);
|
517
|
+
try {
|
518
|
+
await writeFile(typeDeclarationPath, typeDeclaration);
|
519
|
+
} catch (error) {
|
520
|
+
assert(error instanceof Error);
|
521
|
+
if (!(error.code == `EISDIR`)) throw error;
|
522
|
+
typeDeclarationPath = resolve(typeDeclarationPath, `player.d.ts`);
|
523
|
+
await writeFile(typeDeclarationPath, typeDeclaration);
|
524
|
+
}
|
525
|
+
log(`Wrote type declaration to ${chalk.bold(typeDeclarationPath)}`);
|
526
|
+
}
|
527
|
+
break;
|
528
|
+
case `config`:
|
529
|
+
{
|
530
|
+
switch (commands[1]) {
|
531
|
+
case `get`:
|
532
|
+
{
|
533
|
+
const key = commands[2];
|
534
|
+
if (key) log(exploreObject(await configPromise, key.split(`.`)));else console.log(await configPromise);
|
535
|
+
}
|
536
|
+
break;
|
537
|
+
case `delete`:
|
538
|
+
{
|
539
|
+
var _exploreObject;
|
540
|
+
const key = commands[2];
|
541
|
+
if (!key) {
|
542
|
+
logError(`Must provide a key to delete\n`);
|
543
|
+
logHelp();
|
544
|
+
break;
|
545
|
+
}
|
546
|
+
const keyParts = key.split(`.`);
|
547
|
+
const pathName = keyParts.map(name => /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name)).join(`.`);
|
548
|
+
const lastKey = keyParts.pop();
|
549
|
+
const config = await configPromise;
|
550
|
+
(_exploreObject = exploreObject(config, keyParts)) === null || _exploreObject === void 0 || delete _exploreObject[lastKey];
|
551
|
+
log(`Removed ${colourV(pathName)} from config file`);
|
552
|
+
}
|
553
|
+
break;
|
554
|
+
case `set`:
|
555
|
+
{
|
556
|
+
const key = commands[2];
|
557
|
+
const value = commands[3];
|
558
|
+
if (!key) {
|
559
|
+
logError(`Must provide a key and value\n`);
|
560
|
+
logHelp();
|
561
|
+
break;
|
562
|
+
}
|
563
|
+
const keys = key.split(`.`);
|
564
|
+
const pathName = keys.map(name => /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name)).join(`.`);
|
565
|
+
if (!value) {
|
566
|
+
logError(`Must provide a value for the key ${pathName}\n`);
|
567
|
+
logHelp();
|
568
|
+
break;
|
569
|
+
}
|
570
|
+
const lastKey = keys.pop();
|
571
|
+
const config = await configPromise;
|
572
|
+
if (!keys.length && lastKey == `hackmudPath`) config.hackmudPath = resolve(value.startsWith(`~/`) ? homedir() + value.slice(1) : value);else {
|
573
|
+
let object = config;
|
574
|
+
for (const key of keys) {
|
575
|
+
if (typeof object[key] == `object`) object = object[key];else {
|
576
|
+
object[key] = {};
|
577
|
+
object = object[key];
|
578
|
+
}
|
579
|
+
}
|
580
|
+
object[lastKey] = value;
|
581
|
+
}
|
582
|
+
console.log(config);
|
583
|
+
await updateConfig(config);
|
584
|
+
}
|
585
|
+
break;
|
586
|
+
default:
|
587
|
+
{
|
588
|
+
if (commands[1]) logError(`Unknown command: ${JSON.stringify(commands[1])}\n`);
|
589
|
+
logHelp();
|
590
|
+
}
|
591
|
+
}
|
592
|
+
}
|
593
|
+
break;
|
594
|
+
case `help`:
|
595
|
+
case `h`:
|
596
|
+
{
|
597
|
+
logHelp();
|
598
|
+
}
|
599
|
+
break;
|
600
|
+
case `golf`:
|
601
|
+
case `minify`:
|
602
|
+
{
|
603
|
+
const target = commands[1];
|
604
|
+
if (!target) {
|
605
|
+
logError(`Must provide target\n`);
|
606
|
+
logHelp();
|
607
|
+
break;
|
608
|
+
}
|
609
|
+
const fileExtension = extname(target);
|
610
|
+
if (!supportedExtensions.includes(fileExtension)) {
|
611
|
+
logError(`Unsupported file extension "${chalk.bold(fileExtension)}"\nSupported extensions are "${supportedExtensions.map(extension => chalk.bold(extension)).join(`", "`)}"`);
|
612
|
+
break;
|
613
|
+
}
|
614
|
+
const {
|
615
|
+
processScript
|
616
|
+
} = await processScriptModule;
|
617
|
+
const fileBaseName = basename(target, fileExtension);
|
618
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations -- the file extension is `src` not `source`
|
619
|
+
const fileBaseNameEndsWithDotSrc = fileBaseName.endsWith(`.src`);
|
620
|
+
const scriptName = fileBaseNameEndsWithDotSrc ? fileBaseName.slice(0, -4) : fileBaseName;
|
621
|
+
const scriptUser = basename(resolve(target, `..`)) == `scripts` && basename(resolve(target, `../../..`)) == `hackmud` ? basename(resolve(target, `../..`)) : `UNKNOWN`;
|
622
|
+
const minify = !options.get(`skip-minify`);
|
623
|
+
if (options.has(`skip-minify`) && options.has(`mangle-names`)) {
|
624
|
+
logError(`Option ${colourN(`--mangle-names`)} would have no effect if minification is skipped\n`);
|
625
|
+
logHelp();
|
626
|
+
break;
|
627
|
+
}
|
628
|
+
const mangleNames_ = options.get(`mangle-names`);
|
629
|
+
if (mangleNames_ != undefined && typeof mangleNames_ != `boolean`) {
|
630
|
+
logError(`The value for ${colourN(`--mangle-names`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
631
|
+
logHelp();
|
632
|
+
break;
|
633
|
+
}
|
634
|
+
const mangleNames = mangleNames_;
|
635
|
+
const forceQuineCheats_ = options.get(`force-quine-cheats`);
|
636
|
+
if (forceQuineCheats_ != undefined && typeof forceQuineCheats_ != `boolean`) {
|
637
|
+
logError(`the value for ${colourN(`--force-quine-cheats`)} must be ${colourV(`true`)} or ${colourV(`false`)}\n`);
|
638
|
+
logHelp();
|
639
|
+
break;
|
640
|
+
}
|
641
|
+
const forceQuineCheats = forceQuineCheats_;
|
642
|
+
let outputPath = commands[2] || resolve(dirname(target), fileBaseNameEndsWithDotSrc ? `${scriptName}.js` : fileExtension == `.js` ? `${fileBaseName}.min.js` : `${fileBaseName}.js`);
|
643
|
+
const golfFile = () => readFile(target, {
|
644
|
+
encoding: `utf-8`
|
645
|
+
}).then(async source => {
|
646
|
+
const timeStart = performance.now();
|
647
|
+
const {
|
648
|
+
script,
|
649
|
+
warnings
|
650
|
+
} = await processScript(source, {
|
651
|
+
minify,
|
652
|
+
scriptUser,
|
653
|
+
scriptName,
|
654
|
+
filePath: target,
|
655
|
+
mangleNames,
|
656
|
+
forceQuineCheats
|
657
|
+
});
|
658
|
+
const timeTook = performance.now() - timeStart;
|
659
|
+
for (const {
|
660
|
+
message,
|
661
|
+
line
|
662
|
+
} of warnings) log(`Warning "${chalk.bold(message)}" on line ${chalk.bold(String(line))}`);
|
663
|
+
await writeFilePersistent(outputPath, script).catch(async error => {
|
664
|
+
if (!commands[2] || error.code != `EISDIR`) throw error;
|
665
|
+
outputPath = resolve(outputPath, `${basename(target, fileExtension)}.js`);
|
666
|
+
await writeFilePersistent(outputPath, script);
|
667
|
+
}).then(() => log(`Wrote ${chalk.bold(countHackmudCharacters(script))} chars to ${chalk.bold(relative(`.`, outputPath))} | took ${Math.round(timeTook * 100) / 100}ms`), error => logError(error.message));
|
668
|
+
}, error => logError(error.message));
|
669
|
+
if (options.get(`watch`)) {
|
670
|
+
const {
|
671
|
+
watch: watchFile
|
672
|
+
} = await chokidarModule;
|
673
|
+
watchFile(target, {
|
674
|
+
awaitWriteFinish: {
|
675
|
+
stabilityThreshold: 100
|
676
|
+
}
|
677
|
+
}).on(`ready`, () => log(`Watching ${target}`)).on(`change`, golfFile);
|
678
|
+
autoExit = false;
|
679
|
+
} else await golfFile();
|
680
|
+
}
|
681
|
+
break;
|
682
|
+
default:
|
683
|
+
{
|
684
|
+
if (commands[0]) logError(`Unknown command: ${JSON.stringify(commands[0])}\n`);
|
685
|
+
logHelp();
|
686
|
+
}
|
687
|
+
}
|
688
|
+
if (autoExit) process.exit();
|