@rydr/game-sdk 3.8.0 → 3.9.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.
- package/README.md +1 -3
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -1
- package/dist/client/index.js.map +1 -1
- package/dist/protocol/version.d.ts +1 -1
- package/dist/protocol/version.js +1 -1
- package/package.json +1 -1
- package/dist/client/adminContent.d.ts +0 -66
- package/dist/client/adminContent.d.ts.map +0 -1
- package/dist/client/adminContent.js +0 -79
- package/dist/client/adminContent.js.map +0 -1
package/README.md
CHANGED
|
@@ -309,9 +309,7 @@ await session.deleteContent("levels", "old");
|
|
|
309
309
|
|
|
310
310
|
> **Drafts are your data, not a platform flag.** `saveContent` takes no `draft` argument — a doc's draft/published state is just a field in the content you store (`{ draft: true, … }`). Your editor writes it; your game and lobby read it and hide drafts from non-admins (admins keep seeing them via the same `isAdmin`).
|
|
311
311
|
|
|
312
|
-
> **Security boundary.** `
|
|
313
|
-
|
|
314
|
-
> **`createAdminContentBackend` is not for games.** The SDK exports a low-level Bearer client (`createAdminContentBackend`) for the **platform owner's own** out-of-band tooling — a first-party admin console on the shell's origin, a seed/migration script — code that legitimately holds the secret. It is **never** bundled into a game or a game's editor. If you're in a game, use the session.
|
|
312
|
+
> **Security boundary.** A game never authenticates admin writes. `shared`-scope writes are authorized by Supabase RLS on the **signed-in admin's** account (`app_metadata.role === 'admin'`); the shell performs them on behalf of the logged-in admin. No credential is ever shipped to a game or guest or entered into editor code. Player-generated content uses the `public` owner-write scope (`saveData(..., { scope: "public" })`), not admin auth.
|
|
315
313
|
|
|
316
314
|
### Shared worlds
|
|
317
315
|
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC"}
|
package/dist/client/index.js
CHANGED
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC"}
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
export declare const RYDR_PROTOCOL_VERSION: 14;
|
|
10
10
|
/** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
|
|
11
11
|
* (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
|
|
12
|
-
export declare const RYDR_SDK_VERSION = "3.
|
|
12
|
+
export declare const RYDR_SDK_VERSION = "3.9.0";
|
|
13
13
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/protocol/version.js
CHANGED
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
export const RYDR_PROTOCOL_VERSION = 14;
|
|
44
44
|
/** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
|
|
45
45
|
* (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
|
|
46
|
-
export const RYDR_SDK_VERSION = "3.
|
|
46
|
+
export const RYDR_SDK_VERSION = "3.9.0";
|
|
47
47
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Admin content backend — a low-level Bearer client for `shared` gamedata,
|
|
3
|
-
* intended for the **platform owner's own** out-of-band tooling: a first-party
|
|
4
|
-
* admin console on the shell's origin, a seed/migration script, CI. Code that
|
|
5
|
-
* legitimately holds the `ADMIN_SECRET`.
|
|
6
|
-
*
|
|
7
|
-
* NOT for games or their editors. A game — and a game's editor, which is just
|
|
8
|
-
* another guest the shell loads — never holds the secret. An editor is opened
|
|
9
|
-
* inside the shell, gates on `session.identity.isAdmin`, and authors through
|
|
10
|
-
* the session (`saveContent` / `deleteContent` / `getUploadUrl`); the shell
|
|
11
|
-
* relays the authenticated write. See the "Build an in-game editor" guide in
|
|
12
|
-
* the README. If you reach for this from inside a game you've broken the
|
|
13
|
-
* security boundary — use the session instead.
|
|
14
|
-
*
|
|
15
|
-
* This factory wraps the generic gamedata party's HTTP contract for one
|
|
16
|
-
* `gameId` so owner tooling doesn't hand-roll `fetch` + headers:
|
|
17
|
-
*
|
|
18
|
-
* - read (public): `GET {host}/parties/gamedata/{gameId}/shared/{collection}[/{id}]`
|
|
19
|
-
* - write (Bearer): `PUT …/shared/{collection}/{id}` body `{ data, draft? }`
|
|
20
|
-
* - delete(Bearer): `DELETE …/shared/{collection}/{id}`
|
|
21
|
-
* - asset (Bearer): `POST …/{gameId}/asset/upload-url` → presigned R2 PUT
|
|
22
|
-
*
|
|
23
|
-
* SECURITY: `ADMIN_SECRET` is the platform owner's key (full write to any
|
|
24
|
-
* game's shared content). Authoring-time only, entered at runtime, never
|
|
25
|
-
* shipped to players and never bundled into a game or guest. Player-generated
|
|
26
|
-
* content uses the SDK's public owner-write scope instead, not this backend.
|
|
27
|
-
*/
|
|
28
|
-
import type { GameDoc } from "../protocol/gamedata.js";
|
|
29
|
-
/** Bytes accepted by {@link AdminContentBackend.uploadAsset}. */
|
|
30
|
-
export type AssetBody = Blob | ArrayBuffer | ArrayBufferView;
|
|
31
|
-
export interface AdminContentBackend {
|
|
32
|
-
/** List all docs in a shared collection (includes drafts — Bearer is sent). */
|
|
33
|
-
list(collection: string): Promise<GameDoc[]>;
|
|
34
|
-
/** Fetch one shared doc, or `null` if it doesn't exist. */
|
|
35
|
-
get(collection: string, id: string): Promise<GameDoc | null>;
|
|
36
|
-
/** Create/overwrite a shared doc. `draft: true` hides it from the public (player) read until published. */
|
|
37
|
-
save(collection: string, id: string, value: unknown, opts?: {
|
|
38
|
-
draft?: boolean;
|
|
39
|
-
}): Promise<void>;
|
|
40
|
-
/** Delete a shared doc. */
|
|
41
|
-
remove(collection: string, id: string): Promise<void>;
|
|
42
|
-
/** Upload a binary asset to R2 and return its public URL (store it in a doc via {@link save}). */
|
|
43
|
-
uploadAsset(opts: {
|
|
44
|
-
collection: string;
|
|
45
|
-
filename: string;
|
|
46
|
-
contentType?: string;
|
|
47
|
-
body: AssetBody;
|
|
48
|
-
}): Promise<{
|
|
49
|
-
url: string;
|
|
50
|
-
}>;
|
|
51
|
-
}
|
|
52
|
-
export interface AdminContentOptions {
|
|
53
|
-
/** Platform origin (no trailing slash), e.g. `https://my-game.partykit.dev` or `http://localhost:1999`. */
|
|
54
|
-
host: string;
|
|
55
|
-
/** The game's stable id (slug), matching its platform manifest. */
|
|
56
|
-
gameId: string;
|
|
57
|
-
/** Returns the `ADMIN_SECRET` at call time (e.g. from `sessionStorage`). Read per-request so a re-entered secret takes effect. */
|
|
58
|
-
getSecret: () => string;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Build an {@link AdminContentBackend} for one game. Pure factory — no network
|
|
62
|
-
* until a method is called. Every request carries the Bearer secret so the
|
|
63
|
-
* editor can see drafts and perform writes.
|
|
64
|
-
*/
|
|
65
|
-
export declare function createAdminContentBackend(opts: AdminContentOptions): AdminContentBackend;
|
|
66
|
-
//# sourceMappingURL=adminContent.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adminContent.d.ts","sourceRoot":"","sources":["../../src/client/adminContent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD,iEAAiE;AACjE,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,WAAW,GAAG,eAAe,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,2DAA2D;IAC3D,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC7D,2GAA2G;IAC3G,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChG,2BAA2B;IAC3B,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kGAAkG;IAClG,WAAW,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9H;AAED,MAAM,WAAW,mBAAmB;IAClC,2GAA2G;IAC3G,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,kIAAkI;IAClI,SAAS,EAAE,MAAM,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,CAkDxF"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Admin content backend — a low-level Bearer client for `shared` gamedata,
|
|
3
|
-
* intended for the **platform owner's own** out-of-band tooling: a first-party
|
|
4
|
-
* admin console on the shell's origin, a seed/migration script, CI. Code that
|
|
5
|
-
* legitimately holds the `ADMIN_SECRET`.
|
|
6
|
-
*
|
|
7
|
-
* NOT for games or their editors. A game — and a game's editor, which is just
|
|
8
|
-
* another guest the shell loads — never holds the secret. An editor is opened
|
|
9
|
-
* inside the shell, gates on `session.identity.isAdmin`, and authors through
|
|
10
|
-
* the session (`saveContent` / `deleteContent` / `getUploadUrl`); the shell
|
|
11
|
-
* relays the authenticated write. See the "Build an in-game editor" guide in
|
|
12
|
-
* the README. If you reach for this from inside a game you've broken the
|
|
13
|
-
* security boundary — use the session instead.
|
|
14
|
-
*
|
|
15
|
-
* This factory wraps the generic gamedata party's HTTP contract for one
|
|
16
|
-
* `gameId` so owner tooling doesn't hand-roll `fetch` + headers:
|
|
17
|
-
*
|
|
18
|
-
* - read (public): `GET {host}/parties/gamedata/{gameId}/shared/{collection}[/{id}]`
|
|
19
|
-
* - write (Bearer): `PUT …/shared/{collection}/{id}` body `{ data, draft? }`
|
|
20
|
-
* - delete(Bearer): `DELETE …/shared/{collection}/{id}`
|
|
21
|
-
* - asset (Bearer): `POST …/{gameId}/asset/upload-url` → presigned R2 PUT
|
|
22
|
-
*
|
|
23
|
-
* SECURITY: `ADMIN_SECRET` is the platform owner's key (full write to any
|
|
24
|
-
* game's shared content). Authoring-time only, entered at runtime, never
|
|
25
|
-
* shipped to players and never bundled into a game or guest. Player-generated
|
|
26
|
-
* content uses the SDK's public owner-write scope instead, not this backend.
|
|
27
|
-
*/
|
|
28
|
-
/**
|
|
29
|
-
* Build an {@link AdminContentBackend} for one game. Pure factory — no network
|
|
30
|
-
* until a method is called. Every request carries the Bearer secret so the
|
|
31
|
-
* editor can see drafts and perform writes.
|
|
32
|
-
*/
|
|
33
|
-
export function createAdminContentBackend(opts) {
|
|
34
|
-
const base = `${opts.host.replace(/\/$/, "")}/parties/gamedata/${opts.gameId}`;
|
|
35
|
-
// Encode collection + id path segments so reserved chars (`:` `/` `@` …) survive
|
|
36
|
-
// the round-trip; the gamedata party decodes them. Mirrors the shell's GameDataService.
|
|
37
|
-
const enc = encodeURIComponent;
|
|
38
|
-
const authHeaders = () => ({ Authorization: `Bearer ${opts.getSecret()}` });
|
|
39
|
-
async function req(method, url, body) {
|
|
40
|
-
const res = await fetch(url, {
|
|
41
|
-
method,
|
|
42
|
-
headers: { ...authHeaders(), ...(body !== undefined ? { "Content-Type": "application/json" } : {}) },
|
|
43
|
-
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
44
|
-
});
|
|
45
|
-
if (!res.ok) {
|
|
46
|
-
const detail = await res.text().catch(() => "");
|
|
47
|
-
throw new Error(`[rydr-admin] ${method} ${url} → ${res.status} ${detail}`);
|
|
48
|
-
}
|
|
49
|
-
return (await res.json());
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
async list(collection) {
|
|
53
|
-
const r = await req("GET", `${base}/shared/${enc(collection)}`);
|
|
54
|
-
return r.docs ?? [];
|
|
55
|
-
},
|
|
56
|
-
async get(collection, id) {
|
|
57
|
-
const r = await req("GET", `${base}/shared/${enc(collection)}/${enc(id)}`);
|
|
58
|
-
return r.doc ?? null;
|
|
59
|
-
},
|
|
60
|
-
async save(collection, id, value, saveOpts) {
|
|
61
|
-
await req("PUT", `${base}/shared/${enc(collection)}/${enc(id)}`, { data: value, draft: saveOpts?.draft });
|
|
62
|
-
},
|
|
63
|
-
async remove(collection, id) {
|
|
64
|
-
await req("DELETE", `${base}/shared/${enc(collection)}/${enc(id)}`);
|
|
65
|
-
},
|
|
66
|
-
async uploadAsset({ collection, filename, contentType, body }) {
|
|
67
|
-
const { uploadUrl, url } = await req("POST", `${base}/asset/upload-url`, { collection, filename });
|
|
68
|
-
const put = await fetch(uploadUrl, {
|
|
69
|
-
method: "PUT",
|
|
70
|
-
headers: contentType ? { "Content-Type": contentType } : {},
|
|
71
|
-
body: body,
|
|
72
|
-
});
|
|
73
|
-
if (!put.ok)
|
|
74
|
-
throw new Error(`[rydr-admin] asset PUT → ${put.status}`);
|
|
75
|
-
return { url };
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=adminContent.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adminContent.js","sourceRoot":"","sources":["../../src/client/adminContent.ts"],"names":[],"mappings":"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"}
|