hackmud-script-manager 0.20.4-7caccd9 → 0.20.4-9d6d467

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  # Hackmud Script Manager
2
- Command made for [hackmud-environment](https://github.com/samualtnorman/hackmud-environment), which is a scripting environment for hackmud with minification, autocompletes / intellisense, and TypeScript support.
2
+ Command made for [Hackmud Scripting Environment](https://github.com/samualtnorman/hackmud-environment), which is a scripting environment for hackmud with minification, autocompletes / intellisense, and TypeScript support.
3
3
 
4
4
  [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/R6R0XN5CX)
5
5
 
package/bin/hsm.js CHANGED
@@ -12,7 +12,7 @@ import { pull } from "../pull.js"
12
12
  import { syncMacros } from "../syncMacros.js"
13
13
  import "@samual/lib/readDirectoryWithStats"
14
14
  import "@samual/lib/copyFilePersistent"
15
- const version = "0.20.4-7caccd9",
15
+ const version = "0.20.4-9d6d467",
16
16
  options = new Map(),
17
17
  commands = [],
18
18
  userColours = new Cache(user => {
@@ -119,16 +119,25 @@ switch (commands[0]) {
119
119
  logHelp()
120
120
  break
121
121
  }
122
- const { push } = await pushModule
123
- ;(
124
- await push(sourcePath, hackmudPath, {
122
+ const { push, MissingSourceFolderError, MissingHackmudFolderError, NoUsersError } = await pushModule,
123
+ infos = await push(sourcePath, hackmudPath, {
125
124
  scripts,
126
125
  onPush: info => logInfo(info, hackmudPath),
127
126
  minify: shouldMinify,
128
127
  mangleNames: shouldMangleNames,
129
128
  forceQuineCheats: shouldforceQuineCheats
130
129
  })
131
- ).length || logError("Could not find any scripts to push")
130
+ if (infos instanceof Error) {
131
+ logError(infos.message)
132
+ if (infos instanceof MissingSourceFolderError || infos instanceof NoUsersError) {
133
+ console.log()
134
+ logHelp()
135
+ } else
136
+ infos instanceof MissingHackmudFolderError &&
137
+ log(
138
+ `If this is not where your hackmud folder is, you can specify it with the\n${colourN("--hackmud-path")}=${colourB("<path>")} option or ${colourN("HSM_HACKMUD_PATH")} environment variable`
139
+ )
140
+ } else infos.length || logError("Could not find any scripts to push")
132
141
  }
133
142
  break
134
143
  case "dev":
@@ -245,7 +254,7 @@ switch (commands[0]) {
245
254
  typeDeclaration = await generateTypeDeclaration(sourcePath, getHackmudPath())
246
255
  let typeDeclarationPath = resolve(outputPath)
247
256
  await writeFile(typeDeclarationPath, typeDeclaration).catch(error => {
248
- assert(error instanceof Error, "src/bin/hsm.ts:327:35")
257
+ assert(error instanceof Error, "src/bin/hsm.ts:340:35")
249
258
  if ("EISDIR" != error.code) throw error
250
259
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
251
260
  return writeFile(typeDeclarationPath, typeDeclaration)
package/env.d.ts CHANGED
@@ -1,18 +1,14 @@
1
- type Replace<T, R> = Omit<T, Extract<keyof R, keyof T>> & R
1
+ type Replace<A, B> = Omit<A, keyof B> & B
2
2
  type ScriptSuccess<T = object> = { ok: true } & T
3
3
  type ScriptFailure = { ok: false, msg?: string }
4
4
  type ScriptResponse<T = object> = ScriptSuccess<T> | ScriptFailure
5
5
  type ErrorScripts = Record<string, () => ScriptFailure>
6
6
 
7
- type AllOptional<T> = {
8
- [K in keyof T]-?: {} extends Pick<T, K> ? true : false
9
- }[keyof T]
7
+ type AllOptional<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? true : false }[keyof T]
10
8
 
11
9
  type Scriptor<Args = unknown, Ret = unknown> = {
12
- name: string,
13
- call: AllOptional<Args> extends true
14
- ? (args?: Args) => Ret
15
- : (args: Args) => Ret
10
+ name: string
11
+ call: AllOptional<Args> extends true ? (args?: Args) => Ret : (args: Args) => Ret
16
12
  }
17
13
 
18
14
  type Subscripts = Record<string, Record<string, (...args: any) => any>> & {
@@ -41,7 +37,7 @@ type UpgradeRarityString = "`0noob`" | "`1kiddie`" | "`2h4x0r`" | "`3h4rdc0r3`"
41
37
  type UpgradeRarityNumber = 0 | 1 | 2 | 3 | 4 | 5;
42
38
  type UpgradeRarity = UpgradeRarityString | UpgradeRarityNumber;
43
39
 
44
- type UpgradeCore = {
40
+ type UpgradeBase = {
45
41
  name: string
46
42
  type: "lock" | "script_space" | "chat" | "script" | "tool" | "bot_brain" | "glam"
47
43
  up_class?: -1 | 0 | 1 | 2 | 3
@@ -53,9 +49,9 @@ type UpgradeCore = {
53
49
  description: string
54
50
  }
55
51
 
56
- type Upgrade = UpgradeCore & Record<string, null | boolean | number | string>
52
+ type Upgrade = UpgradeBase & Record<string, null | boolean | number | string>
57
53
 
58
- type CLIUpgrade = Omit<UpgradeCore, `rarity`> & {
54
+ type CliUpgrade = Omit<UpgradeBase, `rarity`> & {
59
55
  [x: string]: null | boolean | number | string
60
56
  rarity: UpgradeRarityString
61
57
  }
@@ -155,7 +151,7 @@ type Fullsec = Subscripts & PlayerFullsec & {
155
151
  market: {
156
152
  /** **FULLSEC** */ browse: {
157
153
  (args:
158
- Partial<{ seller: string, listed_before: number, listed_after: number, cost: number | string } & Omit<CLIUpgrade, "rarity">>
154
+ Partial<{ seller: string, listed_before: number, listed_after: number, cost: number | string } & Omit<CliUpgrade, "rarity">>
159
155
  ): { i: string, name: string, rarity: Upgrade["rarity"], cost: number }[] | ScriptFailure
160
156
 
161
157
  <I extends string>(args: { i: I }): {
@@ -357,7 +353,7 @@ type Fullsec = Subscripts & PlayerFullsec & {
357
353
  * const arr = [ 1, 2, 2, 3, 2 ]
358
354
  *
359
355
  * $D(uniq(arr)) // [ 1, 2, 3, 2 ] */
360
- uniq: (array: T[]) => T[]
356
+ uniq: <T>(array: T[]) => T[]
361
357
 
362
358
  /** Sorts an array of numbers or number-coercible strings in descending order. */
363
359
  u_sort_num_arr_desc: <T>(array: T[]) => T[]
@@ -424,17 +420,17 @@ type Fullsec = Subscripts & PlayerFullsec & {
424
420
  upgrades_of_owner: {
425
421
  <F extends Partial<Upgrade & { loaded: boolean }> = object>(args?: { filter?: F, full?: false }): (
426
422
  Omit<
427
- Pick<UpgradeCore, "tier" | "rarity" | "name" | "type" | "i" | "loaded">,
423
+ Pick<UpgradeBase, "tier" | "rarity" | "name" | "type" | "i" | "loaded">,
428
424
  keyof F
429
425
  > & Pick<F, "tier" | "rarity" | "name" | "type" | "i" | "loaded">
430
426
  )[] | ScriptFailure
431
427
 
432
428
  <F extends Partial<Upgrade & { loaded: boolean }> = object>(args: { filter?: F, full: true }): (
433
- Omit<UpgradeCore, keyof F> & F & Record<string, null | boolean | number | string>
429
+ Omit<UpgradeBase, keyof F> & F & Record<string, null | boolean | number | string>
434
430
  )[] | ScriptFailure
435
431
 
436
432
  <I extends number>(args: { i: I }): (
437
- Omit<UpgradeCore, "i"> & { [x: string]: null | boolean | number | string, i: I }
433
+ Omit<UpgradeBase, "i"> & { [x: string]: null | boolean | number | string, i: I }
438
434
  ) | ScriptFailure
439
435
  }
440
436
 
@@ -511,7 +507,7 @@ type Highsec = Fullsec & PlayerHighsec & {
511
507
  /** **HIGHSEC** */
512
508
  upgrades: {
513
509
  <I extends number>(args: { i: I }): (
514
- Omit<UpgradeCore, "i"> & { [x: string]: null | boolean | number | string, i: I }
510
+ Omit<UpgradeBase, "i"> & { [x: string]: null | boolean | number | string, i: I }
515
511
  ) | ScriptFailure
516
512
 
517
513
  <F extends Partial<Upgrade & { loaded: boolean }> = object>(args?: {
@@ -519,20 +515,20 @@ type Highsec = Fullsec & PlayerHighsec & {
519
515
  is_script?: true
520
516
  full?: false
521
517
  }): (
522
- Omit<Pick<UpgradeCore, "tier" | "rarity" | "name" | "type" | "i" | "loaded">, keyof F> & F &
518
+ Omit<Pick<UpgradeBase, "tier" | "rarity" | "name" | "type" | "i" | "loaded">, keyof F> & F &
523
519
  Record<string, null | boolean | number | string>
524
520
  )[] | ScriptFailure
525
521
 
526
522
  <F extends Partial<Upgrade & { loaded: boolean }> = object>(args?:
527
523
  { filter?: F, is_script?: true, full: true }
528
- ): (Omit<UpgradeCore, keyof F> & F & Record<string, null | boolean | number | string>)[] | ScriptFailure
524
+ ): (Omit<UpgradeBase, keyof F> & F & Record<string, null | boolean | number | string>)[] | ScriptFailure
529
525
 
530
526
  (args?: { filter?: Partial<Upgrade & { loaded: boolean }>, is_script: false, full?: false }):
531
527
  { msg: string, upgrades: string[] } | ScriptFailure
532
528
 
533
529
  <F extends Partial<Upgrade & { loaded: boolean }> = object>(
534
530
  args?: { filter?: F, is_script: false, full: true }
535
- ): (Omit<UpgradeCore, keyof F | `rarity`> & F & {
531
+ ): (Omit<UpgradeBase, keyof F | `rarity`> & F & {
536
532
  [x: string]: null | boolean | number | string
537
533
  rarity: UpgradeRarityString
538
534
  })[] | ScriptFailure
@@ -766,7 +762,7 @@ type Cursor = {
766
762
  ObjectId: () => any
767
763
  }
768
764
 
769
- type CLIContext = {
765
+ type CliContext = {
770
766
  /** The name of the user who is calling the script. */ caller: string
771
767
  /** The name of this script. */ this_script: string
772
768
  /** The number of columns in the caller’s terminal. */ cols: number
@@ -774,17 +770,23 @@ type CLIContext = {
774
770
 
775
771
  /** The name of the script that directly called this script, or null if called on the command line or as a
776
772
  * scriptor. */ calling_script: null
773
+ is_scriptor?: undefined
774
+ is_brain?: undefined
777
775
  }
778
776
 
779
- type SubscriptContext = Replace<CLIContext, {
777
+ type SubscriptContext = Replace<CliContext, {
780
778
  /** The name of the script that directly called this script, or null if called on the command line or as a scriptor.
781
779
  */
782
780
  calling_script: string
783
781
  }>
784
782
 
785
- type ScriptorContext = CLIContext & { /** Whether the script is being run as a scriptor. */ is_scriptor: true }
786
- type BrainContext = CLIContext & { /** Whether the script is being run via a bot brain. */ is_brain: true }
787
- type Context = CLIContext | SubscriptContext | ScriptorContext | BrainContext
783
+ type ScriptorContext =
784
+ Replace<CliContext, { /** Whether the script is being run as a scriptor. */ is_scriptor: true }>
785
+
786
+ type BrainContext =
787
+ Replace<CliContext, { /** Whether the script is being run via a bot brain. */ is_brain: true }>
788
+
789
+ type Context = CliContext | SubscriptContext | ScriptorContext | BrainContext
788
790
 
789
791
  /** Subscript space that can call FULLSEC scripts. */ declare const $fs: Fullsec
790
792
 
@@ -827,6 +829,8 @@ declare const $0s: typeof $ns
827
829
  * } */
828
830
  declare const $s: Nullsec
829
831
 
832
+ type ObjectId = { $oid: string }
833
+
830
834
  declare const $db: {
831
835
  /** Insert a document or documents into a collection.
832
836
  * @param documents A document or array of documents to insert into the collection. */
@@ -920,6 +924,8 @@ declare const $db: {
920
924
  signature: { hash: "Undefined Conversion", keyId: "Undefined Conversion" }
921
925
  }
922
926
  }
927
+
928
+ ObjectId: () => ObjectId
923
929
  }
924
930
 
925
931
  /** Debug Log.
@@ -956,7 +962,7 @@ declare const $FMCL: undefined | true
956
962
  * @example
957
963
  * if (!$G.dbCache)
958
964
  * $G.dbCache = $db.f({ whatever: true }).first() */
959
- declare const $G: any
965
+ declare const $G: Record<string | symbol, any>
960
966
 
961
967
  /** This contains a JS timestamp (not Date) set immediately before your code begins running.
962
968
  * @example
@@ -1005,3 +1011,14 @@ declare const _FULL_SCRIPT_NAME: string
1005
1011
  *
1006
1012
  * In rare cases where it's not known at build time, it's `-1`. */
1007
1013
  declare const _SECLEVEL: -1 | 0 | 1 | 2 | 3 | 4
1014
+
1015
+ type DeepFreeze<T> = { readonly [P in keyof T]: DeepFreeze<T[P]> }
1016
+
1017
+ /** Recursively
1018
+ * [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
1019
+ * an object and its properties' objects and its properties' objects and so on.
1020
+ *
1021
+ * [Official Hackmud Wiki](https://wiki.hackmud.com/scripting/extensions/deep_freeze) */
1022
+ declare const DEEP_FREEZE: <T>(value: T) => DeepFreeze<T>
1023
+
1024
+ declare const _RUN_ID: string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.20.4-7caccd9",
3
+ "version": "0.20.4-9d6d467",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -20,7 +20,11 @@
20
20
  "homepage": "https://github.com/samualtnorman/hackmud-script-manager#readme",
21
21
  "bugs": "https://github.com/samualtnorman/hackmud-script-manager/issues",
22
22
  "license": "MIT",
23
- "author": "Samual Norman",
23
+ "author": "Samual Norman <me@samual.uk> (https://samual.uk/)",
24
+ "contributors": [
25
+ "Daniel Swann (https://github.com/danswann)",
26
+ "Longboyy"
27
+ ],
24
28
  "main": "index.js",
25
29
  "repository": {
26
30
  "type": "git",
@@ -136,7 +136,8 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
136
136
  const promises = []
137
137
  traverse(file, {
138
138
  FunctionDeclaration(path) {
139
- path.traverse({
139
+ const body = path.get("body")
140
+ body.traverse({
140
141
  Function(path) {
141
142
  "CallExpression" != path.parent.type && "callee" != path.parentKey && path.skip()
142
143
  },
@@ -152,7 +153,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
152
153
  path.replaceWith(t.identifier(`_${uniqueId}_JSON_VALUE_${jsonValues.push(o) - 1}_`))
153
154
  }
154
155
  })
155
- path.traverse({
156
+ body.traverse({
156
157
  TemplateLiteral(path) {
157
158
  if ("TaggedTemplateExpression" == path.parent.type) return
158
159
  const templateLiteral = path.node
@@ -172,7 +173,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
172
173
  },
173
174
  MemberExpression({ node: memberExpression }) {
174
175
  if (!memberExpression.computed) {
175
- assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:259:62")
176
+ assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:261:62")
176
177
  if (!(memberExpression.property.name.length < 3)) {
177
178
  memberExpression.computed = !0
178
179
  memberExpression.property = t.stringLiteral(memberExpression.property.name)
@@ -246,7 +247,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
246
247
  })
247
248
  await Promise.all(promises)
248
249
  const functionDeclaration = file.program.body[0]
249
- assert("FunctionDeclaration" == functionDeclaration.type, "src/processScript/minify.ts:364:61")
250
+ assert("FunctionDeclaration" == functionDeclaration.type, "src/processScript/minify.ts:366:61")
250
251
  if (jsonValues.length) {
251
252
  hasComment = !0
252
253
  if (1 == jsonValues.length)
@@ -363,7 +364,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
363
364
  )
364
365
  }
365
366
  if (1 == forceQuineCheats) return code
366
- assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:495:43")
367
+ assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:497:43")
367
368
  return (
368
369
  countHackmudCharacters(scriptBeforeJSONValueReplacement) <=
369
370
  countHackmudCharacters(code) + Number(hasComment)
@@ -379,7 +380,7 @@ function parseObjectExpression(node, o) {
379
380
  "Identifier" == property.key.type ||
380
381
  "NumericLiteral" == property.key.type ||
381
382
  "StringLiteral" == property.key.type,
382
- "src/processScript/minify.ts:517:4"
383
+ "src/processScript/minify.ts:519:4"
383
384
  )
384
385
  if ("ArrayExpression" == property.value.type) {
385
386
  const childArray = []
@@ -631,7 +631,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
631
631
  VariableDeclaration({ node: variableDeclaration }) {
632
632
  "const" == variableDeclaration.kind && (variableDeclaration.kind = "let")
633
633
  },
634
- ThisExpression: path => path.replaceWith(t.identifier("undefined")),
634
+ ThisExpression: path => {
635
+ path.replaceWith(t.identifier("undefined"))
636
+ },
635
637
  BigIntLiteral(path) {
636
638
  const bigIntAsNumber = Number(path.node.value)
637
639
  path.replaceWith(
@@ -661,23 +663,23 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
661
663
  }
662
664
  function processFakeSubscriptObject(fakeSubscriptObjectName) {
663
665
  for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
664
- assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:783:60")
666
+ assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:785:60")
665
667
  assert("Identifier" == referencePath.parent.property.type)
666
668
  assert(
667
669
  "MemberExpression" == referencePath.parentPath.parentPath?.node.type,
668
- "src/processScript/transform.ts:785:81"
670
+ "src/processScript/transform.ts:787:81"
669
671
  )
670
672
  assert(
671
673
  "Identifier" == referencePath.parentPath.parentPath.node.property.type,
672
- "src/processScript/transform.ts:786:83"
674
+ "src/processScript/transform.ts:788:83"
673
675
  )
674
676
  assert(
675
677
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
676
- `src/processScript/transform.ts:790:8 invalid user "${referencePath.parent.property.name}" in subscript`
678
+ `src/processScript/transform.ts:792:8 invalid user "${referencePath.parent.property.name}" in subscript`
677
679
  )
678
680
  assert(
679
681
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
680
- `src/processScript/transform.ts:795:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
682
+ `src/processScript/transform.ts:797:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
681
683
  )
682
684
  if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
683
685
  referencePath.parentPath.parentPath.replaceWith(
package/push.d.ts CHANGED
@@ -18,6 +18,14 @@ export type PushOptions = LaxPartial<{
18
18
  */
19
19
  forceQuineCheats: boolean;
20
20
  }>;
21
+ export declare class MissingSourceFolderError extends Error {
22
+ }
23
+ export declare class MissingHackmudFolderError extends Error {
24
+ }
25
+ export declare class NoUsersError extends Error {
26
+ }
27
+ export declare class NoScriptsError extends Error {
28
+ }
21
29
  /** Push scripts from a source directory to the hackmud directory.
22
30
  *
23
31
  * Pushes files directly in the source folder to all users
@@ -25,4 +33,4 @@ export type PushOptions = LaxPartial<{
25
33
  * @param hackmudPath directory created by hackmud containing user data including scripts
26
34
  * @param options {@link PushOptions details}
27
35
  * @returns array of info on pushed scripts */
28
- export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
36
+ export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;
package/push.js CHANGED
@@ -42,32 +42,54 @@ import "./processScript/preprocess.js"
42
42
  import "import-meta-resolve"
43
43
  import "./processScript/transform.js"
44
44
  import "@samual/lib/clearObject"
45
+ class MissingSourceFolderError extends Error {}
46
+ Object.defineProperty(MissingSourceFolderError.prototype, "name", { value: "MissingSourceFolderError" })
47
+ class MissingHackmudFolderError extends Error {}
48
+ Object.defineProperty(MissingHackmudFolderError.prototype, "name", { value: "MissingHackmudFolderError" })
49
+ class NoUsersError extends Error {}
50
+ Object.defineProperty(NoUsersError.prototype, "name", { value: "NoUsersError" })
51
+ class NoScriptsError extends Error {}
52
+ Object.defineProperty(NoScriptsError.prototype, "name", { value: "NoScriptsError" })
45
53
  async function push(
46
54
  sourcePath,
47
55
  hackmudPath,
48
56
  { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
49
57
  ) {
50
58
  const [sourceFolder, hackmudFolder] = await Promise.all([
51
- readDirectoryWithStats(sourcePath),
52
- readDirectoryWithStats(hackmudPath)
53
- ]),
54
- sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
59
+ readDirectoryWithStats(sourcePath).catch(error => {
60
+ if (error && "ENOENT" == error.code)
61
+ return new MissingSourceFolderError("There is no folder at " + sourcePath)
62
+ throw error
63
+ }),
64
+ readDirectoryWithStats(hackmudPath).catch(error => {
65
+ if (error && "ENOENT" == error.code)
66
+ return new MissingHackmudFolderError("There is no folder at " + hackmudPath)
67
+ throw error
68
+ })
69
+ ])
70
+ if (sourceFolder instanceof Error) return sourceFolder
71
+ if (hackmudFolder instanceof Error) return hackmudFolder
72
+ const sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
55
73
  allUsers = new Set([
56
74
  ...scripts
57
- .map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:52:65"))
75
+ .map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:82:65"))
58
76
  .filter(name => "*" != name),
59
77
  ...sourceFolderFolders.map(({ name }) => name),
60
78
  ...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
61
79
  ...hackmudFolder
62
80
  .filter(({ stats, name }) => stats.isFile() && name.endsWith(".key"))
63
81
  .map(({ name }) => name.slice(0, -4))
64
- ]),
65
- usersToScriptsToPush = new Cache(_user => new Map()),
82
+ ])
83
+ if (!allUsers.size)
84
+ return new NoUsersError(
85
+ "Could not find any users. Either provide the names of your users or log into a user in hackmud"
86
+ )
87
+ const usersToScriptsToPush = new Cache(_user => new Map()),
66
88
  scriptNamesToUsers = new Cache(_scriptName => new Set())
67
89
  for (const script of scripts) {
68
90
  const [user, scriptName] = script.split(".")
69
- assert(user, "src/push.ts:69:16")
70
- assert(scriptName, "src/push.ts:70:22")
91
+ assert(user, "src/push.ts:105:16")
92
+ assert(scriptName, "src/push.ts:106:22")
71
93
  "*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
72
94
  }
73
95
  const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
@@ -98,7 +120,7 @@ async function push(
98
120
  for (const [scriptName, users] of scriptNamesToUsers)
99
121
  for (const user of users)
100
122
  if (!usersToScriptsToPush.get(user).has(scriptName))
101
- throw Error(`Could not find script ${user}.${scriptName} to push`)
123
+ return new NoScriptsError(`Could not find script ${user}.${scriptName} to push`)
102
124
  const pathsToUsers = new Cache(_path => new Set())
103
125
  for (const [user, scriptsToPush] of usersToScriptsToPush)
104
126
  for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
@@ -135,4 +157,4 @@ async function push(
135
157
  )
136
158
  return allInfo
137
159
  }
138
- export { push }
160
+ export { MissingHackmudFolderError, MissingSourceFolderError, NoScriptsError, NoUsersError, push }