hackmud-script-manager 0.19.0-fa82f73 → 0.19.1-003b022
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 +0 -2
- package/bin/hsm.js +600 -1
- package/constants.js +3 -1
- package/generateTypeDeclaration.js +68 -1
- package/index.js +51 -1
- package/package.json +37 -36
- package/processScript/index.js +316 -1
- package/processScript/minify.js +458 -1
- package/processScript/postprocess.js +20 -1
- package/processScript/preprocess.js +105 -1
- package/processScript/shared.js +32 -1
- package/processScript/transform.js +661 -1
- package/pull.js +11 -1
- package/push.js +269 -1
- package/syncMacros.js +43 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/watch.js +208 -1
package/pull.js
CHANGED
@@ -1 +1,11 @@
|
|
1
|
-
import{copyFilePersistent
|
1
|
+
import { copyFilePersistent } from "@samual/lib/copyFilePersistent"
|
2
|
+
import { resolve } from "path"
|
3
|
+
const pull = async (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 as default, pull }
|
package/push.js
CHANGED
@@ -1 +1,269 @@
|
|
1
|
-
import
|
1
|
+
import { Cache } from "@samual/lib/Cache"
|
2
|
+
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
3
|
+
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
4
|
+
import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
|
5
|
+
import { readFile } from "fs/promises"
|
6
|
+
import { basename, resolve, extname } from "path"
|
7
|
+
import { supportedExtensions } from "./constants.js"
|
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 "@samual/lib/assert"
|
33
|
+
import "prettier"
|
34
|
+
import "rollup"
|
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
|
+
const push = async (
|
46
|
+
sourceDirectory,
|
47
|
+
hackmudDirectory,
|
48
|
+
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
|
49
|
+
) => {
|
50
|
+
const scriptNamesByUser = new Cache(_user => new Set()),
|
51
|
+
wildScriptUsers = new Set(),
|
52
|
+
wildUserScripts = new Set()
|
53
|
+
let pushEverything = !1
|
54
|
+
for (const fullScriptName of scripts) {
|
55
|
+
const [user, scriptName] = fullScriptName.split(".")
|
56
|
+
user && "*" != user ?
|
57
|
+
scriptName && "*" != scriptName ?
|
58
|
+
scriptNamesByUser.get(user).add(scriptName)
|
59
|
+
: wildScriptUsers.add(user)
|
60
|
+
: scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
|
61
|
+
: (pushEverything = !0)
|
62
|
+
}
|
63
|
+
const usersByGlobalScriptsToPush = new Cache(_user => new Set()),
|
64
|
+
allInfo = [],
|
65
|
+
scriptNamesAlreadyPushedByUser = new Cache(_user => new Set())
|
66
|
+
let sourceDirectoryDirents
|
67
|
+
if (wildUserScripts.size || pushEverything) {
|
68
|
+
let hackmudDirectoryEntries
|
69
|
+
;[hackmudDirectoryEntries, sourceDirectoryDirents] = await Promise.all([
|
70
|
+
readDirectoryWithStats(hackmudDirectory),
|
71
|
+
readDirectoryWithStats(sourceDirectory)
|
72
|
+
])
|
73
|
+
const allUsers = new Set([
|
74
|
+
...sourceDirectoryDirents.filter(({ stats }) => stats.isDirectory()).map(({ path }) => basename(path)),
|
75
|
+
...hackmudDirectoryEntries.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
|
76
|
+
...hackmudDirectoryEntries
|
77
|
+
.filter(({ name, stats }) => stats.isFile() && name.endsWith(".key"))
|
78
|
+
.map(({ name }) => name.slice(0, -4)),
|
79
|
+
...scriptNamesByUser.keys(),
|
80
|
+
...wildScriptUsers
|
81
|
+
])
|
82
|
+
if (pushEverything) for (const user of allUsers) wildScriptUsers.add(user)
|
83
|
+
else
|
84
|
+
for (const user of allUsers) {
|
85
|
+
const scriptNames = scriptNamesByUser.get(user)
|
86
|
+
for (const scriptName of wildUserScripts) scriptNames.add(scriptName)
|
87
|
+
}
|
88
|
+
}
|
89
|
+
await Promise.all(
|
90
|
+
[...wildScriptUsers].map(async user => {
|
91
|
+
await readDirectoryWithStats(resolve(sourceDirectory, user)).then(
|
92
|
+
async entries => {
|
93
|
+
await Promise.all(
|
94
|
+
entries.map(async ({ stats, name, path }) => {
|
95
|
+
if (name.endsWith(".d.ts")) return
|
96
|
+
const extension = extname(name)
|
97
|
+
if (stats.isFile() && supportedExtensions.includes(extension)) {
|
98
|
+
const scriptName = basename(name, extension),
|
99
|
+
{ script: minifiedCode } = await processScript(
|
100
|
+
await readFile(path, { encoding: "utf-8" }),
|
101
|
+
{
|
102
|
+
minify,
|
103
|
+
scriptUser: user,
|
104
|
+
scriptName,
|
105
|
+
filePath: path,
|
106
|
+
mangleNames,
|
107
|
+
forceQuineCheats
|
108
|
+
}
|
109
|
+
),
|
110
|
+
info = {
|
111
|
+
file: `${user}/${name}`,
|
112
|
+
users: [user],
|
113
|
+
minLength: countHackmudCharacters(minifiedCode),
|
114
|
+
error: void 0
|
115
|
+
}
|
116
|
+
scriptNamesAlreadyPushedByUser.get(user).add(scriptName)
|
117
|
+
allInfo.push(info)
|
118
|
+
await writeFilePersistent(
|
119
|
+
resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
|
120
|
+
minifiedCode
|
121
|
+
)
|
122
|
+
onPush(info)
|
123
|
+
}
|
124
|
+
})
|
125
|
+
)
|
126
|
+
},
|
127
|
+
error => {
|
128
|
+
if ("ENOENT" != error.code) throw error
|
129
|
+
}
|
130
|
+
)
|
131
|
+
})
|
132
|
+
)
|
133
|
+
await Promise.all(
|
134
|
+
[...scriptNamesByUser].map(async ([user, scripts]) => {
|
135
|
+
wildScriptUsers.has(user) ||
|
136
|
+
(await Promise.all(
|
137
|
+
[...scripts].map(async scriptName => {
|
138
|
+
let code, fileName, filePath
|
139
|
+
for (const extension of supportedExtensions)
|
140
|
+
try {
|
141
|
+
fileName = `${scriptName}${extension}`
|
142
|
+
code = await readFile((filePath = resolve(sourceDirectory, user, fileName)), {
|
143
|
+
encoding: "utf-8"
|
144
|
+
})
|
145
|
+
break
|
146
|
+
} catch {}
|
147
|
+
if (code) {
|
148
|
+
const { script: minifiedCode } = await processScript(code, {
|
149
|
+
minify,
|
150
|
+
scriptUser: user,
|
151
|
+
scriptName,
|
152
|
+
filePath,
|
153
|
+
mangleNames,
|
154
|
+
forceQuineCheats
|
155
|
+
}),
|
156
|
+
info = {
|
157
|
+
file: `${user}/${fileName}`,
|
158
|
+
users: [user],
|
159
|
+
minLength: countHackmudCharacters(minifiedCode),
|
160
|
+
error: void 0
|
161
|
+
}
|
162
|
+
allInfo.push(info)
|
163
|
+
await writeFilePersistent(
|
164
|
+
resolve(hackmudDirectory, user, "scripts", scriptName + ".js"),
|
165
|
+
minifiedCode
|
166
|
+
)
|
167
|
+
onPush(info)
|
168
|
+
} else usersByGlobalScriptsToPush.get(scriptName).add(user)
|
169
|
+
})
|
170
|
+
))
|
171
|
+
})
|
172
|
+
)
|
173
|
+
await (wildScriptUsers.size ?
|
174
|
+
Promise.all(
|
175
|
+
(sourceDirectoryDirents || (await readDirectoryWithStats(sourceDirectory))).map(
|
176
|
+
async ({ path, stats, name }) => {
|
177
|
+
if (name.endsWith(".d.ts")) return
|
178
|
+
const extension = extname(name)
|
179
|
+
if (!stats.isFile() || !supportedExtensions.includes(extension)) return
|
180
|
+
const scriptName = basename(name, extension),
|
181
|
+
usersToPushTo = [...wildScriptUsers, ...usersByGlobalScriptsToPush.get(scriptName)].filter(
|
182
|
+
user => !scriptNamesAlreadyPushedByUser.get(user).has(scriptName)
|
183
|
+
)
|
184
|
+
if (!usersToPushTo.length) return
|
185
|
+
const uniqueID = Math.floor(Math.random() * 2 ** 52)
|
186
|
+
.toString(36)
|
187
|
+
.padStart(11, "0"),
|
188
|
+
{ script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf-8" }), {
|
189
|
+
minify,
|
190
|
+
scriptUser: !0,
|
191
|
+
scriptName,
|
192
|
+
uniqueID,
|
193
|
+
filePath: path,
|
194
|
+
mangleNames,
|
195
|
+
forceQuineCheats
|
196
|
+
}),
|
197
|
+
info = {
|
198
|
+
file: name,
|
199
|
+
users: usersToPushTo,
|
200
|
+
minLength: countHackmudCharacters(minifiedCode),
|
201
|
+
error: void 0
|
202
|
+
}
|
203
|
+
await Promise.all(
|
204
|
+
usersToPushTo.map(user =>
|
205
|
+
writeFilePersistent(
|
206
|
+
resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
|
207
|
+
minifiedCode
|
208
|
+
.replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
|
209
|
+
.replace(
|
210
|
+
RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
|
211
|
+
`${user}.${scriptName}`
|
212
|
+
)
|
213
|
+
)
|
214
|
+
)
|
215
|
+
)
|
216
|
+
allInfo.push(info)
|
217
|
+
onPush(info)
|
218
|
+
}
|
219
|
+
)
|
220
|
+
)
|
221
|
+
: Promise.all(
|
222
|
+
[...usersByGlobalScriptsToPush].map(async ([scriptName, users]) => {
|
223
|
+
let code, fileName, filePath
|
224
|
+
for (const extension of supportedExtensions)
|
225
|
+
try {
|
226
|
+
fileName = `${scriptName}${extension}`
|
227
|
+
code = await readFile((filePath = resolve(sourceDirectory, fileName)), { encoding: "utf-8" })
|
228
|
+
break
|
229
|
+
} catch {}
|
230
|
+
if (code) {
|
231
|
+
const uniqueID = Math.floor(Math.random() * 2 ** 52)
|
232
|
+
.toString(36)
|
233
|
+
.padStart(11, "0"),
|
234
|
+
{ script: minifiedCode } = await processScript(code, {
|
235
|
+
minify,
|
236
|
+
scriptUser: !0,
|
237
|
+
scriptName,
|
238
|
+
uniqueID,
|
239
|
+
filePath,
|
240
|
+
mangleNames,
|
241
|
+
forceQuineCheats
|
242
|
+
}),
|
243
|
+
info = {
|
244
|
+
file: fileName,
|
245
|
+
users: [...users],
|
246
|
+
minLength: countHackmudCharacters(minifiedCode),
|
247
|
+
error: void 0
|
248
|
+
}
|
249
|
+
await Promise.all(
|
250
|
+
[...users].map(user =>
|
251
|
+
writeFilePersistent(
|
252
|
+
resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
|
253
|
+
minifiedCode
|
254
|
+
.replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
|
255
|
+
.replace(
|
256
|
+
RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
|
257
|
+
`${user}.${scriptName}`
|
258
|
+
)
|
259
|
+
)
|
260
|
+
)
|
261
|
+
)
|
262
|
+
allInfo.push(info)
|
263
|
+
onPush(info)
|
264
|
+
}
|
265
|
+
})
|
266
|
+
))
|
267
|
+
return allInfo
|
268
|
+
}
|
269
|
+
export { push as default, push }
|
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
|
+
const syncMacros = async 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: "utf-8" }).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 as default, syncMacros }
|