hackmud-script-manager 0.19.0 → 0.19.1-01c1752
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/bin/hsm.d.ts +0 -0
- package/bin/hsm.js +436 -1
- package/constants.js +3 -1
- package/env.d.ts +1657 -0
- package/generateTypeDeclaration.d.ts +1 -2
- package/generateTypeDeclaration.js +68 -1
- package/index.d.ts +2 -2
- package/index.js +51 -1
- package/package.json +41 -38
- package/processScript/index.d.ts +17 -26
- package/processScript/index.js +333 -1
- package/processScript/minify.d.ts +15 -21
- package/processScript/minify.js +444 -1
- package/processScript/postprocess.d.ts +1 -2
- package/processScript/postprocess.js +20 -1
- package/processScript/preprocess.d.ts +7 -10
- package/processScript/preprocess.js +105 -1
- package/processScript/shared.d.ts +2 -2
- package/processScript/shared.js +32 -1
- package/processScript/transform.d.ts +13 -18
- package/processScript/transform.js +696 -1
- package/pull.d.ts +5 -9
- package/pull.js +11 -1
- package/push.d.ts +24 -33
- package/push.js +138 -1
- package/syncMacros.d.ts +1 -2
- package/syncMacros.js +43 -1
- package/watch.d.ts +10 -16
- package/watch.js +208 -1
- package/tsconfig.tsbuildinfo +0 -1
package/pull.d.ts
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
/**
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
* @param script to pull in `user.name` format
|
7
|
-
*/
|
8
|
-
export declare const pull: (sourceFolderPath: string, hackmudPath: string, script: string) => Promise<void>;
|
9
|
-
export default pull;
|
1
|
+
/** Copies script from hackmud to local source folder.
|
2
|
+
* @param sourceFolderPath path to folder containing source files
|
3
|
+
* @param hackmudPath path to hackmud directory
|
4
|
+
* @param script to pull in `user.name` format */
|
5
|
+
export declare function pull(sourceFolderPath: string, hackmudPath: string, script: string): Promise<void>;
|
package/pull.js
CHANGED
@@ -1 +1,11 @@
|
|
1
|
-
import{copyFilePersistent
|
1
|
+
import { copyFilePersistent } from "@samual/lib/copyFilePersistent"
|
2
|
+
import { resolve } from "path"
|
3
|
+
async function pull(sourceFolderPath, hackmudPath, script) {
|
4
|
+
const [user, name] = script.split(".")
|
5
|
+
if (!user || !name) throw Error('`script` argument must be in "user.name" format')
|
6
|
+
await copyFilePersistent(
|
7
|
+
resolve(hackmudPath, user, "scripts", name + ".js"),
|
8
|
+
resolve(sourceFolderPath, user, name + ".js")
|
9
|
+
)
|
10
|
+
}
|
11
|
+
export { pull }
|
package/push.d.ts
CHANGED
@@ -1,37 +1,28 @@
|
|
1
1
|
import type { LaxPartial } from "@samual/lib";
|
2
2
|
import type { Info } from ".";
|
3
|
-
export type PushOptions = {
|
4
|
-
/** whether to do the minify step (defaults to `true`) */
|
5
|
-
|
6
|
-
/**
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
* also accepts wild card (`*`) e.g. `*.bar` or `foo.*`
|
12
|
-
*
|
13
|
-
* pushes everything by default (`*.*`)
|
14
|
-
*/
|
3
|
+
export type PushOptions = LaxPartial<{
|
4
|
+
/** whether to do the minify step (defaults to `true`) */ minify: boolean;
|
5
|
+
/** whether to mangle function and class names (defaults to `false`) */ mangleNames: boolean;
|
6
|
+
/** array of scripts in the format `foo.bar`
|
7
|
+
*
|
8
|
+
* also accepts wild card (`*`) e.g. `*.bar` or `foo.*`
|
9
|
+
*
|
10
|
+
* pushes everything by default (`*.*`) */
|
15
11
|
scripts: string[];
|
16
|
-
/** callback called on script push */
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
* when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
|
24
|
-
*/
|
12
|
+
/** callback called on script push */ onPush: (info: Info) => void;
|
13
|
+
/** when set to `true` forces use of quine cheats
|
14
|
+
*
|
15
|
+
* when set to `false` forces quine cheats not to be used
|
16
|
+
*
|
17
|
+
* when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
|
18
|
+
*/
|
25
19
|
forceQuineCheats: boolean;
|
26
|
-
}
|
27
|
-
/**
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
*/
|
36
|
-
export declare const push: (sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: LaxPartial<PushOptions>) => Promise<Info[]>;
|
37
|
-
export default push;
|
20
|
+
}>;
|
21
|
+
/** Push scripts from a source directory to the hackmud directory.
|
22
|
+
*
|
23
|
+
* Pushes files directly in the source folder to all users
|
24
|
+
* @param sourcePath directory containing source code
|
25
|
+
* @param hackmudPath directory created by hackmud containing user data including scripts
|
26
|
+
* @param options {@link PushOptions details}
|
27
|
+
* @returns array of info on pushed scripts */
|
28
|
+
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
|
package/push.js
CHANGED
@@ -1 +1,138 @@
|
|
1
|
-
import
|
1
|
+
import { Cache } from "@samual/lib/Cache"
|
2
|
+
import { ensure, assert } from "@samual/lib/assert"
|
3
|
+
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
4
|
+
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
5
|
+
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
6
|
+
import { readFile } from "fs/promises"
|
7
|
+
import { basename, resolve } from "path"
|
8
|
+
import { processScript } from "./processScript/index.js"
|
9
|
+
import "@babel/generator"
|
10
|
+
import "@babel/parser"
|
11
|
+
import "@babel/plugin-proposal-decorators"
|
12
|
+
import "@babel/plugin-proposal-destructuring-private"
|
13
|
+
import "@babel/plugin-proposal-explicit-resource-management"
|
14
|
+
import "@babel/plugin-transform-class-properties"
|
15
|
+
import "@babel/plugin-transform-class-static-block"
|
16
|
+
import "@babel/plugin-transform-exponentiation-operator"
|
17
|
+
import "@babel/plugin-transform-json-strings"
|
18
|
+
import "@babel/plugin-transform-logical-assignment-operators"
|
19
|
+
import "@babel/plugin-transform-nullish-coalescing-operator"
|
20
|
+
import "@babel/plugin-transform-numeric-separator"
|
21
|
+
import "@babel/plugin-transform-object-rest-spread"
|
22
|
+
import "@babel/plugin-transform-optional-catch-binding"
|
23
|
+
import "@babel/plugin-transform-optional-chaining"
|
24
|
+
import "@babel/plugin-transform-private-property-in-object"
|
25
|
+
import "@babel/plugin-transform-unicode-sets-regex"
|
26
|
+
import "@babel/traverse"
|
27
|
+
import "@babel/types"
|
28
|
+
import "@rollup/plugin-babel"
|
29
|
+
import "@rollup/plugin-commonjs"
|
30
|
+
import "@rollup/plugin-json"
|
31
|
+
import "@rollup/plugin-node-resolve"
|
32
|
+
import "prettier"
|
33
|
+
import "rollup"
|
34
|
+
import "./constants.js"
|
35
|
+
import "./processScript/minify.js"
|
36
|
+
import "@samual/lib/spliceString"
|
37
|
+
import "acorn"
|
38
|
+
import "terser"
|
39
|
+
import "./processScript/shared.js"
|
40
|
+
import "./processScript/postprocess.js"
|
41
|
+
import "./processScript/preprocess.js"
|
42
|
+
import "import-meta-resolve"
|
43
|
+
import "./processScript/transform.js"
|
44
|
+
import "@samual/lib/clearObject"
|
45
|
+
async function push(
|
46
|
+
sourcePath,
|
47
|
+
hackmudPath,
|
48
|
+
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
|
49
|
+
) {
|
50
|
+
const [sourceFolder, hackmudFolder] = await Promise.all([
|
51
|
+
readDirectoryWithStats(sourcePath),
|
52
|
+
readDirectoryWithStats(hackmudPath)
|
53
|
+
]),
|
54
|
+
sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
|
55
|
+
allUsers = new Set([
|
56
|
+
...scripts
|
57
|
+
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:52:65"))
|
58
|
+
.filter(name => "*" != name),
|
59
|
+
...sourceFolderFolders.map(({ name }) => name),
|
60
|
+
...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
|
61
|
+
...hackmudFolder
|
62
|
+
.filter(({ stats, name }) => stats.isFile() && name.endsWith(".key"))
|
63
|
+
.map(({ name }) => name.slice(0, -4))
|
64
|
+
]),
|
65
|
+
usersToScriptsToPush = new Cache(_user => new Map()),
|
66
|
+
scriptNamesToUsers = new Cache(_scriptName => new Set())
|
67
|
+
for (const script of scripts) {
|
68
|
+
const [user, scriptName] = script.split(".")
|
69
|
+
assert(user, "src/push.ts:69:16")
|
70
|
+
assert(scriptName, "src/push.ts:70:22")
|
71
|
+
"*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
|
72
|
+
}
|
73
|
+
const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
|
74
|
+
wildScriptUsers_ = scriptNamesToUsers.get("*")
|
75
|
+
scriptNamesToUsers.delete("*")
|
76
|
+
for (const { name, path } of [
|
77
|
+
...sourceFolderFiles.filter(({ name }) => name.endsWith(".js")),
|
78
|
+
...sourceFolderFiles.filter(({ name }) => name.endsWith(".ts"))
|
79
|
+
]) {
|
80
|
+
const scriptName = name.slice(0, -3)
|
81
|
+
for (const user of [...wildScriptUsers_, ...scriptNamesToUsers.get(scriptName)])
|
82
|
+
usersToScriptsToPush.get(user).set(scriptName, path)
|
83
|
+
}
|
84
|
+
await Promise.all(
|
85
|
+
sourceFolderFolders.map(async ({ name: user, path }) => {
|
86
|
+
const files = (await readDirectoryWithStats(path)).filter(({ stats }) => stats.isFile()),
|
87
|
+
scriptFiles = [
|
88
|
+
...files.filter(({ name }) => name.endsWith(".js")),
|
89
|
+
...files.filter(({ name }) => name.endsWith(".ts"))
|
90
|
+
]
|
91
|
+
for (const { name, path } of scriptFiles) {
|
92
|
+
const scriptName = name.slice(0, -3)
|
93
|
+
;[...wildScriptUsers_, ...scriptNamesToUsers.get(scriptName)].includes(user) &&
|
94
|
+
usersToScriptsToPush.get(user).set(scriptName, path)
|
95
|
+
}
|
96
|
+
})
|
97
|
+
)
|
98
|
+
for (const [scriptName, users] of scriptNamesToUsers)
|
99
|
+
for (const user of users)
|
100
|
+
if (!usersToScriptsToPush.get(user).has(scriptName))
|
101
|
+
throw Error(`Could not find script ${user}.${scriptName} to push`)
|
102
|
+
const pathsToUsers = new Cache(_path => new Set())
|
103
|
+
for (const [user, scriptsToPush] of usersToScriptsToPush)
|
104
|
+
for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
|
105
|
+
const allInfo = []
|
106
|
+
await Promise.all(
|
107
|
+
[...pathsToUsers].map(async ([path, [...users]]) => {
|
108
|
+
const scriptName = basename(path.slice(0, -3)),
|
109
|
+
uniqueId = Math.floor(Math.random() * 2 ** 52)
|
110
|
+
.toString(36)
|
111
|
+
.padStart(11, "0"),
|
112
|
+
{ script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf8" }), {
|
113
|
+
minify,
|
114
|
+
scriptUser: !0,
|
115
|
+
scriptName,
|
116
|
+
uniqueId,
|
117
|
+
filePath: path,
|
118
|
+
mangleNames,
|
119
|
+
forceQuineCheats
|
120
|
+
}),
|
121
|
+
info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0 }
|
122
|
+
await Promise.all(
|
123
|
+
users.map(user =>
|
124
|
+
writeFilePersistent(
|
125
|
+
resolve(hackmudPath, user, `scripts/${scriptName}.js`),
|
126
|
+
minifiedCode
|
127
|
+
.replace(RegExp(`\\$${uniqueId}\\$SCRIPT_USER\\$`, "g"), user)
|
128
|
+
.replace(RegExp(`\\$${uniqueId}\\$FULL_SCRIPT_NAME\\$`, "g"), `${user}.${scriptName}`)
|
129
|
+
)
|
130
|
+
)
|
131
|
+
)
|
132
|
+
allInfo.push(info)
|
133
|
+
onPush(info)
|
134
|
+
})
|
135
|
+
)
|
136
|
+
return allInfo
|
137
|
+
}
|
138
|
+
export { push }
|
package/syncMacros.d.ts
CHANGED
package/syncMacros.js
CHANGED
@@ -1 +1,43 @@
|
|
1
|
-
import{
|
1
|
+
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
2
|
+
import { readFile, stat, writeFile } from "fs/promises"
|
3
|
+
import { extname, basename, resolve } from "path"
|
4
|
+
async function syncMacros(hackmudPath) {
|
5
|
+
const files = await readDirectoryWithStats(hackmudPath),
|
6
|
+
macros = new Map(),
|
7
|
+
users = []
|
8
|
+
await Promise.all(
|
9
|
+
files.map(async file => {
|
10
|
+
if (file.stats.isFile())
|
11
|
+
switch (extname(file.name)) {
|
12
|
+
case ".macros":
|
13
|
+
{
|
14
|
+
const [lines, date] = await Promise.all([
|
15
|
+
readFile(resolve(hackmudPath, file.name), { encoding: "utf8" }).then(file =>
|
16
|
+
file.split("\n")
|
17
|
+
),
|
18
|
+
stat(resolve(hackmudPath, file.name)).then(({ mtime }) => mtime)
|
19
|
+
])
|
20
|
+
for (let index = 0; index < lines.length / 2 - 1; index++) {
|
21
|
+
const macroName = lines[2 * index],
|
22
|
+
currentMacro = macros.get(macroName)
|
23
|
+
;(!currentMacro || date > currentMacro.date) &&
|
24
|
+
macros.set(macroName, { date, macro: lines[2 * index + 1] })
|
25
|
+
}
|
26
|
+
}
|
27
|
+
break
|
28
|
+
case ".key":
|
29
|
+
users.push(basename(file.name, ".key"))
|
30
|
+
}
|
31
|
+
})
|
32
|
+
)
|
33
|
+
let macroFile = "",
|
34
|
+
macrosSynced = 0
|
35
|
+
for (const [name, { macro }] of [...macros].sort(([a], [b]) => (a > b) - (a < b)))
|
36
|
+
if (macro[0] == macro[0].toLowerCase()) {
|
37
|
+
macroFile += `${name}\n${macro}\n`
|
38
|
+
macrosSynced++
|
39
|
+
}
|
40
|
+
for (const user of users) writeFile(resolve(hackmudPath, user + ".macros"), macroFile)
|
41
|
+
return { macrosSynced, usersSynced: users.length }
|
42
|
+
}
|
43
|
+
export { syncMacros }
|
package/watch.d.ts
CHANGED
@@ -1,20 +1,14 @@
|
|
1
1
|
import type { LaxPartial } from "@samual/lib";
|
2
2
|
import type { PushOptions } from "./push";
|
3
|
-
export type WatchOptions = PushOptions & {
|
4
|
-
/**
|
5
|
-
|
6
|
-
|
7
|
-
* writing the type declarations enables interscript type checking and autocompletetes for the args
|
8
|
-
*/
|
3
|
+
export type WatchOptions = PushOptions & LaxPartial<{
|
4
|
+
/** if provided, will write typescript type declarations for all the scripts on every change detected
|
5
|
+
*
|
6
|
+
* writing the type declarations enables interscript type checking and autocompletetes for the args */
|
9
7
|
typeDeclarationPath: string;
|
10
8
|
onReady: () => void;
|
11
|
-
}
|
12
|
-
/**
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
* @param options {@link WatchOptions details} and {@link PushOptions more details}
|
18
|
-
*/
|
19
|
-
export declare const watch: (sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats }?: LaxPartial<WatchOptions>) => Promise<void>;
|
20
|
-
export default watch;
|
9
|
+
}>;
|
10
|
+
/** Watches target file or folder for updates and builds and pushes updated file.
|
11
|
+
* @param sourceDirectory path to folder containing source files
|
12
|
+
* @param hackmudDirectory path to hackmud directory
|
13
|
+
* @param options {@link WatchOptions details} and {@link PushOptions more details} */
|
14
|
+
export declare function watch(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats }?: WatchOptions): Promise<void>;
|
package/watch.js
CHANGED
@@ -1 +1,208 @@
|
|
1
|
-
import
|
1
|
+
import { Cache } from "@samual/lib/Cache"
|
2
|
+
import { assert } from "@samual/lib/assert"
|
3
|
+
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
4
|
+
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
5
|
+
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
6
|
+
import { watch as watch$1 } from "chokidar"
|
7
|
+
import { readFile, writeFile } from "fs/promises"
|
8
|
+
import { extname, basename, resolve } from "path"
|
9
|
+
import { supportedExtensions } from "./constants.js"
|
10
|
+
import { generateTypeDeclaration } from "./generateTypeDeclaration.js"
|
11
|
+
import { processScript } from "./processScript/index.js"
|
12
|
+
import "@babel/generator"
|
13
|
+
import "@babel/parser"
|
14
|
+
import "@babel/plugin-proposal-decorators"
|
15
|
+
import "@babel/plugin-proposal-destructuring-private"
|
16
|
+
import "@babel/plugin-proposal-explicit-resource-management"
|
17
|
+
import "@babel/plugin-transform-class-properties"
|
18
|
+
import "@babel/plugin-transform-class-static-block"
|
19
|
+
import "@babel/plugin-transform-exponentiation-operator"
|
20
|
+
import "@babel/plugin-transform-json-strings"
|
21
|
+
import "@babel/plugin-transform-logical-assignment-operators"
|
22
|
+
import "@babel/plugin-transform-nullish-coalescing-operator"
|
23
|
+
import "@babel/plugin-transform-numeric-separator"
|
24
|
+
import "@babel/plugin-transform-object-rest-spread"
|
25
|
+
import "@babel/plugin-transform-optional-catch-binding"
|
26
|
+
import "@babel/plugin-transform-optional-chaining"
|
27
|
+
import "@babel/plugin-transform-private-property-in-object"
|
28
|
+
import "@babel/plugin-transform-unicode-sets-regex"
|
29
|
+
import "@babel/traverse"
|
30
|
+
import "@babel/types"
|
31
|
+
import "@rollup/plugin-babel"
|
32
|
+
import "@rollup/plugin-commonjs"
|
33
|
+
import "@rollup/plugin-json"
|
34
|
+
import "@rollup/plugin-node-resolve"
|
35
|
+
import "prettier"
|
36
|
+
import "rollup"
|
37
|
+
import "./processScript/minify.js"
|
38
|
+
import "@samual/lib/spliceString"
|
39
|
+
import "acorn"
|
40
|
+
import "terser"
|
41
|
+
import "./processScript/shared.js"
|
42
|
+
import "./processScript/postprocess.js"
|
43
|
+
import "./processScript/preprocess.js"
|
44
|
+
import "import-meta-resolve"
|
45
|
+
import "./processScript/transform.js"
|
46
|
+
import "@samual/lib/clearObject"
|
47
|
+
async function watch(
|
48
|
+
sourceDirectory,
|
49
|
+
hackmudDirectory,
|
50
|
+
{
|
51
|
+
scripts = ["*.*"],
|
52
|
+
onPush,
|
53
|
+
minify = !0,
|
54
|
+
mangleNames = !1,
|
55
|
+
typeDeclarationPath: typeDeclarationPath_,
|
56
|
+
onReady,
|
57
|
+
forceQuineCheats
|
58
|
+
} = {}
|
59
|
+
) {
|
60
|
+
if (!scripts.length) throw Error("scripts option was an empty array")
|
61
|
+
const scriptNamesToUsers = new Cache(_scriptName => new Set()),
|
62
|
+
wildScriptUsers = new Set(),
|
63
|
+
wildUserScripts = new Set()
|
64
|
+
let pushEverything = !1
|
65
|
+
for (const fullScriptName of scripts) {
|
66
|
+
const [user, scriptName] = fullScriptName.split(".")
|
67
|
+
user && "*" != user ?
|
68
|
+
scriptName && "*" != scriptName ?
|
69
|
+
scriptNamesToUsers.get(scriptName).add(user)
|
70
|
+
: wildScriptUsers.add(user)
|
71
|
+
: scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
|
72
|
+
: (pushEverything = !0)
|
73
|
+
}
|
74
|
+
const watcher = watch$1(["*/*.ts", "*/*.js"], {
|
75
|
+
cwd: sourceDirectory,
|
76
|
+
awaitWriteFinish: { stabilityThreshold: 100 },
|
77
|
+
ignored: "*.d.ts"
|
78
|
+
}).on("change", async path => {
|
79
|
+
if (path.endsWith(".d.ts")) return
|
80
|
+
const extension = extname(path)
|
81
|
+
if (!supportedExtensions.includes(extension)) return
|
82
|
+
const scriptName = basename(path, extension)
|
83
|
+
if (path == basename(path)) {
|
84
|
+
if (
|
85
|
+
!(
|
86
|
+
pushEverything ||
|
87
|
+
wildScriptUsers.size ||
|
88
|
+
wildUserScripts.has(scriptName) ||
|
89
|
+
scriptNamesToUsers.has(scriptName)
|
90
|
+
)
|
91
|
+
)
|
92
|
+
return
|
93
|
+
const scriptNamesToUsersToSkip = new Cache(_scriptName => [])
|
94
|
+
await Promise.all(
|
95
|
+
(await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name, path }) => {
|
96
|
+
if (stats.isDirectory())
|
97
|
+
for (const child of await readDirectoryWithStats(path))
|
98
|
+
if (child.stats.isFile()) {
|
99
|
+
const fileExtension = extname(child.name)
|
100
|
+
supportedExtensions.includes(fileExtension) &&
|
101
|
+
scriptNamesToUsersToSkip.get(basename(child.name, fileExtension)).push(name)
|
102
|
+
}
|
103
|
+
})
|
104
|
+
)
|
105
|
+
const usersToPushToSet = new Set()
|
106
|
+
if (pushEverything || wildUserScripts.has(scriptName)) {
|
107
|
+
for (const { stats, name } of await readDirectoryWithStats(sourceDirectory))
|
108
|
+
stats.isDirectory() && usersToPushToSet.add(name)
|
109
|
+
for (const { stats, name } of await readDirectoryWithStats(hackmudDirectory))
|
110
|
+
stats.isDirectory() ?
|
111
|
+
usersToPushToSet.add(name)
|
112
|
+
: stats.isFile() && name.endsWith(".key") && usersToPushToSet.add(name.slice(0, -4))
|
113
|
+
for (const users of scriptNamesToUsers.values()) for (const user of users) usersToPushToSet.add(user)
|
114
|
+
}
|
115
|
+
for (const user of wildScriptUsers) usersToPushToSet.add(user)
|
116
|
+
for (const user of scriptNamesToUsers.get(scriptName)) usersToPushToSet.add(user)
|
117
|
+
const usersToPushTo = [...usersToPushToSet].filter(user => !scriptNamesToUsersToSkip.has(user))
|
118
|
+
if (!usersToPushTo.length) {
|
119
|
+
onPush?.({ path, users: [], characterCount: 0, error: Error("no users to push to") })
|
120
|
+
return
|
121
|
+
}
|
122
|
+
const uniqueId = Math.floor(Math.random() * 2 ** 52)
|
123
|
+
.toString(36)
|
124
|
+
.padStart(11, "0"),
|
125
|
+
filePath = resolve(sourceDirectory, path)
|
126
|
+
let minifiedCode
|
127
|
+
try {
|
128
|
+
;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf8" }), {
|
129
|
+
minify,
|
130
|
+
scriptUser: !0,
|
131
|
+
scriptName,
|
132
|
+
uniqueId,
|
133
|
+
filePath,
|
134
|
+
mangleNames,
|
135
|
+
forceQuineCheats
|
136
|
+
}))
|
137
|
+
} catch (error) {
|
138
|
+
assert(error instanceof Error, "src/watch.ts:141:36")
|
139
|
+
onPush?.({ path, users: [], characterCount: 0, error })
|
140
|
+
return
|
141
|
+
}
|
142
|
+
await Promise.all(
|
143
|
+
usersToPushTo.map(user =>
|
144
|
+
writeFilePersistent(
|
145
|
+
resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
|
146
|
+
minifiedCode
|
147
|
+
.replace(RegExp(`\\$${uniqueId}\\$SCRIPT_USER\\$`, "g"), user)
|
148
|
+
.replace(RegExp(`\\$${uniqueId}\\$FULL_SCRIPT_NAME\\$`, "g"), `${user}.${scriptName}`)
|
149
|
+
)
|
150
|
+
)
|
151
|
+
)
|
152
|
+
onPush?.({
|
153
|
+
path,
|
154
|
+
users: usersToPushTo,
|
155
|
+
characterCount: countHackmudCharacters(minifiedCode),
|
156
|
+
error: void 0
|
157
|
+
})
|
158
|
+
return
|
159
|
+
}
|
160
|
+
const user = basename(resolve(path, ".."))
|
161
|
+
if (
|
162
|
+
!(
|
163
|
+
pushEverything ||
|
164
|
+
wildScriptUsers.size ||
|
165
|
+
wildUserScripts.has(scriptName) ||
|
166
|
+
scriptNamesToUsers.get(scriptName).has(user)
|
167
|
+
)
|
168
|
+
)
|
169
|
+
return
|
170
|
+
const filePath = resolve(sourceDirectory, path),
|
171
|
+
sourceCode = await readFile(filePath, { encoding: "utf8" })
|
172
|
+
let script
|
173
|
+
try {
|
174
|
+
;({ script } = await processScript(sourceCode, {
|
175
|
+
minify,
|
176
|
+
scriptUser: user,
|
177
|
+
scriptName,
|
178
|
+
filePath,
|
179
|
+
mangleNames,
|
180
|
+
forceQuineCheats
|
181
|
+
}))
|
182
|
+
} catch (error) {
|
183
|
+
assert(error instanceof Error, "src/watch.ts:177:35")
|
184
|
+
onPush?.({ path, users: [], characterCount: 0, error })
|
185
|
+
return
|
186
|
+
}
|
187
|
+
await writeFilePersistent(resolve(hackmudDirectory, user, "scripts", scriptName + ".js"), script)
|
188
|
+
onPush?.({ path, users: [user], characterCount: countHackmudCharacters(script), error: void 0 })
|
189
|
+
})
|
190
|
+
onReady && watcher.on("ready", onReady)
|
191
|
+
if (!typeDeclarationPath_) return
|
192
|
+
let typeDeclarationPath = typeDeclarationPath_
|
193
|
+
const writeTypeDeclaration = async () => {
|
194
|
+
const typeDeclaration = await generateTypeDeclaration(sourceDirectory, hackmudDirectory)
|
195
|
+
try {
|
196
|
+
await writeFile(typeDeclarationPath, typeDeclaration)
|
197
|
+
} catch (error) {
|
198
|
+
assert(error instanceof Error, "src/watch.ts:210:35")
|
199
|
+
if ("EISDIR" != error.code) throw error
|
200
|
+
typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
|
201
|
+
await writeFile(typeDeclarationPath, typeDeclaration)
|
202
|
+
}
|
203
|
+
}
|
204
|
+
await writeTypeDeclaration()
|
205
|
+
watcher.on("add", writeTypeDeclaration)
|
206
|
+
watcher.on("unlink", writeTypeDeclaration)
|
207
|
+
}
|
208
|
+
export { watch }
|