@crowdedkingdomstudios/crowdyjs 5.2.0 → 5.3.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.
Files changed (74) hide show
  1. package/MIGRATION.md +22 -0
  2. package/dist/client.d.ts +98 -5
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +74 -5
  5. package/dist/crowdy-client.d.ts +31 -0
  6. package/dist/crowdy-client.d.ts.map +1 -1
  7. package/dist/crowdy-client.js +8 -0
  8. package/dist/domains/actors.d.ts +87 -4
  9. package/dist/domains/actors.d.ts.map +1 -1
  10. package/dist/domains/actors.js +87 -4
  11. package/dist/domains/apps.d.ts +95 -41
  12. package/dist/domains/apps.d.ts.map +1 -1
  13. package/dist/domains/apps.js +80 -33
  14. package/dist/domains/auth.d.ts +139 -19
  15. package/dist/domains/auth.d.ts.map +1 -1
  16. package/dist/domains/auth.js +137 -17
  17. package/dist/domains/channels.d.ts +264 -5
  18. package/dist/domains/channels.d.ts.map +1 -1
  19. package/dist/domains/channels.js +264 -5
  20. package/dist/domains/chunks.d.ts +116 -3
  21. package/dist/domains/chunks.d.ts.map +1 -1
  22. package/dist/domains/chunks.js +116 -3
  23. package/dist/domains/gameModel.d.ts +412 -6
  24. package/dist/domains/gameModel.d.ts.map +1 -1
  25. package/dist/domains/gameModel.js +412 -6
  26. package/dist/domains/platform.d.ts +36 -20
  27. package/dist/domains/platform.d.ts.map +1 -1
  28. package/dist/domains/platform.js +29 -18
  29. package/dist/domains/serverStatus.d.ts +74 -6
  30. package/dist/domains/serverStatus.d.ts.map +1 -1
  31. package/dist/domains/serverStatus.js +74 -6
  32. package/dist/domains/state.d.ts +50 -2
  33. package/dist/domains/state.d.ts.map +1 -1
  34. package/dist/domains/state.js +50 -2
  35. package/dist/domains/teams.d.ts +263 -5
  36. package/dist/domains/teams.d.ts.map +1 -1
  37. package/dist/domains/teams.js +263 -5
  38. package/dist/domains/teleport.d.ts +30 -2
  39. package/dist/domains/teleport.d.ts.map +1 -1
  40. package/dist/domains/teleport.js +30 -2
  41. package/dist/domains/udp.d.ts +341 -5
  42. package/dist/domains/udp.d.ts.map +1 -1
  43. package/dist/domains/udp.js +341 -5
  44. package/dist/domains/users.d.ts +42 -11
  45. package/dist/domains/users.d.ts.map +1 -1
  46. package/dist/domains/users.js +41 -10
  47. package/dist/domains/voxels.d.ts +107 -2
  48. package/dist/domains/voxels.d.ts.map +1 -1
  49. package/dist/domains/voxels.js +107 -2
  50. package/dist/errors.d.ts +116 -0
  51. package/dist/errors.d.ts.map +1 -1
  52. package/dist/errors.js +100 -0
  53. package/dist/generated/graphql.d.ts +5 -1
  54. package/dist/generated/graphql.d.ts.map +1 -1
  55. package/dist/generated/graphql.js +5 -1
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -1
  59. package/dist/realtime.d.ts +226 -0
  60. package/dist/realtime.d.ts.map +1 -1
  61. package/dist/realtime.js +90 -0
  62. package/dist/session.d.ts +46 -0
  63. package/dist/session.d.ts.map +1 -1
  64. package/dist/session.js +35 -0
  65. package/dist/types.d.ts +429 -0
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +53 -0
  68. package/dist/utils.d.ts +86 -0
  69. package/dist/utils.d.ts.map +1 -1
  70. package/dist/utils.js +86 -0
  71. package/dist/world.d.ts +192 -0
  72. package/dist/world.d.ts.map +1 -1
  73. package/dist/world.js +170 -0
  74. package/package.json +1 -1
@@ -4,109 +4,515 @@ GameModelCreateSessionDocument, GameModelJoinSessionDocument, GameModelSetSessio
4
4
  // Studio authoring ops
5
5
  GameModelSeedDocument, GameModelUpsertContainerTypeDocument, GameModelUpsertPropertyDefDocument, GameModelUpsertFunctionDocument, GameModelDeleteFunctionDocument, GameModelDefineFeatureDocument, GameModelGrantTierFeatureDocument, GameModelSetPolicyDocument, GameModelTypeSchemaDocument, } from '../generated/graphql.js';
