hackmud-script-manager 0.19.1-5bceac8 → 0.19.1-6d8d544

Sign up to get free protection for your applications and to get access to all the features.
package/pull.d.ts CHANGED
@@ -1,9 +1,5 @@
1
- /**
2
- * Copies script from hackmud to local source folder.
3
- *
4
- * @param sourceFolderPath path to folder containing source files
5
- * @param hackmudPath path to hackmud directory
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,6 +1,6 @@
1
1
  import { copyFilePersistent } from "@samual/lib/copyFilePersistent"
2
2
  import { resolve } from "path"
3
- const pull = async (sourceFolderPath, hackmudPath, script) => {
3
+ async function pull(sourceFolderPath, hackmudPath, script) {
4
4
  const [user, name] = script.split(".")
5
5
  if (!user || !name) throw Error('`script` argument must be in "user.name" format')
6
6
  await copyFilePersistent(
@@ -8,4 +8,4 @@ const pull = async (sourceFolderPath, hackmudPath, script) => {
8
8
  resolve(sourceFolderPath, user, name + ".js")
9
9
  )
10
10
  }
11
- export { pull as default, pull }
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
- minify: boolean;
6
- /** whether to mangle function and class names (defaults to `false`) */
7
- mangleNames: boolean;
8
- /**
9
- * array of scripts in the format `foo.bar`
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
- onPush: (info: Info) => void;
18
- /**
19
- * when set to `true` forces use of quine cheats
20
- *
21
- * when set to `false` forces quine cheats not to be used
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
- * Push scripts from a source directory to the hackmud directory.
29
- *
30
- * Pushes files directly in the source folder to all users
31
- * @param sourceDirectory directory containing source code
32
- * @param hackmudDirectory directory created by hackmud containing user data including scripts
33
- * @param options {@link PushOptions details}
34
- * @returns array of info on pushed scripts
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,9 +1,10 @@
1
1
  import { Cache } from "@samual/lib/Cache"
2
+ import { ensure, assert } from "@samual/lib/assert"
2
3
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
3
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
4
- import { readdir, readFile } from "fs/promises"
5
- import { resolve, extname, basename } from "path"
6
- import { supportedExtensions } from "./constants.js"
6
+ import { readFile } from "fs/promises"
7
+ import { basename, resolve } from "path"
7
8
  import { processScript } from "./processScript/index.js"
8
9
  import "@babel/generator"
9
10
  import "@babel/parser"
@@ -28,9 +29,9 @@ import "@rollup/plugin-babel"
28
29
  import "@rollup/plugin-commonjs"
29
30
  import "@rollup/plugin-json"
30
31
  import "@rollup/plugin-node-resolve"
31
- import "@samual/lib/assert"
32
32
  import "prettier"
33
33
  import "rollup"
34
+ import "./constants.js"
34
35
  import "./processScript/minify.js"
35
36
  import "@samual/lib/spliceString"
36
37
  import "acorn"
@@ -41,223 +42,97 @@ import "./processScript/preprocess.js"
41
42
  import "import-meta-resolve"
42
43
  import "./processScript/transform.js"
43
44
  import "@samual/lib/clearObject"
44
- const push = async (
45
- sourceDirectory,
46
- hackmudDirectory,
45
+ async function push(
46
+ sourcePath,
47
+ hackmudPath,
47
48
  { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
48
- ) => {
49
- const scriptNamesByUser = new Cache(_user => new Set()),
50
- wildScriptUsers = new Set(),
51
- wildUserScripts = new Set()
52
- let pushEverything = !1
53
- for (const fullScriptName of scripts) {
54
- const [user, scriptName] = fullScriptName.split(".")
55
- user && "*" != user ?
56
- scriptName && "*" != scriptName ?
57
- scriptNamesByUser.get(user).add(scriptName)
58
- : wildScriptUsers.add(user)
59
- : scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
60
- : (pushEverything = !0)
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)
61
72
  }
62
- const usersByGlobalScriptsToPush = new Cache(_user => new Set()),
63
- allInfo = [],
64
- scriptNamesAlreadyPushedByUser = new Cache(_user => new Set())
65
- let sourceDirectoryDirents
66
- if (wildUserScripts.size || pushEverything) {
67
- const hackmudDirectoryDirents = await readdir(resolve(hackmudDirectory), { withFileTypes: !0 }),
68
- allUsers = new Set([
69
- ...(sourceDirectoryDirents = await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))
70
- .filter(dirent => dirent.isDirectory())
71
- .map(dirent => dirent.name),
72
- ...hackmudDirectoryDirents.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name),
73
- ...hackmudDirectoryDirents
74
- .filter(dirent => dirent.isFile() && dirent.name.endsWith(".key"))
75
- .map(dirent => dirent.name.slice(0, -4)),
76
- ...scriptNamesByUser.keys(),
77
- ...wildScriptUsers
78
- ])
79
- if (pushEverything) for (const user of allUsers) wildScriptUsers.add(user)
80
- else
81
- for (const user of allUsers) {
82
- const scriptNames = scriptNamesByUser.get(user)
83
- for (const scriptName of wildUserScripts) scriptNames.add(scriptName)
84
- }
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)
85
83
  }
86
84
  await Promise.all(
87
- [...wildScriptUsers].map(async user => {
88
- await readdir(resolve(sourceDirectory, user), { withFileTypes: !0 }).then(
89
- async dirents => {
90
- await Promise.all(
91
- dirents.map(async dirent => {
92
- if (dirent.name.endsWith(".d.ts")) return
93
- const extension = extname(dirent.name)
94
- if (dirent.isFile() && supportedExtensions.includes(extension)) {
95
- const scriptName = basename(dirent.name, extension),
96
- filePath = resolve(sourceDirectory, user, dirent.name),
97
- { script: minifiedCode } = await processScript(
98
- await readFile(filePath, { encoding: "utf-8" }),
99
- {
100
- minify,
101
- scriptUser: user,
102
- scriptName,
103
- filePath,
104
- mangleNames,
105
- forceQuineCheats
106
- }
107
- ),
108
- info = {
109
- file: `${user}/${dirent.name}`,
110
- users: [user],
111
- minLength: countHackmudCharacters(minifiedCode),
112
- error: void 0
113
- }
114
- scriptNamesAlreadyPushedByUser.get(user).add(scriptName)
115
- allInfo.push(info)
116
- await writeFilePersistent(
117
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
118
- minifiedCode
119
- )
120
- onPush(info)
121
- }
122
- })
123
- )
124
- },
125
- error => {
126
- if ("ENOENT" != error.code) throw error
127
- }
128
- )
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
+ }
129
96
  })
130
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 = []
131
106
  await Promise.all(
132
- [...scriptNamesByUser].map(async ([user, scripts]) => {
133
- wildScriptUsers.has(user) ||
134
- (await Promise.all(
135
- [...scripts].map(async scriptName => {
136
- let code, fileName, filePath
137
- for (const extension of supportedExtensions)
138
- try {
139
- fileName = `${scriptName}${extension}`
140
- code = await readFile((filePath = resolve(sourceDirectory, user, fileName)), {
141
- encoding: "utf-8"
142
- })
143
- break
144
- } catch {}
145
- if (code) {
146
- const { script: minifiedCode } = await processScript(code, {
147
- minify,
148
- scriptUser: user,
149
- scriptName,
150
- filePath,
151
- mangleNames,
152
- forceQuineCheats
153
- }),
154
- info = {
155
- file: `${user}/${fileName}`,
156
- users: [user],
157
- minLength: countHackmudCharacters(minifiedCode),
158
- error: void 0
159
- }
160
- allInfo.push(info)
161
- await writeFilePersistent(
162
- resolve(hackmudDirectory, user, "scripts", scriptName + ".js"),
163
- minifiedCode
164
- )
165
- onPush(info)
166
- } else usersByGlobalScriptsToPush.get(scriptName).add(user)
167
- })
168
- ))
169
- })
170
- )
171
- await (wildScriptUsers.size ?
172
- Promise.all(
173
- (sourceDirectoryDirents || (await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))).map(
174
- async dirent => {
175
- if (dirent.name.endsWith(".d.ts")) return
176
- const extension = extname(dirent.name)
177
- if (!dirent.isFile() || !supportedExtensions.includes(extension)) return
178
- const scriptName = basename(dirent.name, extension),
179
- usersToPushTo = [...wildScriptUsers, ...usersByGlobalScriptsToPush.get(scriptName)].filter(
180
- user => !scriptNamesAlreadyPushedByUser.get(user).has(scriptName)
181
- )
182
- if (!usersToPushTo.length) return
183
- const uniqueID = Math.floor(Math.random() * 2 ** 52)
184
- .toString(36)
185
- .padStart(11, "0"),
186
- filePath = resolve(sourceDirectory, dirent.name),
187
- { script: minifiedCode } = await processScript(
188
- await readFile(filePath, { encoding: "utf-8" }),
189
- { minify, scriptUser: !0, scriptName, uniqueID, filePath, mangleNames, forceQuineCheats }
190
- ),
191
- info = {
192
- file: dirent.name,
193
- users: usersToPushTo,
194
- minLength: countHackmudCharacters(minifiedCode),
195
- error: void 0
196
- }
197
- await Promise.all(
198
- usersToPushTo.map(user =>
199
- writeFilePersistent(
200
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
201
- minifiedCode
202
- .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
203
- .replace(
204
- RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
205
- `${user}.${scriptName}`
206
- )
207
- )
208
- )
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}`)
209
129
  )
210
- allInfo.push(info)
211
- onPush(info)
212
- }
130
+ )
213
131
  )
214
- )
215
- : Promise.all(
216
- [...usersByGlobalScriptsToPush].map(async ([scriptName, users]) => {
217
- let code, fileName, filePath
218
- for (const extension of supportedExtensions)
219
- try {
220
- fileName = `${scriptName}${extension}`
221
- code = await readFile((filePath = resolve(sourceDirectory, fileName)), { encoding: "utf-8" })
222
- break
223
- } catch {}
224
- if (code) {
225
- const uniqueID = Math.floor(Math.random() * 2 ** 52)
226
- .toString(36)
227
- .padStart(11, "0"),
228
- { script: minifiedCode } = await processScript(code, {
229
- minify,
230
- scriptUser: !0,
231
- scriptName,
232
- uniqueID,
233
- filePath,
234
- mangleNames,
235
- forceQuineCheats
236
- }),
237
- info = {
238
- file: fileName,
239
- users: [...users],
240
- minLength: countHackmudCharacters(minifiedCode),
241
- error: void 0
242
- }
243
- await Promise.all(
244
- [...users].map(user =>
245
- writeFilePersistent(
246
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
247
- minifiedCode
248
- .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
249
- .replace(
250
- RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
251
- `${user}.${scriptName}`
252
- )
253
- )
254
- )
255
- )
256
- allInfo.push(info)
257
- onPush(info)
258
- }
259
- })
260
- ))
132
+ allInfo.push(info)
133
+ onPush(info)
134
+ })
135
+ )
261
136
  return allInfo
262
137
  }
263
- export { push as default, push }
138
+ export { push }
package/syncMacros.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export declare const syncMacros: (hackmudPath: string) => Promise<{
1
+ export declare function syncMacros(hackmudPath: string): Promise<{
2
2
  macrosSynced: number;
3
3
  usersSynced: number;
4
4
  }>;
5
- export default syncMacros;
package/syncMacros.js CHANGED
@@ -1,17 +1,18 @@
1
- import { readdir, readFile, stat, writeFile } from "fs/promises"
1
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
2
+ import { readFile, stat, writeFile } from "fs/promises"
2
3
  import { extname, basename, resolve } from "path"
3
- const syncMacros = async hackmudPath => {
4
- const files = await readdir(hackmudPath, { withFileTypes: !0 }),
4
+ async function syncMacros(hackmudPath) {
5
+ const files = await readDirectoryWithStats(hackmudPath),
5
6
  macros = new Map(),
6
7
  users = []
7
8
  await Promise.all(
8
9
  files.map(async file => {
9
- if (file.isFile())
10
+ if (file.stats.isFile())
10
11
  switch (extname(file.name)) {
11
12
  case ".macros":
12
13
  {
13
14
  const [lines, date] = await Promise.all([
14
- readFile(resolve(hackmudPath, file.name), { encoding: "utf-8" }).then(file =>
15
+ readFile(resolve(hackmudPath, file.name), { encoding: "utf8" }).then(file =>
15
16
  file.split("\n")
16
17
  ),
17
18
  stat(resolve(hackmudPath, file.name)).then(({ mtime }) => mtime)
@@ -39,4 +40,4 @@ const syncMacros = async hackmudPath => {
39
40
  for (const user of users) writeFile(resolve(hackmudPath, user + ".macros"), macroFile)
40
41
  return { macrosSynced, usersSynced: users.length }
41
42
  }
42
- export { syncMacros as default, syncMacros }
43
+ export { syncMacros }