@serverkgg/bridge 0.1.1 → 0.1.2

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 (52) hide show
  1. package/package.json +1 -1
  2. package/src/bot/botPanel.test.ts +30 -0
  3. package/src/bot/botPanel.ts +9 -1
  4. package/src/cli/validate.test.ts +73 -1
  5. package/src/cli/validate.ts +35 -1
  6. package/src/context/bridgeContext.ts +6 -1
  7. package/src/core/bridgeAction.ts +2 -0
  8. package/src/core/bridgeActivity.ts +9 -0
  9. package/src/core/bridgeAvailability.ts +10 -0
  10. package/src/core/bridgeUserError.test.ts +10 -0
  11. package/src/core/bridgeUserError.ts +6 -2
  12. package/src/core/describeDownloadFailure.test.ts +58 -0
  13. package/src/core/describeDownloadFailure.ts +69 -0
  14. package/src/core/index.ts +3 -0
  15. package/src/modules/bridge.ts +8 -1
  16. package/src/modules/bridgeModule.ts +13 -1
  17. package/src/panel/bridgeDetail.ts +2 -1
  18. package/src/protocol/bridgeActivity.ts +54 -0
  19. package/src/protocol/bridgeEvents.ts +30 -0
  20. package/src/protocol/bridgeFrame.ts +10 -1
  21. package/src/protocol/index.ts +1 -0
  22. package/src/runtime/bridgeActions.ts +19 -2
  23. package/src/runtime/bridgeActivity.test.ts +318 -0
  24. package/src/runtime/bridgeActivity.ts +268 -0
  25. package/src/runtime/bridgeContext.test.ts +6 -0
  26. package/src/runtime/bridgeContext.ts +8 -1
  27. package/src/runtime/bridgeDriver.test.ts +21 -0
  28. package/src/runtime/bridgeDriver.ts +10 -7
  29. package/src/runtime/bridgeLog.ts +10 -0
  30. package/src/runtime/bridgeRefusalError.ts +13 -0
  31. package/src/runtime/bridgeRegistry.test.ts +1053 -10
  32. package/src/runtime/bridgeRegistry.ts +464 -65
  33. package/src/runtime/bridgeScopedContext.ts +55 -0
  34. package/src/runtime/bridgeServer.test.ts +404 -4
  35. package/src/runtime/bridgeServer.ts +125 -35
  36. package/src/runtime/bridgeSetupHandlers.test.ts +69 -6
  37. package/src/runtime/bridgeSetupHandlers.ts +45 -10
  38. package/src/runtime/serve.ts +45 -3
  39. package/src/steam/steamcmd.test.ts +32 -1
  40. package/src/steam/steamcmd.ts +27 -4
  41. package/src/utils/changedSettingKeys.test.ts +65 -0
  42. package/src/utils/changedSettingKeys.ts +6 -0
  43. package/src/utils/describeExecFailure.test.ts +34 -0
  44. package/src/utils/describeExecFailure.ts +9 -0
  45. package/src/utils/index.ts +3 -0
  46. package/src/utils/sameSettingValue.test.ts +35 -0
  47. package/src/utils/sameSettingValue.ts +40 -0
  48. package/src/wire/activity.test.ts +95 -0
  49. package/src/wire/activity.ts +41 -0
  50. package/src/wire/index.ts +1 -0
  51. package/src/wire/panel.test.ts +67 -1
  52. package/src/wire/panel.ts +11 -0
@@ -275,6 +275,27 @@ 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", () => {
279
+ const driver = driverWithTabs(1, 1);
280
+
281
+ driver.modules = {
282
+ ...driver.modules,
283
+ worlds: {
284
+ kind: BridgeKind.Collection,
285
+ list: async () => [],
286
+ actions: {
287
+ preview: async () => {
288
+ return;
289
+ },
290
+ },
291
+ },
292
+ };
293
+
294
+ expect(() => validateDriver(driver)).toThrow(
295
+ 'module "worlds" declares action "preview", which is reserved for reads',
296
+ );
297
+ });
298
+
278
299
  test("takes the tab and section counts the agent mirror accepts", () => {
279
300
  expect(() => validateDriver(driverWithTabs(8, 8))).not.toThrow();
280
301
  });
@@ -3,6 +3,7 @@ import {
3
3
  BRIDGE_MODULE_ID_PATTERN,
4
4
  BridgeKind,
5
5
  BridgeSetupStepKind,
6
+ isReadAction,
6
7
  type LocalizedText,
7
8
  } from "../core";
8
9
  import { GuideOpenTab } from "../guides";
@@ -801,15 +802,17 @@ export const validateDriver = (driver: BridgeDriver) => {
801
802
  countIn((module.dependsOn ?? []).length, BRIDGE_DEPENDS_ON_LIMIT, "dependencies", `module "${id}"`);
802
803
  }
803
804
 
804
- if (module.kind === BridgeKind.Actions) {
805
- for (const action of Object.keys(module.actions)) {
806
- validateModuleId(action, `module "${id}" action`);
807
- }
808
- }
809
-
810
- if (module.kind === BridgeKind.Collection || module.kind === BridgeKind.Detail) {
805
+ if (
806
+ module.kind === BridgeKind.Actions
807
+ || module.kind === BridgeKind.Collection
808
+ || module.kind === BridgeKind.Detail
809
+ ) {
811
810
  for (const action of Object.keys(module.actions ?? {})) {
812
811
  validateModuleId(action, `module "${id}" action`);
812
+
813
+ if (isReadAction(action)) {
814
+ fail(`module "${id}" declares action "${action}", which is reserved for reads — pick another id`);
815
+ }
813
816
  }
814
817
  }
815
818
  }
@@ -36,3 +36,13 @@ export const log: BridgeLeveledLogger = Object.assign(
36
36
  export const errorText = (error: unknown) => {
37
37
  return error instanceof Error ? error.message : String(error);
38
38
  };
39
+
40
+ export const errorDetail = (error: unknown) => {
41
+ const text = errorText(error);
42
+
43
+ if (!(error instanceof Error) || error.cause === undefined) {
44
+ return text;
45
+ }
46
+
47
+ return `${text} — ${errorText(error.cause)}`;
48
+ };
@@ -0,0 +1,13 @@
1
+ import type { LocalizedText } from "../core";
2
+ import { BridgeDriverError } from "./bridgeDriver";
3
+
4
+ export class BridgeRefusalError extends BridgeDriverError {
5
+ readonly text: LocalizedText | null;
6
+
7
+ constructor(message: string, text: LocalizedText | null = null) {
8
+ super(message);
9
+
10
+ this.name = "BridgeRefusalError";
11
+ this.text = text;
12
+ }
13
+ }