6
6
  /**
7
- * Abstract game model sub-client (cks-game-api). Studios author the model
8
- * (container types, property schemas, functions, tier features) and players
9
- * query state + invoke functions at runtime.
7
+ * Abstract **game-model** sub-client on the **game-api** a schema-driven,
8
+ * server-authoritative layer for modelling game/world logic on top of the
9
+ * spatial voxel world. Studios *author* the model; players *query* state and
10
+ * *invoke* functions at runtime. Exposed as `client.gameModel`.
10
11
  *
11
- * Arbitrary JSON values are passed/returned as JSON-encoded strings (the
12
- * `*Json` fields); callers JSON.parse / JSON.stringify around them.
12
+ * The model is a typed graph of entities:
13
+ * - **Container types** are the schemas (like classes) for a kind of entity.
14
+ * **Property definitions** are their typed fields, each with a default value,
15
+ * a read **visibility** (`public | owner | hidden`) and a **writability**
16
+ * (`function | owner | admin`). See {@link upsertContainerType} /
17
+ * {@link upsertPropertyDef} / {@link typeSchema}.
18
+ * - **Containers** are the runtime instances of a type, optionally scoped to a
19
+ * session and carrying property values. See {@link createContainer},
20
+ * {@link container}, {@link containers}, {@link containerState}.
21
+ * - **Functions** are named, sandboxed behaviours over containers: typed
22
+ * parameters, declared property **mutations** (expressions compiled to an AST
23
+ * server-side — never `eval`'d), an optional return expression, an
24
+ * `invokeScope` (`player | server | internal`), and an **invoke policy** — an
25
+ * authority rule tree of `owner_of_self`, `is_host`, `is_current_turn`,
26
+ * `is_participant`, `tier_feature`, `group_permission`, `grid_permission`, and
27
+ * `condition` rules. {@link invoke} is the primary, *safe* way for players to
28
+ * mutate state: the server checks the policy, evaluates the expressions,
29
+ * applies the mutations atomically, and logs an **event**.
30
+ * - **Sessions** are isolated instance scopes (a match, room, or save) with
31
+ * **participants**, a creator, and an optional current-**turn** user for
32
+ * turn-based play. See {@link createSession}, {@link joinSession},
33
+ * {@link setSessionTurn}, {@link session}, {@link sessions}.
34
+ * - **Edges** are directed, typed relationships between containers (the model is
35
+ * a graph); {@link traverse} walks them from a root up to a depth. See
36
+ * {@link addEdge}.
37
+ * - **Events** are an audit log of every function invocation and its outcome.
38
+ * See {@link events}.
39
+ * - **App features** are keys functions gate on (via `tier_feature` rules) and
40
+ * that **access tiers** can be granted ({@link defineFeature},
41
+ * {@link grantTierFeature}); **policy** governs who may create sessions and the
42
+ * default participant role ({@link setPolicy}).
43
+ * - {@link seed} bulk-creates definitions *and* instances in one transaction for
44
+ * model init/import.
13
45
  *
14
- * Exposed as `client.gameModel`.
46
+ * **Encoding.** `BigInt` ids (`appId`, `tierId`, every `*UserId`) are sent and
47
+ * received as decimal **strings**. Container, session, function, edge, and event
48
+ * ids are opaque **UUID strings**. All structured values travel as JSON-encoded
49
+ * strings in the `*Json` fields (`metadataJson`, `propertiesJson`, `paramsJson`,
50
+ * `valueJson`, `returnValueJson`, `invokePolicyJson`, `idMapJson`, …) — callers
51
+ * `JSON.parse` / `JSON.stringify` around them. (Unlike actor/state blobs, these
52
+ * are JSON text, not base64.)
53
+ *
54
+ * **Auth.** Every call requires an authenticated session (a Bearer token set via
55
+ * `client.auth.login()` or `client.setToken()`) scoped to the target app, or it
56
+ * throws {@link CrowdyGraphQLError} (`UNAUTHENTICATED` / `SCOPE_MISSING`). The
57
+ * **studio-authoring** methods ({@link seed}, {@link upsertContainerType},
58
+ * {@link upsertPropertyDef}, {@link upsertFunction}, {@link deleteFunction},
59
+ * {@link defineFeature}, {@link grantTierFeature}, {@link setPolicy}) and the
60
+ * {@link typeSchema} query additionally require the app-admin **`manage_apps`**
61
+ * permission (otherwise `FORBIDDEN`, with `extensions.requiredPermission ===
62
+ * 'manage_apps'`); the runtime/player methods need only a valid token plus
63
+ * whatever per-operation policy applies (session-creation policy, a type's
64
+ * `instantiableBy` rule, a property's `writable` rule, or a function's invoke
65
+ * policy).
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * // Studio authors a type, then a player creates a session and invokes a function.
70
+ * await client.gameModel.upsertContainerType({ appId, typeName: 'Player', displayName: 'Player' });
71
+ * const session = await client.gameModel.createSession({ appId, name: 'Match 1' });
72
+ * const result = await client.gameModel.invoke({
73
+ * appId,
74
+ * functionName: 'takeDamage',
75
+ * selfContainerId,
76
+ * paramsJson: JSON.stringify({ amount: 10 }),
77
+ * });
78
+ * if (!result.success) console.warn(result.errorMessage); // authority/eval failures don't throw
79
+ * ```
15
80
  */
