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

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/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>;