@serverkgg/bridge 0.1.2 → 0.1.4

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.
Files changed (94) hide show
  1. package/package.json +3 -2
  2. package/rules/package.md +65 -0
  3. package/src/blog/articleFrontmatter.test.ts +10 -10
  4. package/src/blog/compile.test.ts +9 -9
  5. package/src/bot/botDeploy.test.ts +16 -16
  6. package/src/bot/botEnvironment.test.ts +8 -8
  7. package/src/bot/botIdentity.test.ts +12 -12
  8. package/src/bot/botPanel.test.ts +13 -13
  9. package/src/bot/botPanel.ts +4 -4
  10. package/src/bot/botState.test.ts +3 -3
  11. package/src/bot/botTerminal.test.ts +5 -5
  12. package/src/bot/botVariables.test.ts +8 -8
  13. package/src/bot/detect/botToken.test.ts +6 -6
  14. package/src/bot/detect/detect.test.ts +21 -21
  15. package/src/bot/detect/detectTable.test.ts +5 -5
  16. package/src/bot/detect/envExample.test.ts +2 -2
  17. package/src/bot/detect/envScan.test.ts +4 -4
  18. package/src/bot/detect/inferBotPlatform.test.ts +4 -4
  19. package/src/bot/detect/keys.test.ts +3 -3
  20. package/src/bot/detect/sensitiveKey.test.ts +5 -5
  21. package/src/bot/detect/serverkJson.test.ts +5 -5
  22. package/src/catalogs/curseforge.test.ts +35 -35
  23. package/src/catalogs/thunderstore.test.ts +9 -9
  24. package/src/cli/detectTable.test.ts +3 -3
  25. package/src/cli/link.test.ts +11 -11
  26. package/src/cli/main.ts +8 -0
  27. package/src/cli/rules.test.ts +198 -0
  28. package/src/cli/rules.ts +188 -0
  29. package/src/cli/validate.test.ts +179 -31
  30. package/src/cli/validate.ts +44 -0
  31. package/src/codecs/ini.test.ts +13 -13
  32. package/src/codecs/javaProperties.test.ts +11 -11
  33. package/src/codecs/sourceCfg.test.ts +14 -14
  34. package/src/codecs/xmlProperties.test.ts +10 -10
  35. package/src/core/bridgePort.test.ts +6 -6
  36. package/src/core/bridgeUserError.test.ts +4 -4
  37. package/src/core/bridgeValue.test.ts +5 -5
  38. package/src/core/describeDownloadFailure.test.ts +12 -12
  39. package/src/core/describeDownloadFailure.ts +10 -10
  40. package/src/guides/markdown.test.ts +31 -31
  41. package/src/install/installStamp.test.ts +9 -9
  42. package/src/manifest/extension.ts +36 -0
  43. package/src/manifest/index.ts +1 -0
  44. package/src/manifest/manifest.test.ts +208 -90
  45. package/src/manifest/manifest.ts +34 -0
  46. package/src/net/loopback.test.ts +10 -10
  47. package/src/presence/rosterSync.test.ts +7 -7
  48. package/src/probes/a2s.test.ts +5 -5
  49. package/src/probes/minecraftPing.test.ts +17 -17
  50. package/src/probes/raknetPing.test.ts +13 -13
  51. package/src/protocol/bridgePreview.ts +1 -0
  52. package/src/rcon/rconAccess.test.ts +20 -20
  53. package/src/rcon/rconAccess.ts +14 -14
  54. package/src/rcon/rconClient.test.ts +49 -49
  55. package/src/rcon/rconFrame.test.ts +14 -14
  56. package/src/rcon/rconIds.test.ts +4 -4
  57. package/src/rcon/rconWriter.test.ts +6 -6
  58. package/src/runtime/bridgeActivity.test.ts +15 -15
  59. package/src/runtime/bridgeBackupLease.test.ts +9 -9
  60. package/src/runtime/bridgeConfigReader.test.ts +5 -5
  61. package/src/runtime/bridgeConsoleHandler.test.ts +8 -8
  62. package/src/runtime/bridgeContext.test.ts +5 -5
  63. package/src/runtime/bridgeDriver.test.ts +94 -94
  64. package/src/runtime/bridgeEvents.test.ts +15 -15
  65. package/src/runtime/bridgeFiles.test.ts +54 -54
  66. package/src/runtime/bridgeInstall.test.ts +10 -10
  67. package/src/runtime/bridgeLiveConfig.test.ts +6 -6
  68. package/src/runtime/bridgePending.test.ts +6 -6
  69. package/src/runtime/bridgeRedaction.test.ts +16 -16
  70. package/src/runtime/bridgeRegistry.test.ts +84 -52
  71. package/src/runtime/bridgeRegistry.ts +2 -2
  72. package/src/runtime/bridgeServer.test.ts +31 -31
  73. package/src/runtime/bridgeSetup.test.ts +27 -27
  74. package/src/runtime/bridgeSetup.ts +1 -1
  75. package/src/runtime/bridgeSetupHandlers.test.ts +13 -13
  76. package/src/runtime/bridgeSignal.test.ts +7 -7
  77. package/src/runtime/bridgeSupervisor.test.ts +42 -42
  78. package/src/runtime/serve.ts +4 -4
  79. package/src/steam/avatars.test.ts +13 -13
  80. package/src/steam/steamApp.test.ts +8 -8
  81. package/src/steam/steamcmd.test.ts +17 -17
  82. package/src/steam/steamcmd.ts +4 -4
  83. package/src/steam/steamcmdNarrator.test.ts +4 -4
  84. package/src/steam/workshop.test.ts +5 -5
  85. package/src/utils/changedSettingKeys.test.ts +5 -5
  86. package/src/utils/describeExecFailure.test.ts +4 -4
  87. package/src/utils/describeExecFailure.ts +1 -1
  88. package/src/utils/sameSettingValue.test.ts +7 -7
  89. package/src/utils/token.test.ts +7 -7
  90. package/src/wine/protonCommand.test.ts +5 -5
  91. package/src/wine/wineCommand.test.ts +6 -6
  92. package/src/wine/winePrefix.test.ts +6 -6
  93. package/src/wire/activity.test.ts +8 -8
  94. package/src/wire/panel.test.ts +28 -28
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "bun:test";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { BridgeKind, BridgeSetupStepKind, PortJoin, PortProtocol } from "../core";
3
3
  import { GuideOpenTab } from "../guides";
