@anweather/game-plugin-ssdk 1.17.0 → 1.19.0

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.
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BlobStoreError = exports.blobOwner = void 0;
4
4
  exports.isVersionConflict = isVersionConflict;
5
5
  exports.createBlobClient = createBlobClient;
6
+ exports.allBlobOwners = allBlobOwners;
6
7
  exports.casUpdate = casUpdate;
7
8
  exports.blobOwner = {
8
9
  save: (saveFileId) => `save:${saveFileId}`,
9
10
  player: (participantId) => `player:${participantId}`,
10
11
  world: (worldId) => `world:${worldId}`,
12
+ space: (spaceId) => `space:${spaceId}`,
11
13
  };
12
14
  class BlobStoreError extends Error {
13
15
  type;
@@ -31,7 +33,7 @@ const ERROR_TYPES = new Set([
31
33
  function createBlobClient(options) {
32
34
  const doFetch = options.fetchImpl ?? fetch;
33
35
  const timeoutMs = options.timeoutMs ?? 5000;
34
- const root = `${options.platformUrl}/internal/plugins/${encodeURIComponent(options.gameType)}/blobs`;
36
+ const root = `${options.platformUrl}/internal/plugins/${encodeURIComponent(options.gameType)}`;
35
37
  async function call(method, path, body) {
36
38
  const headers = {};
37
39
  if (options.authToken)
@@ -53,7 +55,7 @@ function createBlobClient(options) {
53
55
  throw new BlobStoreError(type, res.status, parsed);
54
56
  throw new Error(`blob store ${method} ${path}: ${res.status} ${text.slice(0, 200)}`);
55
57
  }
56
- const at = (owner, key) => key === undefined ? encodeURIComponent(owner) : `${encodeURIComponent(owner)}/${encodeURIComponent(key)}`;
58
+ const at = (owner, key) => key === undefined ? `blobs/${encodeURIComponent(owner)}` : `blobs/${encodeURIComponent(owner)}/${encodeURIComponent(key)}`;
57
59
  return {
58
60
  get: (owner, key) => call("GET", at(owner, key)),
59
61
  put: (owner, key, value, expectedVersion) => call("PUT", at(owner, key), { value, expectedVersion }),
@@ -61,8 +63,24 @@ function createBlobClient(options) {
61
63
  batchGet: async (owner, keys) => (await call("POST", `${at(owner)}/batch-get`, { keys })).items,
62
64
  batchPut: async (owner, writes) => (await call("POST", `${at(owner)}/batch-put`, { writes })).items,
63
65
  list: (owner) => call("GET", at(owner)),
66
+ listOwners: (prefix = "", page = {}) => {
67
+ const query = new URLSearchParams({ prefix });
68
+ if (page.after !== undefined)
69
+ query.set("after", page.after);
70
+ if (page.limit !== undefined)
71
+ query.set("limit", String(page.limit));
72
+ return call("GET", `blob-owners?${query}`);
73
+ },
64
74
  };
65
75
  }
76
+ async function* allBlobOwners(client, prefix = "", pageSize) {
77
+ let after;
78
+ do {
79
+ const page = await client.listOwners(prefix, { after, limit: pageSize });
80
+ yield* page.owners;
81
+ after = page.nextToken;
82
+ } while (after !== undefined);
83
+ }
66
84
  async function casUpdate(client, owner, key, change, maxAttempts = 5) {
67
85
  for (let attempt = 1;; attempt++) {
68
86
  const current = await client.get(owner, key);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_LINK_FRAME_BYTES = exports.LinkCloseCode = exports.LIVE_PATH = exports.LIVE_PROTOCOL_VERSION = exports.assertLiveConformance = exports.runLiveConformance = exports.loadRoomCheckpoint = exports.createLiveHarness = exports.attachLive = exports.isVersionConflict = exports.BlobStoreError = exports.blobOwner = exports.casUpdate = exports.createBlobClient = exports.runtimeVersion = exports.PLUGIN_PROTOCOL_VERSION = exports.assertConformance = exports.runConformance = exports.createRegistrationLoop = exports.createPluginApp = exports.servePlugin = exports.createGamePluginService = exports.mountSsdkHandler = void 0;
3
+ exports.MAX_MEMBERSHIP_AGE_MS = exports.FakeSpaceClient = exports.NotASpaceMemberError = exports.SpaceApiError = exports.isAlreadyASpace = exports.createMembershipGuard = exports.createSpaceClient = exports.MAX_LINK_FRAME_BYTES = exports.LinkCloseCode = exports.LIVE_PATH = exports.LIVE_PROTOCOL_VERSION = exports.assertLiveConformance = exports.runLiveConformance = exports.loadRoomCheckpoint = exports.createLiveHarness = exports.attachLive = exports.isVersionConflict = exports.BlobStoreError = exports.allBlobOwners = exports.blobOwner = exports.casUpdate = exports.createBlobClient = exports.runtimeVersion = exports.PLUGIN_PROTOCOL_VERSION = exports.assertConformance = exports.runConformance = exports.createRegistrationLoop = exports.createPluginApp = exports.servePlugin = exports.createGamePluginService = exports.mountSsdkHandler = void 0;
4
4
  var express_1 = require("./express");
5
5
  Object.defineProperty(exports, "mountSsdkHandler", { enumerable: true, get: function () { return express_1.mountSsdkHandler; } });
6
6
  var defaultService_1 = require("./defaultService");
@@ -20,6 +20,7 @@ var blobClient_1 = require("./blobClient");
20
20
  Object.defineProperty(exports, "createBlobClient", { enumerable: true, get: function () { return blobClient_1.createBlobClient; } });
21
21
  Object.defineProperty(exports, "casUpdate", { enumerable: true, get: function () { return blobClient_1.casUpdate; } });
22
22
  Object.defineProperty(exports, "blobOwner", { enumerable: true, get: function () { return blobClient_1.blobOwner; } });
23
+ Object.defineProperty(exports, "allBlobOwners", { enumerable: true, get: function () { return blobClient_1.allBlobOwners; } });
23
24
  Object.defineProperty(exports, "BlobStoreError", { enumerable: true, get: function () { return blobClient_1.BlobStoreError; } });
24
25
  Object.defineProperty(exports, "isVersionConflict", { enumerable: true, get: function () { return blobClient_1.isVersionConflict; } });
25
26
  var server_1 = require("./live/server");
@@ -36,3 +37,11 @@ Object.defineProperty(exports, "LIVE_PROTOCOL_VERSION", { enumerable: true, get:
36
37
  Object.defineProperty(exports, "LIVE_PATH", { enumerable: true, get: function () { return protocol_1.LIVE_PATH; } });
37
38
  Object.defineProperty(exports, "LinkCloseCode", { enumerable: true, get: function () { return protocol_1.LinkCloseCode; } });
38
39
  Object.defineProperty(exports, "MAX_LINK_FRAME_BYTES", { enumerable: true, get: function () { return protocol_1.MAX_LINK_FRAME_BYTES; } });
40
+ var spaceClient_1 = require("./spaceClient");
41
+ Object.defineProperty(exports, "createSpaceClient", { enumerable: true, get: function () { return spaceClient_1.createSpaceClient; } });
42
+ Object.defineProperty(exports, "createMembershipGuard", { enumerable: true, get: function () { return spaceClient_1.createMembershipGuard; } });
43
+ Object.defineProperty(exports, "isAlreadyASpace", { enumerable: true, get: function () { return spaceClient_1.isAlreadyASpace; } });
44
+ Object.defineProperty(exports, "SpaceApiError", { enumerable: true, get: function () { return spaceClient_1.SpaceApiError; } });
45
+ Object.defineProperty(exports, "NotASpaceMemberError", { enumerable: true, get: function () { return spaceClient_1.NotASpaceMemberError; } });
46
+ Object.defineProperty(exports, "FakeSpaceClient", { enumerable: true, get: function () { return spaceClient_1.FakeSpaceClient; } });
47
+ Object.defineProperty(exports, "MAX_MEMBERSHIP_AGE_MS", { enumerable: true, get: function () { return spaceClient_1.MAX_MEMBERSHIP_AGE_MS; } });
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FakeSpaceClient = exports.NotASpaceMemberError = exports.MAX_MEMBERSHIP_AGE_MS = exports.SpaceApiError = void 0;
4
+ exports.isAlreadyASpace = isAlreadyASpace;
5
+ exports.createSpaceClient = createSpaceClient;
6
+ exports.createMembershipGuard = createMembershipGuard;
7
+ class SpaceApiError extends Error {
8
+ type;
9
+ status;
10
+ details;
11
+ constructor(type, status, details) {
12
+ super(`${type}: ${String(details.message ?? status)}`);
13
+ this.type = type;
14
+ this.status = status;
15
+ this.details = details;
16
+ this.name = "SpaceApiError";
17
+ }
18
+ }
19
+ exports.SpaceApiError = SpaceApiError;
20
+ function isAlreadyASpace(e) {
21
+ return e instanceof SpaceApiError && e.type === "SpaceAlreadyExists";
22
+ }
23
+ const ERROR_TYPES = new Set([
24
+ "SpaceNotFound", "InvalidSpaceImport", "SpaceImportDisabled", "SpaceAlreadyExists", "InviteCodeTaken", "PluginUnauthorized",
25
+ ]);
26
+ function createSpaceClient(options) {
27
+ const doFetch = options.fetchImpl ?? fetch;
28
+ const timeoutMs = options.timeoutMs ?? 5000;
29
+ const base = `${options.platformUrl}/internal/plugins/${encodeURIComponent(options.gameType)}`;
30
+ async function call(method, path, body) {
31
+ const headers = {};
32
+ if (options.authToken)
33
+ headers["X-Plugin-Auth"] = `Bearer ${options.authToken}`;
34
+ if (body !== undefined)
35
+ headers["Content-Type"] = "application/json";
36
+ const res = await doFetch(`${base}/${path}`, {
37
+ method,
38
+ headers,
39
+ body: body === undefined ? undefined : JSON.stringify(body),
40
+ signal: AbortSignal.timeout(timeoutMs),
41
+ });
42
+ const text = await res.text();
43
+ let parsed = {};
44
+ try {
45
+ parsed = text ? JSON.parse(text) : {};
46
+ }
47
+ catch {
48
+ }
49
+ if (res.ok)
50
+ return parsed;
51
+ const type = (res.headers.get("X-Amzn-Errortype") ?? parsed.__type ?? "");
52
+ if (ERROR_TYPES.has(type))
53
+ throw new SpaceApiError(type, res.status, parsed);
54
+ throw new Error(`spaces ${method} ${path}: ${res.status} ${text.slice(0, 200)}`);
55
+ }
56
+ return {
57
+ get: async (spaceId) => {
58
+ try {
59
+ return await call("GET", `spaces/${encodeURIComponent(spaceId)}`);
60
+ }
61
+ catch (e) {
62
+ if (e instanceof SpaceApiError && e.type === "SpaceNotFound")
63
+ return null;
64
+ throw e;
65
+ }
66
+ },
67
+ import: (spaceId, body) => call("PUT", `spaces/${encodeURIComponent(spaceId)}/import`, body),
68
+ counts: () => call("GET", "space-counts"),
69
+ };
70
+ }
71
+ exports.MAX_MEMBERSHIP_AGE_MS = 15_000;
72
+ class NotASpaceMemberError extends Error {
73
+ spaceId;
74
+ playerId;
75
+ constructor(spaceId, playerId) {
76
+ super(`${playerId} is not an ACTIVE member of Space ${spaceId}`);
77
+ this.spaceId = spaceId;
78
+ this.playerId = playerId;
79
+ this.name = "NotASpaceMemberError";
80
+ }
81
+ }
82
+ exports.NotASpaceMemberError = NotASpaceMemberError;
83
+ function createMembershipGuard(client, options = {}) {
84
+ const maxAgeMs = Math.min(options.maxAgeMs ?? exports.MAX_MEMBERSHIP_AGE_MS, exports.MAX_MEMBERSHIP_AGE_MS);
85
+ const now = options.now ?? Date.now;
86
+ const cache = new Map();
87
+ function space(spaceId) {
88
+ const t = now();
89
+ const cached = cache.get(spaceId);
90
+ if (cached && t - cached.at < maxAgeMs)
91
+ return cached.read;
92
+ for (const [id, entry] of cache)
93
+ if (t - entry.at >= maxAgeMs)
94
+ cache.delete(id);
95
+ const read = client.get(spaceId);
96
+ cache.set(spaceId, { at: t, read });
97
+ const forget = () => {
98
+ if (cache.get(spaceId)?.read === read)
99
+ cache.delete(spaceId);
100
+ };
101
+ read.then((s) => { if (s === null)
102
+ forget(); }, forget);
103
+ return read;
104
+ }
105
+ const isMember = (s, playerId) => s !== null && s.members.some((m) => m.playerId === playerId && m.status === "ACTIVE");
106
+ return {
107
+ space,
108
+ isActiveMember: async (spaceId, playerId) => isMember(await space(spaceId), playerId),
109
+ assertActiveMember: async (spaceId, playerId) => {
110
+ const s = await space(spaceId);
111
+ if (!isMember(s, playerId))
112
+ throw new NotASpaceMemberError(spaceId, playerId);
113
+ return s;
114
+ },
115
+ invalidate: (spaceId) => (spaceId === undefined ? cache.clear() : void cache.delete(spaceId)),
116
+ };
117
+ }
118
+ class FakeSpaceClient {
119
+ options;
120
+ spaces = new Map();
121
+ calls = [];
122
+ names = new Map();
123
+ importEnabled = true;
124
+ constructor(options = {}) {
125
+ this.options = options;
126
+ }
127
+ add(space) {
128
+ const at = new Date(0).toISOString();
129
+ this.spaces.set(space.id, {
130
+ space: { id: space.id, name: space.name ?? "Space", ownerId: space.ownerId, settings: space.settings ?? {}, archived: false, revision: 1 },
131
+ inviteCode: space.inviteCode ? normalizeCode(space.inviteCode) : null,
132
+ members: new Map([[space.ownerId, { playerId: space.ownerId, role: "OWNER", status: "ACTIVE", joinedAt: at, statusAt: at }]]),
133
+ });
134
+ }
135
+ setStatus(spaceId, playerId, status) {
136
+ const s = this.spaces.get(spaceId);
137
+ if (!s)
138
+ throw new Error(`no Space ${spaceId}`);
139
+ const at = new Date().toISOString();
140
+ const current = s.members.get(playerId);
141
+ s.members.set(playerId, current ? { ...current, status, statusAt: at } : { playerId, role: "MEMBER", status, joinedAt: at, statusAt: at });
142
+ s.space.revision++;
143
+ s.imported = undefined;
144
+ }
145
+ archive(spaceId) {
146
+ const s = this.spaces.get(spaceId);
147
+ if (!s)
148
+ throw new Error(`no Space ${spaceId}`);
149
+ s.space.archived = true;
150
+ s.space.revision++;
151
+ s.imported = undefined;
152
+ }
153
+ async get(spaceId) {
154
+ this.calls.push(`get ${spaceId}`);
155
+ const s = this.spaces.get(spaceId);
156
+ return s ? this.view(s) : null;
157
+ }
158
+ async import(spaceId, body) {
159
+ this.calls.push(`import ${spaceId}`);
160
+ const refuse = (type, status, details = {}) => {
161
+ throw new SpaceApiError(type, status, { message: type, ...details });
162
+ };
163
+ if (!this.importEnabled)
164
+ refuse("SpaceImportDisabled", 403);
165
+ const owners = body.members.filter((m) => m.role === "OWNER");
166
+ if (owners.length !== 1 || owners[0].playerId !== body.ownerId || owners[0].status !== "ACTIVE") {
167
+ refuse("InvalidSpaceImport", 400, { message: "exactly one ACTIVE OWNER, who is ownerId" });
168
+ }
169
+ const code = body.inviteCode ? normalizeCode(body.inviteCode) : null;
170
+ const key = JSON.stringify({ ...body, inviteCode: code, settings: body.settings ?? {} });
171
+ const existing = this.spaces.get(spaceId);
172
+ if (existing) {
173
+ if (existing.imported === key)
174
+ return { created: false, space: this.view(existing) };
175
+ refuse("SpaceAlreadyExists", 409);
176
+ }
177
+ if (this.options.players) {
178
+ const known = new Set(this.options.players);
179
+ const unknown = [...new Set([body.ownerId, ...body.members.map((m) => m.playerId)])].filter((p) => !known.has(p));
180
+ if (unknown.length > 0)
181
+ refuse("InvalidSpaceImport", 400, { unknownPlayerIds: unknown });
182
+ }
183
+ if (code && [...this.spaces.values()].some((s) => s.inviteCode === code))
184
+ refuse("InviteCodeTaken", 409);
185
+ const stored = {
186
+ space: { id: spaceId, name: body.name.trim(), ownerId: body.ownerId, settings: body.settings ?? {}, archived: false, revision: 1 },
187
+ inviteCode: code,
188
+ members: new Map(body.members.map((m) => [m.playerId, { ...m }])),
189
+ imported: key,
190
+ };
191
+ this.spaces.set(spaceId, stored);
192
+ return { created: true, space: this.view(stored) };
193
+ }
194
+ async counts() {
195
+ this.calls.push("counts");
196
+ const all = [...this.spaces.values()];
197
+ return {
198
+ spaces: all.length,
199
+ inviteCodes: all.filter((s) => s.inviteCode !== null).length,
200
+ activeMembers: all.reduce((n, s) => n + [...s.members.values()].filter((m) => m.status === "ACTIVE").length, 0),
201
+ };
202
+ }
203
+ view(s) {
204
+ const members = [...s.members.values()]
205
+ .filter((m) => m.status === "ACTIVE")
206
+ .sort((a, b) => (a.role === b.role ? a.joinedAt.localeCompare(b.joinedAt) : a.role === "OWNER" ? -1 : 1))
207
+ .map((m) => ({ playerId: m.playerId, displayName: this.names.get(m.playerId), role: m.role, status: "ACTIVE" }));
208
+ return { ...s.space, settings: { ...s.space.settings }, members };
209
+ }
210
+ }
211
+ exports.FakeSpaceClient = FakeSpaceClient;
212
+ function normalizeCode(code) {
213
+ return code.toUpperCase().replace(/[\s\-_.]/g, "");
214
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ValidateMoveInput = exports.MoveValidation = exports.SelectBotMoveOutput = exports.SelectBotMoveInput = exports.IsOutOfTurnMoveOutput = exports.IsOutOfTurnMoveInput = exports.IsConfigMoveOutput = exports.IsConfigMoveInput = exports.InitializeGameInput = exports.HealthOutput = exports.GetSaveFileEditorStateOutput = exports.GetSaveFileEditorStateInput = exports.GetPlayerViewOutput = exports.GetPlayerViewInput = exports.GameTypeMetadata = exports.GameStatusOutput = exports.PluginStateOnlyInput = exports.GameResultOutput = exports.Outcome = exports.DescribeSaveFileOutput = exports.DescribeSaveFileInput = exports.BotSkillLevelEntry = exports.AssignParticipantsOutput = exports.AssignParticipantsInput = exports.SaveFileEditRejectedError = exports.ApplySaveFileEditOutput = exports.ApplySaveFileEditInput = exports.PluginStateUpdate = exports.InvalidMoveError = exports.ApplyMoveInput = exports.Move = void 0;
3
+ exports.ValidateMoveInput = exports.MoveValidation = exports.SelectBotMoveOutput = exports.SelectBotMoveInput = exports.IsOutOfTurnMoveOutput = exports.IsOutOfTurnMoveInput = exports.IsConfigMoveOutput = exports.IsConfigMoveInput = exports.InitializeGameInput = exports.HealthOutput = exports.GetSaveFileEditorStateOutput = exports.GetSaveFileEditorStateInput = exports.GetPlayerViewOutput = exports.GetPlayerViewInput = exports.GameTypeMetadata = exports.SpaceCapability = exports.LiveCapability = exports.LiveScope = exports.LiveMode = exports.GameStatusOutput = exports.PluginStateOnlyInput = exports.GameResultOutput = exports.Outcome = exports.DescribeSaveFileOutput = exports.DescribeSaveFileInput = exports.BotSkillLevelEntry = exports.AssignParticipantsOutput = exports.AssignParticipantsInput = exports.SaveFileEditRejectedError = exports.ApplySaveFileEditOutput = exports.ApplySaveFileEditInput = exports.PluginStateUpdate = exports.InvalidMoveError = exports.ApplyMoveInput = exports.Move = void 0;
4
4
  const server_common_1 = require("@aws-smithy/server-common");
5
5
  var Move;
6
6
  (function (Move) {
@@ -411,6 +411,108 @@ var GameStatusOutput;
411
411
  ];
412
412
  };
413
413
  })(GameStatusOutput || (exports.GameStatusOutput = GameStatusOutput = {}));
414
+ exports.LiveMode = {
415
+ HOSTED: "HOSTED",
416
+ RELAY: "RELAY",
417
+ };
418
+ exports.LiveScope = {
419
+ GAME: "GAME",
420
+ SPACE: "SPACE",
421
+ };
422
+ var LiveCapability;
423
+ (function (LiveCapability) {
424
+ const memberValidators = {};
425
+ LiveCapability.validate = (obj, path = "") => {
426
+ function getMemberValidator(member) {
427
+ if (memberValidators[member] === undefined) {
428
+ switch (member) {
429
+ case "mode": {
430
+ memberValidators["mode"] = new server_common_1.CompositeValidator([
431
+ new server_common_1.EnumValidator([
432
+ "RELAY",
433
+ "HOSTED",
434
+ ], [
435
+ "RELAY",
436
+ "HOSTED",
437
+ ]),
438
+ new server_common_1.RequiredValidator(),
439
+ ]);
440
+ break;
441
+ }
442
+ case "scope": {
443
+ memberValidators["scope"] = new server_common_1.CompositeValidator([
444
+ new server_common_1.EnumValidator([
445
+ "GAME",
446
+ "SPACE",
447
+ ], [
448
+ "GAME",
449
+ "SPACE",
450
+ ]),
451
+ ]);
452
+ break;
453
+ }
454
+ case "spectators": {
455
+ memberValidators["spectators"] = new server_common_1.NoOpValidator();
456
+ break;
457
+ }
458
+ case "maxSignalsPerSecond": {
459
+ memberValidators["maxSignalsPerSecond"] = new server_common_1.NoOpValidator();
460
+ break;
461
+ }
462
+ case "maxSignalBytes": {
463
+ memberValidators["maxSignalBytes"] = new server_common_1.NoOpValidator();
464
+ break;
465
+ }
466
+ }
467
+ }
468
+ return memberValidators[member];
469
+ }
470
+ return [
471
+ ...getMemberValidator("mode").validate(obj.mode, `${path}/mode`),
472
+ ...getMemberValidator("scope").validate(obj.scope, `${path}/scope`),
473
+ ...getMemberValidator("spectators").validate(obj.spectators, `${path}/spectators`),
474
+ ...getMemberValidator("maxSignalsPerSecond").validate(obj.maxSignalsPerSecond, `${path}/maxSignalsPerSecond`),
475
+ ...getMemberValidator("maxSignalBytes").validate(obj.maxSignalBytes, `${path}/maxSignalBytes`),
476
+ ];
477
+ };
478
+ })(LiveCapability || (exports.LiveCapability = LiveCapability = {}));
479
+ var SpaceCapability;
480
+ (function (SpaceCapability) {
481
+ const memberValidators = {};
482
+ SpaceCapability.validate = (obj, path = "") => {
483
+ function getMemberValidator(member) {
484
+ if (memberValidators[member] === undefined) {
485
+ switch (member) {
486
+ case "maxMembers": {
487
+ memberValidators["maxMembers"] = new server_common_1.CompositeValidator([
488
+ new server_common_1.RequiredValidator(),
489
+ ]);
490
+ break;
491
+ }
492
+ case "label": {
493
+ memberValidators["label"] = new server_common_1.NoOpValidator();
494
+ break;
495
+ }
496
+ case "settingsSchema": {
497
+ memberValidators["settingsSchema"] = new server_common_1.NoOpValidator();
498
+ break;
499
+ }
500
+ case "gameConfig": {
501
+ memberValidators["gameConfig"] = new server_common_1.NoOpValidator();
502
+ break;
503
+ }
504
+ }
505
+ }
506
+ return memberValidators[member];
507
+ }
508
+ return [
509
+ ...getMemberValidator("maxMembers").validate(obj.maxMembers, `${path}/maxMembers`),
510
+ ...getMemberValidator("label").validate(obj.label, `${path}/label`),
511
+ ...getMemberValidator("settingsSchema").validate(obj.settingsSchema, `${path}/settingsSchema`),
512
+ ...getMemberValidator("gameConfig").validate(obj.gameConfig, `${path}/gameConfig`),
513
+ ];
514
+ };
515
+ })(SpaceCapability || (exports.SpaceCapability = SpaceCapability = {}));
414
516
  var GameTypeMetadata;
415
517
  (function (GameTypeMetadata) {
416
518
  const memberValidators = {};
@@ -490,6 +592,14 @@ var GameTypeMetadata;
490
592
  memberValidators["hasSaveFileEditor"] = new server_common_1.NoOpValidator();
491
593
  break;
492
594
  }
595
+ case "spaces": {
596
+ memberValidators["spaces"] = new server_common_1.CompositeStructureValidator(new server_common_1.NoOpValidator(), SpaceCapability.validate);
597
+ break;
598
+ }
599
+ case "live": {
600
+ memberValidators["live"] = new server_common_1.CompositeStructureValidator(new server_common_1.NoOpValidator(), LiveCapability.validate);
601
+ break;
602
+ }
493
603
  }
494
604
  }
495
605
  return memberValidators[member];
@@ -510,6 +620,8 @@ var GameTypeMetadata;
510
620
  ...getMemberValidator("hasSaveFiles").validate(obj.hasSaveFiles, `${path}/hasSaveFiles`),
511
621
  ...getMemberValidator("hasSaveSummary").validate(obj.hasSaveSummary, `${path}/hasSaveSummary`),
512
622
  ...getMemberValidator("hasSaveFileEditor").validate(obj.hasSaveFileEditor, `${path}/hasSaveFileEditor`),
623
+ ...getMemberValidator("spaces").validate(obj.spaces, `${path}/spaces`),
624
+ ...getMemberValidator("live").validate(obj.live, `${path}/live`),
513
625
  ];
514
626
  };
515
627
  })(GameTypeMetadata || (exports.GameTypeMetadata = GameTypeMetadata = {}));
@@ -640,8 +640,10 @@ const serializeGetMetadataResponse = async (input, ctx) => {
640
640
  'hasSaveFiles': [],
641
641
  'hasSaveSummary': [],
642
642
  'id': [],
643
+ 'live': _ => se_LiveCapability(_, context),
643
644
  'maxPlayers': [],
644
645
  'minPlayers': [],
646
+ 'spaces': _ => se_SpaceCapability(_, context),
645
647
  'spectatorSafe': [],
646
648
  'teamPlay': [],
647
649
  }));
@@ -1051,9 +1053,26 @@ const se_BotSkillLevelList = (input, context) => {
1051
1053
  return se_BotSkillLevelEntry(entry, context);
1052
1054
  });
1053
1055
  };
1056
+ const se_LiveCapability = (input, context) => {
1057
+ return (0, smithy_client_1.take)(input, {
1058
+ 'maxSignalBytes': [],
1059
+ 'maxSignalsPerSecond': [],
1060
+ 'mode': [],
1061
+ 'scope': [],
1062
+ 'spectators': [],
1063
+ });
1064
+ };
1054
1065
  const se_ParticipantIdList = (input, context) => {
1055
1066
  return input.filter((e) => e != null);
1056
1067
  };
1068
+ const se_SpaceCapability = (input, context) => {
1069
+ return (0, smithy_client_1.take)(input, {
1070
+ 'gameConfig': _ => se_Document(_, context),
1071
+ 'label': [],
1072
+ 'maxMembers': [],
1073
+ 'settingsSchema': _ => se_Document(_, context),
1074
+ });
1075
+ };
1057
1076
  const se_Document = (input, context) => {
1058
1077
  return input;
1059
1078
  };