16
81
  export class GameModelAPI {
17
82
  constructor(gql) {
18
83
  this.gql = gql;
19
84
  }
20
85
  // -- Runtime (player) -------------------------------------------------------
86
+ /**
87
+ * **Sessions** — create a runtime session: an isolated instance scope for
88
+ * containers (e.g. a match, room, or save). Subject to the app's
89
+ * session-creation policy ({@link setPolicy}); the caller becomes the creator
90
+ * and a participant.
91
+ *
92
+ * @param input - {@link CreateSessionInput}: `appId` (decimal string), an
93
+ * optional `name`, optional `metadataJson` (a JSON-object string), and
94
+ * optional `participantUserIds` (decimal-string ids of initial participants
95
+ * besides the creator).
96
+ * @returns The created {@link GmSession} (`sessionId`, `status`, creator,
97
+ * current turn, metadata, …).
98
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING` if the token
99
+ * is missing or not scoped to the app, `FORBIDDEN` if the session-creation
100
+ * policy disallows the caller, or `BAD_USER_INPUT` for malformed input.
101
+ */
21
102
  async createSession(input) {
22
103
  const data = await this.gql.request(GameModelCreateSessionDocument, { input });
23
104
  return data.gameModelCreateSession;
24
105
  }
106
+ /**
107
+ * **Sessions** — join an existing session as a participant, optionally with a
108
+ * role. Requires a valid token and access to the app.
109
+ *
110
+ * @param input - {@link JoinSessionInput}: `appId` (decimal string),
111
+ * `sessionId`, and an optional participant `role`.
112
+ * @returns The {@link GmSessionParticipant} record (`sessionId`, `userId`,
113
+ * `role`).
114
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
115
+ * `NOT_FOUND` if no such session, or `FORBIDDEN` if joining isn't permitted.
116
+ */
25
117
  async joinSession(input) {
26
118
  const data = await this.gql.request(GameModelJoinSessionDocument, { input });
27
119
  return data.gameModelJoinSession;
28
120
  }
121
+ /**
122
+ * **Sessions** — set or clear the session's current-turn user, for turn-based
123
+ * play (turn authority is enforced by the service).
124
+ *
125
+ * @param input - {@link SetSessionTurnInput}: `appId` (decimal string),
126
+ * `sessionId`, and `userId` (the decimal-string id of the user whose turn it
127
+ * now is) — pass `userId: null` to **clear** the turn.
128
+ * @returns The updated {@link GmSession} (with `currentTurnUserId` reflecting
129
+ * the change).
130
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
131
+ * `NOT_FOUND` if the session doesn't exist, or `FORBIDDEN` if the caller may
132
+ * not change the turn.
133
+ */
29
134
  async setSessionTurn(input) {
30
135
  const data = await this.gql.request(GameModelSetSessionTurnDocument, { input });
31
136
  return data.gameModelSetSessionTurn;
32
137
  }
138
+ /**
139
+ * **Containers** — instantiate a container (a runtime entity of a given type),
140
+ * optionally within a session, with an owner and initial property values.
141
+ * Subject to the type's `instantiableBy` rule (`admin | member | owner`).
142
+ *
143
+ * @param input - {@link CreateContainerInput}: `appId` (decimal string), an
144
+ * optional `sessionId` (omit for an app-global container), the `typeName` to
145
+ * instantiate, a `displayName`, optional `description`, optional
146
+ * `ownerUserId` (decimal string; defaults to the caller for member/owner
147
+ * instantiation), optional `metadataJson` (JSON-object string), and optional
148
+ * initial `properties` (each `{ key, valueType, valueJson }` with a
149
+ * JSON-encoded value).
150
+ * @returns The created {@link GmContainer}.
151
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
152
+ * `FORBIDDEN` if `instantiableBy` disallows the caller, `NOT_FOUND` for an
153
+ * unknown type, or `BAD_USER_INPUT` for malformed properties.
154
+ */
33
155
  async createContainer(input) {
34
156
  const data = await this.gql.request(GameModelCreateContainerDocument, { input });
35
157
  return data.gameModelCreateContainer;
36
158
  }
159
+ /**
160
+ * **Containers** — set a single property value on a container directly (outside
161
+ * a function). Allowed only when the property's `writable` rule
162
+ * (`function | owner | admin`) permits the caller; the value is JSON-encoded
163
+ * and coerced to the property's declared value type. For game-logic changes
164
+ * prefer {@link invoke}, which enforces an authority policy and logs an event.
165
+ *
166
+ * @param input - {@link SetContainerPropertyInput}: `appId` (decimal string),
167
+ * `containerId`, the property `key`, its `valueType` (must match the property
168
+ * definition), and `valueJson` (the JSON-encoded value to write).
169
+ * @returns The updated {@link GmContainer}.
170
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
171
+ * `FORBIDDEN` if the property's `writable` rule forbids a direct write,
172
+ * `NOT_FOUND` for an unknown container/property, or `BAD_USER_INPUT` for a
173
+ * value-type mismatch.
174
+ */
37
175
  async setProperty(input) {
38
176
  const data = await this.gql.request(GameModelSetPropertyDocument, { input });
39
177
  return data.gameModelSetProperty;
40
178
  }
179
+ /**
180
+ * **Edges** — create a directed relationship edge between two containers (the
181
+ * game model is a graph), with a relationship type and optional weight.
182
+ *
183
+ * @param input - {@link AddEdgeInput}: `appId` (decimal string),
184
+ * `fromContainerId` (source) and `toContainerId` (target), a
185
+ * `relationshipType` label, an optional numeric `weight`, and optional
186
+ * `metadataJson` (JSON-object string).
187
+ * @returns The created {@link GmEdge} (`edgeId`, endpoints, type, weight).
188
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
189
+ * `NOT_FOUND` if either container is unknown, or `BAD_USER_INPUT`.
190
+ */
41
191
  async addEdge(input) {
42
192
  const data = await this.gql.request(GameModelAddEdgeDocument, { input });
43
193
  return data.gameModelAddEdge;
44
194
  }
195
+ /**
196
+ * **Functions** — invoke a studio-defined function against a `self` container
197
+ * with JSON params. This is the primary, *safe* way for players to mutate game
198
+ * state: the server enforces the function's invoke policy (the authority rule
199
+ * tree — `owner_of_self` / `is_host` / `is_current_turn` / `is_participant` /
200
+ * `tier_feature` / `group_permission` / `grid_permission` / `condition`),
201
+ * evaluates its expressions, atomically applies its declared property
202
+ * mutations, and logs an {@link events | event}. Only `player`-scope functions
203
+ * are invocable here.
204
+ *
205
+ * Note: an authority denial or an expression-evaluation error is **not** a
206
+ * thrown exception — it comes back as a resolved result with `success: false`
207
+ * and an `errorMessage`. Inspect `result.success` rather than relying on
208
+ * `try/catch` for those cases.
209
+ *
210
+ * @param input - {@link InvokeFunctionInput}: `appId` (decimal string), the
211
+ * `functionName`, the `selfContainerId` (the container the function runs
212
+ * against, referenced as `self` in expressions), an optional `sessionId`
213
+ * context, and `paramsJson` (a JSON-object string of params).
214
+ * @returns A {@link GmInvokeResult}: `success`, the logged `eventId`, the
215
+ * JSON-encoded `returnValueJson`, the `mutationsApplied` (each with
216
+ * before/after JSON values), and `errorMessage` when `success` is `false`.
217
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
218
+ * `NOT_FOUND` for an unknown function/container, `FORBIDDEN` if the function
219
+ * isn't `player`-scope, or `BAD_USER_INPUT` for malformed params. (Authority
220
+ * and evaluation failures surface as `success: false`, see above.)
221
+ */
45
222
  async invoke(input) {
46
223
  const data = await this.gql.request(GameModelInvokeDocument, { input });
47
224
  return data.gameModelInvoke;
48
225
  }
226
+ /**
227
+ * **Containers** — fetch one container (instance) by id, with its full record
228
+ * (unfiltered metadata). For a player-facing view whose property values are
229
+ * filtered to what the caller may see, use {@link containerState} instead.
230
+ *
231
+ * @param variables - `{ appId, containerId }`: `appId` (decimal string) is the
232
+ * owning app and `containerId` is the container UUID to fetch.
233
+ * @returns The {@link GmContainer}.
234
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`, or
235
+ * `NOT_FOUND` if no such container.
236
+ */
49
237
  async container(variables) {
50
238
  const data = await this.gql.request(GameModelContainerDocument, variables);
51
239
  return data.gameModelContainer;
52
240
  }
241
+ /**
242
+ * **Containers** — list containers in an app, optionally narrowed by container
243
+ * type and/or session.
244
+ *
245
+ * @param variables - `{ appId, typeName?, sessionId? }`: `appId` (decimal
246
+ * string); optional `typeName` (omit for all types); optional `sessionId`
247
+ * (omit for all containers, including app-global ones).
248
+ * @returns The matching {@link GmContainer}s.
249
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`.
250
+ */
53
251
  async containers(variables) {
54
252
  const data = await this.gql.request(GameModelContainersDocument, variables);
55
253
  return data.gameModelContainers;
56
254
  }
255
+ /**
256
+ * **Containers** — fetch a container together with its property values
257
+ * filtered to what the **calling** user is allowed to see (`public` always;
258
+ * `owner`/`hidden` depend on the caller's relationship to the container). Use
259
+ * this for a player-facing view of an entity.
260
+ *
261
+ * @param variables - `{ appId, containerId }`: `appId` (decimal string) and
262
+ * the `containerId` UUID whose visible state to fetch.
263
+ * @returns A {@link GmContainerState}; its `propertiesJson` is a JSON-object
264
+ * string of the properties visible to the caller (`JSON.parse` it).
265
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`, or
266
+ * `NOT_FOUND` if no such container.
267
+ */
57
268
  async containerState(variables) {
58
269
  const data = await this.gql.request(GameModelContainerStateDocument, variables);
59
270
  return data.gameModelContainerState;
60
271
  }
272
+ /**
273
+ * **Edges** — traverse the container graph from a root container along a
274
+ * relationship type up to a given depth, returning the reachable nodes and the
275
+ * edges between them.
276
+ *
277
+ * @param variables - `{ appId, rootId, relationshipType, depth? }`: `appId`
278
+ * (decimal string); the `rootId` container UUID to start from; the
279
+ * `relationshipType` edge label to follow; and optional `depth`, the number
280
+ * of edge hops to follow from the root (defaults to `1`).
281
+ * @returns A {@link GmTraverseResult}: the `rootId`, the reachable `nodes`
282
+ * ({@link GmContainer}[]), and the traversed `edges` ({@link GmEdge}[]).
283
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`, or
284
+ * `NOT_FOUND` if the root container is unknown.
285
+ */
61
286
  async traverse(variables) {
62
287
  const data = await this.gql.request(GameModelTraverseDocument, variables);
63
288
  return data.gameModelTraverse;
64
289
  }
290
+ /**
291
+ * **Sessions** — fetch one session by id.
292
+ *
293
+ * @param variables - `{ appId, sessionId }`: `appId` (decimal string) and the
294
+ * `sessionId` to fetch.
295
+ * @returns The {@link GmSession}.
296
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`, or
297
+ * `NOT_FOUND` if no such session.
298
+ */
65
299
  async session(variables) {
66
300
  const data = await this.gql.request(GameModelSessionDocument, variables);
67
301
  return data.gameModelSession;
68
302
  }
303
+ /**
304
+ * **Sessions** — list sessions in an app, optionally filtered by status.
305
+ *
306
+ * @param variables - `{ appId, status? }`: `appId` (decimal string) and an
307
+ * optional `status` filter (e.g. `'active'`; omit for all statuses).
308
+ * @returns The matching {@link GmSession}s.
309
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`.
310
+ */
69
311
  async sessions(variables) {
70
312
  const data = await this.gql.request(GameModelSessionsDocument, variables);
71
313
  return data.gameModelSessions;
72
314
  }
315
+ /**
316
+ * **Events** — query the function-invocation event log (audit trail) with
317
+ * optional filters and pagination. Useful for debugging functions or showing
318
+ * recent activity.
319
+ *
320
+ * @param variables - `{ appId, sessionId?, selfContainerId?, functionName?,
321
+ * success?, limit?, offset? }`: `appId` (decimal string); optional
322
+ * `sessionId`; optional `selfContainerId` (the UUID the function ran
323
+ * against); optional `functionName`; optional `success` (`true` = succeeded,
324
+ * `false` = failed). `limit` (page size) and `offset` (rows to skip) are
325
+ * **deprecated** — see below.
326
+ * @returns The matching {@link GmEvent}s (each with `paramsJson`,
327
+ * `mutationsAppliedJson`, `returnValueJson`, `success`, `errorMessage`, and
328
+ * `executedAt`).
329
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`.
330
+ * @remarks The `limit`/`offset` fields use deprecated offset pagination. For
331
+ * large logs prefer the Relay-style `gameModelEventsConnection(first:, after:)`
332
+ * cursor query (available on the schema via `client.graphql`). See
333
+ * https://docs.crowdedkingdoms.com/overview/pagination.
334
+ */
73
335
  async events(variables) {
74
336
  const data = await this.gql.request(GameModelEventsDocument, variables);
75
337
  return data.gameModelEvents;
76
338
  }
77
339
  // -- Studio authoring -------------------------------------------------------
340
+ /**
341
+ * **Seed** — bulk-create game-model definitions (container types, property
342
+ * defs, functions) and optionally instances (containers + edges) in one
343
+ * transaction; used to initialize or import a model.
344
+ *
345
+ * Requires the app-admin **`manage_apps`** permission.
346
+ *
347
+ * @param input - {@link SeedGameModelInput}: `appId` (decimal string); an
348
+ * optional `sessionId` to seed instances into (omit/`null` = app-global);
349
+ * and arrays of `containerTypes`, `propertyDefinitions`, `functions`,
350
+ * `containers`, and `edges` to create. Seed containers carry a developer
351
+ * `tempId`; seed edges reference containers by those temp ids
352
+ * (`fromTempId`/`toTempId`).
353
+ * @returns A {@link GmSeedResult}: the counts created, non-fatal `warnings`,
354
+ * and `idMapJson` — a JSON-object string mapping each seed `tempId` to the
355
+ * created container UUID (`JSON.parse` it to wire up follow-up calls).
356
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
357
+ * `FORBIDDEN` (with `extensions.requiredPermission === 'manage_apps'`) if the
358
+ * caller lacks app-admin, or `BAD_USER_INPUT` for malformed definitions.
359
+ */
78
360
  async seed(input) {
79
361
  const data = await this.gql.request(GameModelSeedDocument, { input });
80
362
  return data.gameModelSeed;
81
363
  }
364
+ /**
365
+ * **Container types** — create or update a container type: the studio-defined
366
+ * schema for a kind of runtime entity (like a class). Idempotent on
367
+ * `(appId, typeName)`.
368
+ *
369
+ * Requires the app-admin **`manage_apps`** permission.
370
+ *
371
+ * @param input - {@link UpsertContainerTypeInput}: `appId` (decimal string);
372
+ * the `typeName` (the stable upsert key, unique per app); a `displayName`;
373
+ * optional `description`; optional `instantiableBy` (`admin | member |
374
+ * owner`); optional `defaultPropertyVisibility` (`public | owner | hidden`);
375
+ * and optional `metadataJson` (JSON-object string).
376
+ * @returns The upserted {@link GmContainerType}.
377
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
378
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), or `BAD_USER_INPUT`.
379
+ */
82
380
  async upsertContainerType(input) {
83
381
  const data = await this.gql.request(GameModelUpsertContainerTypeDocument, { input });
84
382
  return data.gameModelUpsertContainerType;
85
383
  }
384
+ /**
385
+ * **Property definitions** — create or update a typed property on a container
386
+ * type (a field with a default value, read visibility, and writability).
387
+ * Idempotent on `(appId, containerTypeName, key)`.
388
+ *
389
+ * Requires the app-admin **`manage_apps`** permission.
390
+ *
391
+ * @param input - {@link UpsertPropertyDefInput}: `appId` (decimal string); the
392
+ * `containerTypeName` to define on; the property `key` (part of the upsert
393
+ * key); a `valueType` (`int | float | string | bool | array | object |
394
+ * container_ref`); optional `defaultValueJson` (JSON-encoded default);
395
+ * optional `visibility` (`public | owner | hidden`); optional `writable`
396
+ * (`function | owner | admin`); and optional `description`.
397
+ * @returns The upserted {@link GmPropertyDef}.
398
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
399
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), `NOT_FOUND` for an
400
+ * unknown container type, or `BAD_USER_INPUT`.
401
+ */
86
402
  async upsertPropertyDef(input) {
87
403
  const data = await this.gql.request(GameModelUpsertPropertyDefDocument, { input });
88
404
  return data.gameModelUpsertPropertyDef;
89
405
  }
406
+ /**
407
+ * **Functions** — create or update a studio-defined function: a named,
408
+ * sandboxed behaviour with typed parameters, declared property mutations
409
+ * (expressions compiled to an AST server-side — never `eval`'d), an optional
410
+ * return expression, an invoke scope, and an invoke policy (authority rule
411
+ * tree). Idempotent on `(appId, name)`. Players run these via {@link invoke}.
412
+ *
413
+ * Requires the app-admin **`manage_apps`** permission.
414
+ *
415
+ * @param input - {@link UpsertFunctionInput}: `appId` (decimal string); the
416
+ * `name` (upsert key, used to invoke it); optional `containerTypeName` to
417
+ * bind to (omit for a global function); optional `description`; optional
418
+ * `returnType`; `parameters` (typed `{ name, valueType, required?,
419
+ * defaultValueJson?, … }`); `mutations` (declared writes `{ target, property,
420
+ * expression }`, applied atomically); optional `returnExpression`;
421
+ * `invokeScope` (`player | server | internal`); and `invokePolicyJson` (a
422
+ * JSON-encoded authority rule tree).
423
+ * @returns The upserted {@link GmFunction}, including any non-fatal
424
+ * static-analysis `warnings` from this upload.
425
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
426
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), or `BAD_USER_INPUT`
427
+ * for an expression/policy that fails to compile.
428
+ */
90
429
  async upsertFunction(input) {
91
430
  const data = await this.gql.request(GameModelUpsertFunctionDocument, { input });
92
431
  return data.gameModelUpsertFunction;
93
432
  }
433
+ /**
434
+ * **Functions** — delete a studio-defined function by name. **Destructive.**
435
+ *
436
+ * Requires the app-admin **`manage_apps`** permission.
437
+ *
438
+ * @param variables - `{ appId, name }`: `appId` (decimal string) and the
439
+ * function `name` to delete.
440
+ * @returns `true` if a function was deleted, `false` if none matched.
441
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`, or
442
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`) if the caller lacks
443
+ * app-admin.
444
+ */
94
445
  async deleteFunction(variables) {
95
446
  const data = await this.gql.request(GameModelDeleteFunctionDocument, variables);
96
447
  return data.gameModelDeleteFunction;
97
448
  }
449
+ /**
450
+ * **App features** — define an app feature key that functions can gate on (via
451
+ * a `tier_feature` authority rule) and that access tiers can be granted.
452
+ * Idempotent on `(appId, featureKey)`.
453
+ *
454
+ * Requires the app-admin **`manage_apps`** permission.
455
+ *
456
+ * @param input - {@link DefineAppFeatureInput}: `appId` (decimal string); the
457
+ * `featureKey` (referenced by `tier_feature` rules); and an optional
458
+ * `description`.
459
+ * @returns The defined {@link GmAppFeature}.
460
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
461
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), or `BAD_USER_INPUT`.
462
+ */
98
463
  async defineFeature(input) {
99
464
  const data = await this.gql.request(GameModelDefineFeatureDocument, { input });
100
465
  return data.gameModelDefineFeature;
101
466
  }
467
+ /**
468
+ * **App features** — grant a feature key to an access tier, so users on that
469
+ * tier satisfy `tier_feature` authority checks for it.
470
+ *
471
+ * Requires the app-admin **`manage_apps`** permission.
472
+ *
473
+ * @param input - {@link GrantTierFeatureInput}: `appId` (decimal string); the
474
+ * `tierId` (decimal string) of the access tier; and the `featureKey` to
475
+ * grant to that tier.
476
+ * @returns The {@link GmTierFeature} grant record.
477
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
478
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), or `NOT_FOUND` for an
479
+ * unknown tier/feature.
480
+ */
102
481
  async grantTierFeature(input) {
103
482
  const data = await this.gql.request(GameModelGrantTierFeatureDocument, { input });
104
483
  return data.gameModelGrantTierFeature;
105
484
  }
485
+ /**
486
+ * **Policy** — set the app's game-model runtime policy: who may create
487
+ * sessions and the default role assigned to new session participants.
488
+ *
489
+ * Requires the app-admin **`manage_apps`** permission.
490
+ *
491
+ * @param input - {@link SetGameModelPolicyInput}: `appId` (decimal string); an
492
+ * optional `sessionCreationPolicy` (`admin | member | anyone`); and an
493
+ * optional `defaultParticipantRole`.
494
+ * @returns The updated {@link GmAppPolicy}.
495
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
496
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), or `BAD_USER_INPUT`.
497
+ */
106
498
  async setPolicy(input) {
107
499
  const data = await this.gql.request(GameModelSetPolicyDocument, { input });
108
500
  return data.gameModelSetPolicy;
109
501
  }
502
+ /**
503
+ * **Container types** — fetch a container type's full schema: its property
504
+ * definitions plus the functions available on it. A studio/authoring read.
505
+ *
506
+ * Requires the app-admin **`manage_apps`** permission.
507
+ *
508
+ * @param variables - `{ appId, typeName }`: `appId` (decimal string) and the
509
+ * `typeName` whose schema to fetch.
510
+ * @returns A {@link GmTypeSchema}: the `typeName`, its `propertyDefinitions`
511
+ * ({@link GmPropertyDef}[]), and its `functions` ({@link GmFunction}[]).
512
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `SCOPE_MISSING`,
513
+ * `FORBIDDEN` (`requiredPermission === 'manage_apps'`), or `NOT_FOUND` for an
514
+ * unknown type.
515
+ */
110
516
  async typeSchema(variables) {
111
517
  const data = await this.gql.request(GameModelTypeSchemaDocument, variables);
112
518
  return data.gameModelTypeSchema;
@@ -1,33 +1,49 @@
1
+ import type { GraphQLClient } from '../client.js';
1
2
  /**
2
- * Platform discovery sub-client. Targets `cks-management-api`. Lets a client
3
- * find the shared game-api URL (for apps published to the shared environment)
4
- * BEFORE it has a per-app endpoint, then build a game-api `CrowdyClient`
5
- * against it.
6
- *
7
- * Typical pattern:
8
- *
9
- * const base = createCrowdyClient({ managementUrl: 'https://api.example.com' });
10
- * const cfg = await base.platform.config();
11
- * const gameClient = createCrowdyClient({
12
- * managementUrl: 'https://api.example.com',
13
- * httpUrl: cfg.sharedGameApiUrl ?? undefined,
14
- * wsUrl: cfg.sharedGameApiWsUrl ?? undefined,
15
- * tokenStore: base.session.tokenStore,
16
- * });
3
+ * Public platform discovery returned by {@link PlatformAPI.config}: how SDKs
4
+ * find the shared game-api so they can route apps deployed to the shared
5
+ * environment. All fields are public (no auth required to read them).
17
6
  */
18
- import type { GraphQLClient } from '../client.js';
19
7
  export interface PlatformConfig {
20
- /** Shared game-api HTTP/GraphQL root for shared-environment apps. */
8
+ /** Shared game-api HTTP/GraphQL root for shared-environment apps; `null` if unset. */
21
9
  sharedGameApiUrl: string | null;
22
- /** Shared game-api WebSocket root (subscriptions / UDP proxy). */
10
+ /** Shared game-api WebSocket root (subscriptions / UDP proxy); `null` if unset. */
23
11
  sharedGameApiWsUrl: string | null;
24
- /** Free shared app slots an org gets before a paid subscription. */
12
+ /** Free shared app slots an org gets before a paid subscription is required. */
25
13
  freeAppsPerOrg: number;
26
14
  }
15
+ /**
16
+ * Public platform discovery — exposed as `client.platform`.
17
+ *
18
+ * Targets the **management-api** (every call routes to `managementUrl`).
19
+ * **Public**: no authentication required. Lets a client discover the shared
20
+ * game-api URL (for apps published to the shared environment) *before* it has a
21
+ * per-app endpoint, then build a game-api `CrowdyClient` against it.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const base = createCrowdyClient({ managementUrl: 'https://api.example.com' });
26
+ * const cfg = await base.platform.config();
27
+ * const gameClient = createCrowdyClient({
28
+ * managementUrl: 'https://api.example.com',
29
+ * httpUrl: cfg.sharedGameApiUrl ?? undefined,
30
+ * wsUrl: cfg.sharedGameApiWsUrl ?? undefined,
31
+ * tokenStore: base.session.tokenStore,
32
+ * });
33
+ * ```
34
+ */
27
35
  export declare class PlatformAPI {
28
36
  private readonly management;
29
37
  constructor(management: GraphQLClient);
30
- /** Fetch public platform discovery (shared game-api URL, free app quota). */
38
+ /**
39
+ * Fetch public platform discovery: the shared game-api URL clients use for
40
+ * shared-environment apps, plus the free shared-app quota. **Public** — no
41
+ * authentication required.
42
+ *
43
+ * @returns A {@link PlatformConfig} (`sharedGameApiUrl`, `sharedGameApiWsUrl`,
44
+ * and `freeAppsPerOrg`).
45
+ * @throws {CrowdyGraphQLError} on transport/validation failures.
46
+ */
31
47
  config(): Promise<PlatformConfig>;
32
48
  }
33
49
  //# sourceMappingURL=platform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/domains/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kEAAkE;IAClE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;CACxB;AAiBD,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,aAAa;IAEtD,6EAA6E;IACvE,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;CAIxC"}
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/domains/platform.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,sFAAsF;IACtF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mFAAmF;IACnF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,gFAAgF;IAChF,cAAc,EAAE,MAAM,CAAC;CACxB;AAiBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,aAAa;IAEtD;;;;;;;;OAQG;IACG,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;CAIxC"}
@@ -1,20 +1,3 @@
1
- /**
2
- * Platform discovery sub-client. Targets `cks-management-api`. Lets a client
3
- * find the shared game-api URL (for apps published to the shared environment)
4
- * BEFORE it has a per-app endpoint, then build a game-api `CrowdyClient`
5
- * against it.
6
- *
7
- * Typical pattern:
8
- *
9
- * const base = createCrowdyClient({ managementUrl: 'https://api.example.com' });
10
- * const cfg = await base.platform.config();
11
- * const gameClient = createCrowdyClient({
12
- * managementUrl: 'https://api.example.com',
13
- * httpUrl: cfg.sharedGameApiUrl ?? undefined,
14
- * wsUrl: cfg.sharedGameApiWsUrl ?? undefined,
15
- * tokenStore: base.session.tokenStore,
16
- * });
17
- */
18
1
  import { parse } from 'graphql';
19
2
  // Hand-written document so the SDK can discover the shared game-api URL even
20
3
  // before codegen picks up the new schema (see src/operations/platform/).
@@ -27,11 +10,39 @@ const PlatformConfigDocument = parse(/* GraphQL */ `
27
10
  }
28
11
  }
29
12
  `);
13
+ /**
14
+ * Public platform discovery — exposed as `client.platform`.
15
+ *
16
+ * Targets the **management-api** (every call routes to `managementUrl`).
17
+ * **Public**: no authentication required. Lets a client discover the shared
18
+ * game-api URL (for apps published to the shared environment) *before* it has a
19
+ * per-app endpoint, then build a game-api `CrowdyClient` against it.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const base = createCrowdyClient({ managementUrl: 'https://api.example.com' });
24
+ * const cfg = await base.platform.config();
25
+ * const gameClient = createCrowdyClient({
26
+ * managementUrl: 'https://api.example.com',
27
+ * httpUrl: cfg.sharedGameApiUrl ?? undefined,
28
+ * wsUrl: cfg.sharedGameApiWsUrl ?? undefined,
29
+ * tokenStore: base.session.tokenStore,
30
+ * });
31
+ * ```
32
+ */
30
33
  export class PlatformAPI {
31
34
  constructor(management) {
32
35
  this.management = management;
33
36
  }
34
- /** Fetch public platform discovery (shared game-api URL, free app quota). */
37
+ /**
38
+ * Fetch public platform discovery: the shared game-api URL clients use for
39
+ * shared-environment apps, plus the free shared-app quota. **Public** — no
40
+ * authentication required.
41
+ *
42
+ * @returns A {@link PlatformConfig} (`sharedGameApiUrl`, `sharedGameApiWsUrl`,
43
+ * and `freeAppsPerOrg`).
44
+ * @throws {CrowdyGraphQLError} on transport/validation failures.
45
+ */
35
46
  async config() {
36
47
  const data = await this.management.request(PlatformConfigDocument, {});
37
48
  return data.platformConfig;