4
4
  import type { ManifestPort, ManifestPortActivation } from "../manifest";
@@ -275,7 +275,7 @@ const driverWithTabs = (tabs: number, sections: number): BridgeDriver => ({
275
275
  });
276
276
 
277
277
  describe("panel caps", () => {
278
- test("rejects a collection row action named after a read action", () => {
278
+ it("rejects a collection row action named after a read action", () => {
279
279
  const driver = driverWithTabs(1, 1);
280
280
 
281
281
  driver.modules = {
@@ -296,23 +296,23 @@ describe("panel caps", () => {
296
296
  );
297
297
  });
298
298
 
299
- test("takes the tab and section counts the agent mirror accepts", () => {
299
+ it("takes the tab and section counts the agent mirror accepts", () => {
300
300
  expect(() => validateDriver(driverWithTabs(8, 8))).not.toThrow();
301
301
  });
302
302
 
303
- test("rejects a ninth tab the agent mirror would drop", () => {
303
+ it("rejects a ninth tab the agent mirror would drop", () => {
304
304
  expect(() => validateDriver(driverWithTabs(9, 1))).toThrow(
305
305
  "the panel declares 9 tabs — the platform takes at most 8",
306
306
  );
307
307
  });
308
308
 
309
- test("rejects a ninth section the agent mirror would drop", () => {
309
+ it("rejects a ninth section the agent mirror would drop", () => {
310
310
  expect(() => validateDriver(driverWithTabs(1, 9))).toThrow(
311
311
  'tab "tab-0" declares 9 sections — the platform takes at most 8',
312
312
  );
313
313
  });
314
314
 
315
- test("rejects a form carrying more fields than the agent mirror accepts", () => {
315
+ it("rejects a form carrying more fields than the agent mirror accepts", () => {
316
316
  const driver = driverWithTabs(1, 1);
317
317
  const [tab] = driver.panel?.tabs ?? [];
318
318
  const [section] = tab?.sections ?? [];
@@ -328,7 +328,7 @@ describe("panel caps", () => {
328
328
  expect(() => validateDriver(driver)).toThrow("declares 33 fields — the platform takes at most 32");
329
329
  });
330
330
 
331
- test("rejects a table carrying more columns than the agent mirror accepts", () => {
331
+ it("rejects a table carrying more columns than the agent mirror accepts", () => {
332
332
  const driver = driverWithTabs(1, 1);
333
333
  const [tab] = driver.panel?.tabs ?? [];
334
334
 
@@ -360,7 +360,7 @@ describe("panel caps", () => {
360
360
  expect(() => validateDriver(driver)).toThrow("declares 9 columns — the platform takes at most 8");
361
361
  });
362
362
 
363
- test("rejects a label longer than the agent mirror accepts", () => {
363
+ it("rejects a label longer than the agent mirror accepts", () => {
364
364
  const driver = driverWithTabs(1, 1);
365
365
  const [tab] = driver.panel?.tabs ?? [];
366
366
 
@@ -377,7 +377,7 @@ describe("panel caps", () => {
377
377
  });
378
378
 
379
379
  describe("actions sections", () => {
380
- test("accepts an action the module implements", () => {
380
+ it("accepts an action the module implements", () => {
381
381
  expect(() =>
382
382
  validateDriver(
383
383
  driverWithActions([
@@ -393,7 +393,7 @@ describe("actions sections", () => {
393
393
  ).not.toThrow();
394
394
  });
395
395
 
396
- test("rejects an action the module does not implement", () => {
396
+ it("rejects an action the module does not implement", () => {
397
397
  expect(() =>
398
398
  validateDriver(
399
399
  driverWithActions([
@@ -406,11 +406,11 @@ describe("actions sections", () => {
406
406
  ).toThrow('declares action "shout", which module "broadcast" does not implement');
407
407
  });
408
408
 
409
- test("rejects a section with no actions", () => {
409
+ it("rejects a section with no actions", () => {
410
410
  expect(() => validateDriver(driverWithActions([]))).toThrow("declares no actions");
411
411
  });
412
412
 
413
- test("rejects an action carrying more fields than one prompt fits", () => {
413
+ it("rejects an action carrying more fields than one prompt fits", () => {
414
414
  expect(() =>
415
415
  validateDriver(
416
416
  driverWithActions([
@@ -431,7 +431,7 @@ describe("actions sections", () => {
431
431
  ).toThrow('action "say" declares 6 fields — at most 5 fit one prompt');
432
432
  });
433
433
 
434
- test("rejects a section pointing at a module that is not an actions module", () => {
434
+ it("rejects a section pointing at a module that is not an actions module", () => {
435
435
  const driver = driverWithActions([
436
436
  {
437
437
  id: "say",
@@ -449,7 +449,7 @@ describe("actions sections", () => {
449
449
  expect(() => validateDriver(driver)).toThrow('references "broadcast", which is not an actions module');
450
450
  });
451
451
 
452
- test("checks the fields a row action declares", () => {
452
+ it("checks the fields a row action declares", () => {
453
453
  const driver = driverWithActions([
454
454
  {
455
455
  id: "say",
@@ -510,7 +510,7 @@ describe("actions sections", () => {
510
510
  });
511
511
 
512
512
  describe("visibleWhen", () => {
513
- test("accepts a rule that matches on values", () => {
513
+ it("accepts a rule that matches on values", () => {
514
514
  expect(() =>
515
515
  validateDriver(
516
516
  driverWith({
@@ -523,7 +523,7 @@ describe("visibleWhen", () => {
523
523
  ).not.toThrow();
524
524
  });
525
525
 
526
- test("accepts a rule that matches on emptiness", () => {
526
+ it("accepts a rule that matches on emptiness", () => {
527
527
  expect(() =>
528
528
  validateDriver(
529
529
  driverWith({
@@ -543,7 +543,7 @@ describe("visibleWhen", () => {
543
543
  ).not.toThrow();
544
544
  });
545
545
 
546
- test("accepts a rule that narrows values inside a presence check", () => {
546
+ it("accepts a rule that narrows values inside a presence check", () => {
547
547
  expect(() =>
548
548
  validateDriver(
549
549
  driverWith({
@@ -557,7 +557,7 @@ describe("visibleWhen", () => {
557
557
  ).not.toThrow();
558
558
  });
559
559
 
560
- test("rejects a rule that declares neither values nor empty", () => {
560
+ it("rejects a rule that declares neither values nor empty", () => {
561
561
  expect(() =>
562
562
  validateDriver(
563
563
  driverWith({
@@ -567,7 +567,7 @@ describe("visibleWhen", () => {
567
567
  ).toThrow('is visible when "MODPACK" matches nothing');
568
568
  });
569
569
 
570
- test("rejects an empty values list", () => {
570
+ it("rejects an empty values list", () => {
571
571
  expect(() =>
572
572
  validateDriver(
573
573
  driverWith({
@@ -578,7 +578,7 @@ describe("visibleWhen", () => {
578
578
  ).toThrow('is visible when "MODPACK" matches nothing');
579
579
  });
580
580
 
581
- test("checks a field rule as well as a section rule", () => {
581
+ it("checks a field rule as well as a section rule", () => {
582
582
  const driver = driverWith({
583
583
  variable: "MODPACK",
584
584
  empty: true,
@@ -605,11 +605,11 @@ describe("visibleWhen", () => {
605
605
  });
606
606
 
607
607
  describe("form preview", () => {
608
- test("accepts a variables form pointing at a preview module", () => {
608
+ it("accepts a variables form pointing at a preview module", () => {
609
609
  expect(() => validateDriver(driverWithPreview())).not.toThrow();
610
610
  });
611
611
 
612
- test("rejects a preview ref to a module that is not a preview module", () => {
612
+ it("rejects a preview ref to a module that is not a preview module", () => {
613
613
  const driver = driverWithPreview();
614
614
 
615
615
  driver.modules = {
@@ -622,7 +622,7 @@ describe("form preview", () => {
622
622
  expect(() => validateDriver(driver)).toThrow('references "transition", which is not a preview module');
623
623
  });
624
624
 
625
- test("rejects a preview on a form that writes settings", () => {
625
+ it("rejects a preview on a form that writes settings", () => {
626
626
  const driver = driverWithPreview();
627
627
  const section = formSectionOf(driver);
628
628
 
@@ -645,7 +645,7 @@ describe("form preview", () => {
645
645
  });
646
646
 
647
647
  describe("validatePortActivation", () => {
648
- test("accepts a variable a variables form or a catalog section declares", () => {
648
+ it("accepts a variable a variables form or a catalog section declares", () => {
649
649
  expect(() =>
650
650
  validatePortActivation(
651
651
  [
@@ -667,7 +667,7 @@ describe("validatePortActivation", () => {
667
667
  ).not.toThrow();
668
668
  });
669
669
 
670
- test("rejects a variable nothing in the panel declares", () => {
670
+ it("rejects a variable nothing in the panel declares", () => {
671
671
  expect(() =>
672
672
  validatePortActivation(
673
673
  [
@@ -804,11 +804,11 @@ const clearingFormOf = (driver: BridgeDriver) => {
804
804
  };
805
805
 
806
806
  describe("detail sections", () => {
807
- test("accepts a detail section on a detail module", () => {
807
+ it("accepts a detail section on a detail module", () => {
808
808
  expect(() => validateDriver(withNoop(driverWithDetail()))).not.toThrow();
809
809
  });
810
810
 
811
- test("rejects a section pointing at a module that is not a detail module", () => {
811
+ it("rejects a section pointing at a module that is not a detail module", () => {
812
812
  const driver = withNoop(driverWithDetail());
813
813
 
814
814
  driver.modules = {
@@ -822,7 +822,7 @@ describe("detail sections", () => {
822
822
  expect(() => validateDriver(driver)).toThrow('references "modpackStatus", which is not a detail module');
823
823
  });
824
824
 
825
- test("rejects an action the module does not implement", () => {
825
+ it("rejects an action the module does not implement", () => {
826
826
  const driver = withNoop(driverWithDetail());
827
827
 
828
828
  detailSectionOf(driver).actions = [
@@ -837,7 +837,7 @@ describe("detail sections", () => {
837
837
  );
838
838
  });
839
839
 
840
- test("rejects a download action, since a detail has no rows to serve", () => {
840
+ it("rejects a download action, since a detail has no rows to serve", () => {
841
841
  const driver = withNoop(driverWithDetail());
842
842
 
843
843
  detailSectionOf(driver).actions = [
@@ -851,7 +851,7 @@ describe("detail sections", () => {
851
851
  expect(() => validateDriver(driver)).toThrow('declares action "update" as a download');
852
852
  });
853
853
 
854
- test("rejects a related tab the panel does not declare", () => {
854
+ it("rejects a related tab the panel does not declare", () => {
855
855
  const driver = withNoop(driverWithDetail());
856
856
 
857
857
  detailSectionOf(driver).related = {
@@ -862,7 +862,7 @@ describe("detail sections", () => {
862
862
  expect(() => validateDriver(driver)).toThrow('relates to tab "worlds", which the panel does not declare');
863
863
  });
864
864
 
865
- test("counts a detail variable as declared for port activation", () => {
865
+ it("counts a detail variable as declared for port activation", () => {
866
866
  expect(() =>
867
867
  validatePortActivation(
868
868
  [
@@ -880,11 +880,11 @@ describe("detail sections", () => {
880
880
  });
881
881
 
882
882
  describe("form clears", () => {
883
- test("accepts a clear of a variable a detail section declares", () => {
883
+ it("accepts a clear of a variable a detail section declares", () => {
884
884
  expect(() => validateDriver(withNoop(driverWithDetail()))).not.toThrow();
885
885
  });
886
886
 
887
- test("rejects a clear of a variable nothing declares", () => {
887
+ it("rejects a clear of a variable nothing declares", () => {
888
888
  const driver = withNoop(driverWithDetail());
889
889
 
890
890
  clearingFormOf(driver).clears = [
@@ -899,7 +899,7 @@ describe("form clears", () => {
899
899
  );
900
900
  });
901
901
 
902
- test("rejects a clear of one of the form's own fields", () => {
902
+ it("rejects a clear of one of the form's own fields", () => {
903
903
  const driver = withNoop(driverWithDetail());
904
904
 
905
905
  clearingFormOf(driver).clears = [
@@ -912,7 +912,7 @@ describe("form clears", () => {
912
912
  expect(() => validateDriver(driver)).toThrow('clears "MC_VERSION", which is one of its own fields');
913
913
  });
914
914
 
915
- test("rejects clears on a form that writes settings", () => {
915
+ it("rejects clears on a form that writes settings", () => {
916
916
  const driver = withNoop(driverWithDetail());
917
917
  const form = clearingFormOf(driver);
918
918
 
@@ -990,16 +990,16 @@ describe("table uploads", () => {
990
990
  mode,
991
991
  });
992
992
 
993
- test("accepts an upload that declares no mode", () => {
993
+ it("accepts an upload that declares no mode", () => {
994
994
  expect(() => validateDriver(driverWithUpload(upload()))).not.toThrow();
995
995
  });
996
996
 
997
- test("accepts both declared upload modes", () => {
997
+ it("accepts both declared upload modes", () => {
998
998
  expect(() => validateDriver(driverWithUpload(upload(BridgeUploadMode.Archive)))).not.toThrow();
999
999
  expect(() => validateDriver(driverWithUpload(upload(BridgeUploadMode.File)))).not.toThrow();
1000
1000
  });
1001
1001
 
1002
- test("rejects an upload mode the platform does not know", () => {
1002
+ it("rejects an upload mode the platform does not know", () => {
1003
1003
  const section = upload("stream" as BridgeUploadMode);
1004
1004
 
1005
1005
  expect(() => validateDriver(driverWithUpload(section))).toThrow('declares an unknown upload mode "stream"');
@@ -1036,7 +1036,7 @@ describe("the pending module", () => {
1036
1036
  ...overrides,
1037
1037
  });
1038
1038
 
1039
- test("accepts a driver that declares no pending module", () => {
1039
+ it("accepts a driver that declares no pending module", () => {
1040
1040
  expect(() =>
1041
1041
  validateDriver({
1042
1042
  install: {
@@ -1055,11 +1055,11 @@ describe("the pending module", () => {
1055
1055
  ).not.toThrow();
1056
1056
  });
1057
1057
 
1058
- test("accepts a pending module declaring a staging path and one extension", () => {
1058
+ it("accepts a pending module declaring a staging path and one extension", () => {
1059
1059
  expect(() => validateDriver(driverWithPending(pendingWith({})))).not.toThrow();
1060
1060
  });
1061
1061
 
1062
- test("rejects a pending module carrying another kind", () => {
1062
+ it("rejects a pending module carrying another kind", () => {
1063
1063
  const pending = pendingWith({
1064
1064
  kind: BridgeKind.Collection as BridgeKind.Pending,
1065
1065
  });
@@ -1069,7 +1069,7 @@ describe("the pending module", () => {
1069
1069
  );
1070
1070
  });
1071
1071
 
1072
- test("rejects a pending module with no staging path", () => {
1072
+ it("rejects a pending module with no staging path", () => {
1073
1073
  expect(() =>
1074
1074
  validateDriver(
1075
1075
  driverWithPending(
@@ -1081,7 +1081,7 @@ describe("the pending module", () => {
1081
1081
  ).toThrow("the pending module declares no staging path");
1082
1082
  });
1083
1083
 
1084
- test("rejects a staging path longer than the platform takes", () => {
1084
+ it("rejects a staging path longer than the platform takes", () => {
1085
1085
  expect(() =>
1086
1086
  validateDriver(
1087
1087
  driverWithPending(
@@ -1093,7 +1093,7 @@ describe("the pending module", () => {
1093
1093
  ).toThrow("the pending module staging path is 129 characters — the platform takes at most 128");
1094
1094
  });
1095
1095
 
1096
- test("rejects a pending module declaring no extensions", () => {
1096
+ it("rejects a pending module declaring no extensions", () => {
1097
1097
  expect(() =>
1098
1098
  validateDriver(
1099
1099
  driverWithPending(
@@ -1105,7 +1105,7 @@ describe("the pending module", () => {
1105
1105
  ).toThrow("the pending module declares no extensions");
1106
1106
  });
1107
1107
 
1108
- test("rejects more extensions than the platform takes", () => {
1108
+ it("rejects more extensions than the platform takes", () => {
1109
1109
  expect(() =>
1110
1110
  validateDriver(
1111
1111
  driverWithPending(
@@ -1119,7 +1119,7 @@ describe("the pending module", () => {
1119
1119
  ).toThrow("the pending module declares 9 extensions — the platform takes at most 8");
1120
1120
  });
1121
1121
 
1122
- test("rejects an extension longer than the platform takes", () => {
1122
+ it("rejects an extension longer than the platform takes", () => {
1123
1123
  expect(() =>
1124
1124
  validateDriver(
1125
1125
  driverWithPending(
@@ -1133,7 +1133,7 @@ describe("the pending module", () => {
1133
1133
  ).toThrow('the pending module extension "xxxxxxxxxxxxxxxxx" is 17 characters — the platform takes at most 16');
1134
1134
  });
1135
1135
 
1136
- test("reserves the pending module id for the singleton", () => {
1136
+ it("reserves the pending module id for the singleton", () => {
1137
1137
  expect(() =>
1138
1138
  validateDriver({
1139
1139
  install: {
@@ -1245,7 +1245,7 @@ const driverWithFields = (fields: BridgeField[]): BridgeDriver => ({
1245
1245
  });
1246
1246
 
1247
1247
  describe("the setup singleton", () => {
1248
- test("takes a driver step with both locales", () => {
1248
+ it("takes a driver step with both locales", () => {
1249
1249
  expect(() =>
1250
1250
  validateDriver(
1251
1251
  driverWithSetup(
@@ -1257,11 +1257,11 @@ describe("the setup singleton", () => {
1257
1257
  ).not.toThrow();
1258
1258
  });
1259
1259
 
1260
- test("rejects a setup that declares no steps", () => {
1260
+ it("rejects a setup that declares no steps", () => {
1261
1261
  expect(() => validateDriver(driverWithSetup(setupWith([])))).toThrow("the setup module declares no steps");
1262
1262
  });
1263
1263
 
1264
- test("rejects more steps than the platform takes", () => {
1264
+ it("rejects more steps than the platform takes", () => {
1265
1265
  expect(() =>
1266
1266
  validateDriver(
1267
1267
  driverWithSetup(
@@ -1275,7 +1275,7 @@ describe("the setup singleton", () => {
1275
1275
  ).toThrow("the setup module declares 9 steps — the platform takes at most 8");
1276
1276
  });
1277
1277
 
1278
- test("rejects a step id that is not kebab-case", () => {
1278
+ it("rejects a step id that is not kebab-case", () => {
1279
1279
  expect(() =>
1280
1280
  validateDriver(
1281
1281
  driverWithSetup(
@@ -1287,7 +1287,7 @@ describe("the setup singleton", () => {
1287
1287
  ).toThrow('the setup module step id "signIn" must be kebab-case');
1288
1288
  });
1289
1289
 
1290
- test("rejects the same step id twice", () => {
1290
+ it("rejects the same step id twice", () => {
1291
1291
  expect(() =>
1292
1292
  validateDriver(
1293
1293
  driverWithSetup(
@@ -1300,7 +1300,7 @@ describe("the setup singleton", () => {
1300
1300
  ).toThrow('the setup module declares step "sign-in" more than once');
1301
1301
  });
1302
1302
 
1303
- test("rejects a title that is missing a locale", () => {
1303
+ it("rejects a title that is missing a locale", () => {
1304
1304
  expect(() =>
1305
1305
  validateDriver(
1306
1306
  driverWithSetup(
@@ -1319,7 +1319,7 @@ describe("the setup singleton", () => {
1319
1319
  ).toThrow('the setup module step "sign-in" title needs both arabic and english text');
1320
1320
  });
1321
1321
 
1322
- test("takes a form step that names an existing form section and its own fields", () => {
1322
+ it("takes a form step that names an existing form section and its own fields", () => {
1323
1323
  expect(() =>
1324
1324
  validateDriver(
1325
1325
  driverWithSetup(
@@ -1340,7 +1340,7 @@ describe("the setup singleton", () => {
1340
1340
  ).not.toThrow();
1341
1341
  });
1342
1342
 
1343
- test("rejects a form step that names a section the panel does not declare", () => {
1343
+ it("rejects a form step that names a section the panel does not declare", () => {
1344
1344
  expect(() =>
1345
1345
  validateDriver(
1346
1346
  driverWithSetup(
@@ -1360,7 +1360,7 @@ describe("the setup singleton", () => {
1360
1360
  );
1361
1361
  });
1362
1362
 
1363
- test("rejects a form step that names a field the section does not declare", () => {
1363
+ it("rejects a form step that names a field the section does not declare", () => {
1364
1364
  expect(() =>
1365
1365
  validateDriver(
1366
1366
  driverWithSetup(
@@ -1381,7 +1381,7 @@ describe("the setup singleton", () => {
1381
1381
  ).toThrow('the setup module step "name" names field "PASSWORD", which section "server" does not declare');
1382
1382
  });
1383
1383
 
1384
- test("takes an open step that names an existing panel tab", () => {
1384
+ it("takes an open step that names an existing panel tab", () => {
1385
1385
  expect(() =>
1386
1386
  validateDriver(
1387
1387
  driverWithSetup(
@@ -1401,7 +1401,7 @@ describe("the setup singleton", () => {
1401
1401
  ).not.toThrow();
1402
1402
  });
1403
1403
 
1404
- test("rejects an open step that names a panel tab the panel does not declare", () => {
1404
+ it("rejects an open step that names a panel tab the panel does not declare", () => {
1405
1405
  expect(() =>
1406
1406
  validateDriver(
1407
1407
  driverWithSetup(
@@ -1421,7 +1421,7 @@ describe("the setup singleton", () => {
1421
1421
  ).toThrow('the setup module step "tune" opens panel tab "world", which the panel does not declare');
1422
1422
  });
1423
1423
 
1424
- test("takes an open step that leaves the panel altogether", () => {
1424
+ it("takes an open step that leaves the panel altogether", () => {
1425
1425
  expect(() =>
1426
1426
  validateDriver(
1427
1427
  driverWithSetup(
@@ -1440,7 +1440,7 @@ describe("the setup singleton", () => {
1440
1440
  ).not.toThrow();
1441
1441
  });
1442
1442
 
1443
- test("takes a form step over a secret field", () => {
1443
+ it("takes a form step over a secret field", () => {
1444
1444
  expect(() =>
1445
1445
  validateDriver(
1446
1446
  driverWithSetup(
@@ -1461,7 +1461,7 @@ describe("the setup singleton", () => {
1461
1461
  ).not.toThrow();
1462
1462
  });
1463
1463
 
1464
- test("rejects a driver step while the setup exports no submit", () => {
1464
+ it("rejects a driver step while the setup exports no submit", () => {
1465
1465
  expect(() =>
1466
1466
  validateDriver(
1467
1467
  driverWithSetup(
@@ -1473,7 +1473,7 @@ describe("the setup singleton", () => {
1473
1473
  ).toThrow("the setup module declares a driver step but exports no submit");
1474
1474
  });
1475
1475
 
1476
- test("takes a setup with no submit while every step is answered elsewhere", () => {
1476
+ it("takes a setup with no submit while every step is answered elsewhere", () => {
1477
1477
  expect(() =>
1478
1478
  validateDriver(
1479
1479
  driverWithSetup(
@@ -1492,7 +1492,7 @@ describe("the setup singleton", () => {
1492
1492
  ).not.toThrow();
1493
1493
  });
1494
1494
 
1495
- test("reserves the setup module id for the singleton", () => {
1495
+ it("reserves the setup module id for the singleton", () => {
1496
1496
  expect(() =>
1497
1497
  validateDriver({
1498
1498
  install: {
@@ -1519,7 +1519,7 @@ describe("the setup singleton", () => {
1519
1519
  });
1520
1520
 
1521
1521
  describe("field patterns", () => {
1522
- test("takes a pattern on a text field and on a secret one", () => {
1522
+ it("takes a pattern on a text field and on a secret one", () => {
1523
1523
  expect(() =>
1524
1524
  validateDriver(
1525
1525
  driverWithFields([
@@ -1527,8 +1527,8 @@ describe("field patterns", () => {
1527
1527
  key: "LICENSE_KEY",
1528
1528
  control: BridgeControl.Secret,
1529
1529
  label: text("Licence key"),
1530
- pattern: "^cfxk_\\w{1,60}_\\w{1,20}$",
1531
- patternHint: text("A licence key starts with cfxk_"),
1530
+ pattern: "^key_\\w{1,60}_\\w{1,20}$",
1531
+ patternHint: text("A licence key starts with key_"),
1532
1532
  },
1533
1533
  {
1534
1534
  key: "SERVER_NAME",
@@ -1541,7 +1541,7 @@ describe("field patterns", () => {
1541
1541
  ).not.toThrow();
1542
1542
  });
1543
1543
 
1544
- test("rejects a pattern that is not a regular expression", () => {
1544
+ it("rejects a pattern that is not a regular expression", () => {
1545
1545
  expect(() =>
1546
1546
  validateDriver(
1547
1547
  driverWithFields([
@@ -1549,14 +1549,14 @@ describe("field patterns", () => {
1549
1549
  key: "LICENSE_KEY",
1550
1550
  control: BridgeControl.Text,
1551
1551
  label: text("Licence key"),
1552
- pattern: "^cfxk_(",
1552
+ pattern: "^key_(",
1553
1553
  },
1554
1554
  ]),
1555
1555
  ),
1556
- ).toThrow('declares pattern "^cfxk_(", which is not a valid regular expression');
1556
+ ).toThrow('declares pattern "^key_(", which is not a valid regular expression');
1557
1557
  });
1558
1558
 
1559
- test("takes the FiveM licence pattern, whose repeats are all bounded", () => {
1559
+ it("takes an alternation whose repeats are all bounded", () => {
1560
1560
  expect(() =>
1561
1561
  validateDriver(
1562
1562
  driverWithFields([
@@ -1564,14 +1564,14 @@ describe("field patterns", () => {
1564
1564
  key: "LICENSE_KEY",
1565
1565
  control: BridgeControl.Secret,
1566
1566
  label: text("Licence key"),
1567
- pattern: "^(?:cfxk_\\w{1,60}_\\w{1,20}|\\w{32})$",
1567
+ pattern: "^(?:key_\\w{1,60}_\\w{1,20}|\\w{32})$",
1568
1568
  },
1569
1569
  ]),
1570
1570
  ),
1571
1571
  ).not.toThrow();
1572
1572
  });
1573
1573
 
1574
- test("rejects a pattern that repeats a group which already repeats", () => {
1574
+ it("rejects a pattern that repeats a group which already repeats", () => {
1575
1575
  expect(() =>
1576
1576
  validateDriver(
1577
1577
  driverWithFields([
@@ -1586,7 +1586,7 @@ describe("field patterns", () => {
1586
1586
  ).toThrow('declares pattern "^(a+)+$", which repeats a group that already repeats');
1587
1587
  });
1588
1588
 
1589
- test("rejects a starred group whose body repeats without a bound", () => {
1589
+ it("rejects a starred group whose body repeats without a bound", () => {
1590
1590
  expect(() =>
1591
1591
  validateDriver(
1592
1592
  driverWithFields([
@@ -1601,7 +1601,7 @@ describe("field patterns", () => {
1601
1601
  ).toThrow("repeats a group that already repeats");
1602
1602
  });
1603
1603
 
1604
- test("rejects a pattern longer than the platform takes", () => {
1604
+ it("rejects a pattern longer than the platform takes", () => {
1605
1605
  expect(() =>
1606
1606
  validateDriver(
1607
1607
  driverWithFields([
@@ -1616,7 +1616,7 @@ describe("field patterns", () => {
1616
1616
  ).toThrow("pattern is 258 characters — the platform takes at most 256");
1617
1617
  });
1618
1618
 
1619
- test("rejects a pattern hint with no pattern to explain", () => {
1619
+ it("rejects a pattern hint with no pattern to explain", () => {
1620
1620
  expect(() =>
1621
1621
  validateDriver(
1622
1622
  driverWithFields([
@@ -1624,14 +1624,14 @@ describe("field patterns", () => {
1624
1624
  key: "LICENSE_KEY",
1625
1625
  control: BridgeControl.Text,
1626
1626
  label: text("Licence key"),
1627
- patternHint: text("A licence key starts with cfxk_"),
1627
+ patternHint: text("A licence key starts with key_"),
1628
1628
  },
1629
1629
  ]),
1630
1630
  ),
1631
1631
  ).toThrow("declares a pattern hint with no pattern to explain");
1632
1632
  });
1633
1633
 
1634
- test("rejects a pattern on a control that never matches one", () => {
1634
+ it("rejects a pattern on a control that never matches one", () => {
1635
1635
  expect(() =>
1636
1636
  validateDriver(
1637
1637
  driverWithFields([
@@ -1646,7 +1646,7 @@ describe("field patterns", () => {
1646
1646
  ).toThrow('declares a pattern on a "boolean" control — only text and secret controls match one');
1647
1647
  });
1648
1648
 
1649
- test("rejects a secret control that offers options", () => {
1649
+ it("rejects a secret control that offers options", () => {
1650
1650
  expect(() =>
1651
1651
  validateDriver(
1652
1652
  driverWithFields([
@@ -1731,7 +1731,7 @@ describe("section placement", () => {
1731
1731
  return driver;
1732
1732
  };
1733
1733
 
1734
- test("accepts a table placed on the players page", () => {
1734
+ it("accepts a table placed on the players page", () => {
1735
1735
  expect(() =>
1736
1736
  validateDriver(
1737
1737
  driverWithRoster({
@@ -1741,19 +1741,19 @@ describe("section placement", () => {
1741
1741
  ).not.toThrow();
1742
1742
  });
1743
1743
 
1744
- test("rejects a form placed on the players page", () => {
1744
+ it("rejects a form placed on the players page", () => {
1745
1745
  expect(() => validateDriver(placedForm(BridgePlace.Players))).toThrow(
1746
1746
  'tab "version" section "version" places a form section on players, which that page cannot render',
1747
1747
  );
1748
1748
  });
1749
1749
 
1750
- test("rejects a form placed on the overview page", () => {
1750
+ it("rejects a form placed on the overview page", () => {
1751
1751
  expect(() => validateDriver(placedForm(BridgePlace.Overview))).toThrow(
1752
1752
  "places a form section on overview, which that page cannot render",
1753
1753
  );
1754
1754
  });
1755
1755
 
1756
- test("rejects a table placed on the overview page", () => {
1756
+ it("rejects a table placed on the overview page", () => {
1757
1757
  expect(() =>
1758
1758
  validateDriver(
1759
1759
  driverWithRoster({
@@ -1763,7 +1763,7 @@ describe("section placement", () => {
1763
1763
  ).toThrow('tab "roster" section "online" places a table section on overview, which that page cannot render');
1764
1764
  });
1765
1765
 
1766
- test("accepts an offline row action on a table", () => {
1766
+ it("accepts an offline row action on a table", () => {
1767
1767
  expect(() =>
1768
1768
  validateDriver(
1769
1769
  driverWithRoster({
@@ -1780,7 +1780,7 @@ describe("section placement", () => {
1780
1780
  ).not.toThrow();
1781
1781
  });
1782
1782
 
1783
- test("rejects an offline action on an actions section", () => {
1783
+ it("rejects an offline action on an actions section", () => {
1784
1784
  expect(() =>
1785
1785
  validateDriver(
1786
1786
  driverWithActions([
@@ -1796,7 +1796,7 @@ describe("section placement", () => {
1796
1796
  );
1797
1797
  });
1798
1798
 
1799
- test("rejects a form help that is missing a locale", () => {
1799
+ it("rejects a form help that is missing a locale", () => {
1800
1800
  const driver = driverWith(anyVisibleWhen);
1801
1801
 
1802
1802
  formSectionOf(driver).help = {
@@ -1827,7 +1827,7 @@ describe("the lifecycle module", () => {
1827
1827
  },
1828
1828
  });
1829
1829
 
1830
- test("accepts an environment resolver", () => {
1830
+ it("accepts an environment resolver", () => {
1831
1831
  expect(() =>
1832
1832
  validateDriver(
1833
1833
  lifecycleDriver({
@@ -1839,11 +1839,11 @@ describe("the lifecycle module", () => {
1839
1839
  ).not.toThrow();
1840
1840
  });
1841
1841
 
1842
- test("accepts a lifecycle that declares no environment", () => {
1842
+ it("accepts a lifecycle that declares no environment", () => {
1843
1843
  expect(() => validateDriver(lifecycleDriver({}))).not.toThrow();
1844
1844
  });
1845
1845
 
1846
- test("accepts each stop signal the bridge sends", () => {
1846
+ it("accepts each stop signal the bridge sends", () => {
1847
1847
  for (const stopSignal of Object.values(BridgeStopSignal)) {
1848
1848
  expect(() =>
1849
1849
  validateDriver(
@@ -1855,7 +1855,7 @@ describe("the lifecycle module", () => {
1855
1855
  }
1856
1856
  });
1857
1857
 
1858
- test("refuses a stop signal the bridge does not send", () => {
1858
+ it("refuses a stop signal the bridge does not send", () => {
1859
1859
  expect(() =>
1860
1860
  validateDriver(
1861
1861
  lifecycleDriver({
@@ -1865,7 +1865,7 @@ describe("the lifecycle module", () => {
1865
1865
  ).toThrow('the lifecycle module declares stop signal "SIGHUP" — the bridge sends only SIGTERM or SIGINT');
1866
1866
  });
1867
1867
 
1868
- test("accepts a ready timeout from one second to an hour", () => {
1868
+ it("accepts a ready timeout from one second to an hour", () => {
1869
1869
  for (const readyTimeoutSeconds of [
1870
1870
  1,
1871
1871
  900,
@@ -1881,7 +1881,7 @@ describe("the lifecycle module", () => {
1881
1881
  }
1882
1882
  });
1883
1883
 
1884
- test("refuses a ready timeout outside one second to an hour", () => {
1884
+ it("refuses a ready timeout outside one second to an hour", () => {
1885
1885
  for (const readyTimeoutSeconds of [
1886
1886
  0,
1887
1887
  3601,
@@ -1899,7 +1899,7 @@ describe("the lifecycle module", () => {
1899
1899
  }
1900
1900
  });
1901
1901
 
1902
- test("accepts each lifecycle subject the bridge names", () => {
1902
+ it("accepts each lifecycle subject the bridge names", () => {
1903
1903
  for (const subject of Object.values(BridgeLifecycleSubject)) {
1904
1904
  expect(() =>
1905
1905
  validateDriver(
@@ -1911,7 +1911,7 @@ describe("the lifecycle module", () => {
1911
1911
  }
1912
1912
  });
1913
1913
 
1914
- test("refuses a lifecycle subject the bridge does not name", () => {
1914
+ it("refuses a lifecycle subject the bridge does not name", () => {
1915
1915
  expect(() =>
1916
1916
  validateDriver(
1917
1917
  lifecycleDriver({
@@ -1921,7 +1921,7 @@ describe("the lifecycle module", () => {
1921
1921
  ).toThrow('the lifecycle module declares subject "server" — the bridge names only game or bot');
1922
1922
  });
1923
1923
 
1924
- test("refuses an environment that is not a function", () => {
1924
+ it("refuses an environment that is not a function", () => {
1925
1925
  expect(() =>
1926
1926
  validateDriver(
1927
1927
  lifecycleDriver({