hackmud-script-manager 0.19.1-3ef8894 → 0.19.1-49ea60d

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