@masonf539/game-sdk 1.0.0 → 1.0.1

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
@@ -17,6 +17,11 @@ routing through `GameClientContext.input`. GameHub treats installed packages
17
17
  as trusted code and does not expose its private room implementation through
18
18
  these contracts.
19
19
 
20
+ Keybind defaults are validated `KeyboardEvent.code` values. Letters, numbers,
21
+ arrows, Space, Enter, Escape, punctuation, and ordinary numpad keys are
22
+ assignable; Tab, function keys, and standalone modifiers are reserved by the
23
+ platform. Games must subscribe only to action IDs declared in their manifest.
24
+
20
25
  ## Releasing
21
26
 
22
27
  The package is configured for public npm publication. From the repository
@@ -39,7 +39,10 @@ export type GameKeybind = {
39
39
  id: string;
40
40
  label: string;
41
41
  description?: string;
42
- /** KeyboardEvent.code value, so defaults follow physical key positions. */
42
+ /**
43
+ * Assignable KeyboardEvent.code value. Tab, function keys, and standalone
44
+ * modifier keys are reserved by GameHub.
45
+ */
43
46
  defaultKey: string;
44
47
  };
45
48
  export type GameDefinition = {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export type { BooleanGameSetting, GameDefinition, GameKeybind, GamePreview, GameSetting, GameSettingValue, NumberGameSetting, RangeNumberGameSetting, SelectNumberGameSetting } from "./gameDefinition.js";
2
2
  export { gameHubGameApiVersion, type EmbeddedGameClient, type GameClientDelivery, type GamePluginManifest, type GamePluginPackage, type ModuleGameClient } from "./manifest.js";
3
3
  export type { GameActionEnvelope, GameActionResult, GameAudioApi, GameClientContext, GameClientInstance, GameClientModule, GameCompletion, GameEvent, GameEventEnvelope, GameLifecycleState, GameMember, GameMemberRole, GameInputApi, GamePlatformEvent, GameServerPlugin, GameSession, GameSessionContext, GameStateEnvelope, GameViewer } from "./plugin.js";
4
- export { GamePluginRegistry, GamePluginValidationError, validateGamePluginManifest } from "./registry.js";
4
+ export { GamePluginRegistry, GamePluginValidationError, isAssignableKeyCode, validateGamePluginManifest } from "./registry.js";
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateGamePluginManifest = exports.GamePluginValidationError = exports.GamePluginRegistry = exports.gameHubGameApiVersion = void 0;
3
+ exports.validateGamePluginManifest = exports.isAssignableKeyCode = exports.GamePluginValidationError = exports.GamePluginRegistry = exports.gameHubGameApiVersion = void 0;
4
4
  var manifest_js_1 = require("./manifest.js");
5
5
  Object.defineProperty(exports, "gameHubGameApiVersion", { enumerable: true, get: function () { return manifest_js_1.gameHubGameApiVersion; } });
6
6
  var registry_js_1 = require("./registry.js");
7
7
  Object.defineProperty(exports, "GamePluginRegistry", { enumerable: true, get: function () { return registry_js_1.GamePluginRegistry; } });
8
8
  Object.defineProperty(exports, "GamePluginValidationError", { enumerable: true, get: function () { return registry_js_1.GamePluginValidationError; } });
9
+ Object.defineProperty(exports, "isAssignableKeyCode", { enumerable: true, get: function () { return registry_js_1.isAssignableKeyCode; } });
9
10
  Object.defineProperty(exports, "validateGamePluginManifest", { enumerable: true, get: function () { return registry_js_1.validateGamePluginManifest; } });
@@ -1,5 +1,6 @@
1
1
  import type { GameDefinition } from "./gameDefinition.js";
2
2
  import { type GamePluginManifest } from "./manifest.js";
3
+ export declare function isAssignableKeyCode(code: string): boolean;
3
4
  export declare class GamePluginValidationError extends Error {
4
5
  constructor(message: string);
5
6
  }
package/dist/registry.js CHANGED
@@ -1,12 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GamePluginRegistry = exports.GamePluginValidationError = void 0;
4
+ exports.isAssignableKeyCode = isAssignableKeyCode;
4
5
  exports.validateGamePluginManifest = validateGamePluginManifest;
5
6
  const manifest_js_1 = require("./manifest.js");
6
7
  const identifierPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
7
8
  const settingKeyPattern = /^[A-Za-z][A-Za-z0-9]*$/;
8
9
  const actionIdPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
9
10
  const semanticVersionPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
11
+ const assignableKeyCodes = new Set([
12
+ "Escape", "Space", "Enter",
13
+ "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
14
+ "Backquote", "Minus", "Equal", "BracketLeft", "BracketRight",
15
+ "Backslash", "Semicolon", "Quote", "Comma", "Period", "Slash",
16
+ "NumpadAdd", "NumpadSubtract", "NumpadMultiply", "NumpadDivide",
17
+ "NumpadDecimal", "NumpadEnter", "NumpadEqual", "NumpadComma"
18
+ ]);
19
+ function isAssignableKeyCode(code) {
20
+ return /^(Key[A-Z]|Digit[0-9]|Numpad[0-9])$/.test(code) ||
21
+ assignableKeyCodes.has(code);
22
+ }
10
23
  class GamePluginValidationError extends Error {
11
24
  constructor(message) {
12
25
  super(message);
@@ -118,6 +131,9 @@ function validateGamePluginManifest(manifest) {
118
131
  }
119
132
  requireNonEmpty(keybind.label, `${game.id}.${keybind.id} keybind label`);
120
133
  requireNonEmpty(keybind.defaultKey, `${game.id}.${keybind.id} default keybind`);
134
+ if (!isAssignableKeyCode(keybind.defaultKey)) {
135
+ throw new GamePluginValidationError(`${game.id}.${keybind.id} has an invalid default keybind: ${keybind.defaultKey}.`);
136
+ }
121
137
  if (defaultKeys.has(keybind.defaultKey)) {
122
138
  throw new GamePluginValidationError(`${game.id} assigns ${keybind.defaultKey} to multiple actions.`);
123
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masonf539/game-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Versioned contracts for GameHub game plugins.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",