@pluv/platform-pluv 0.38.3 → 0.38.5
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +18 -0
- package/dist/index.d.mts +11 -22
- package/dist/index.d.ts +11 -22
- package/dist/index.js +16 -10
- package/dist/index.mjs +16 -10
- package/package.json +6 -6
- package/src/PluvPlatform.ts +27 -16
- package/src/constants.ts +1 -0
- package/src/index.ts +1 -6
- package/src/platformPluv.ts +2 -2
- package/src/types.ts +18 -23
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/platform-pluv@0.38.
|
|
2
|
+
> @pluv/platform-pluv@0.38.5 build /home/runner/work/pluv/pluv/packages/platform-pluv
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
14
|
-
[
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m11.86 KB[39m
|
|
12
|
+
[32mCJS[39m ⚡️ Build success in 84ms
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m10.32 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 85ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 6199ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.43 KB[39m
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.43 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @pluv/platform-pluv
|
|
2
2
|
|
|
3
|
+
## 0.38.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 77df696: Fixed platform event contexts being undefined.
|
|
8
|
+
- @pluv/crdt@0.38.5
|
|
9
|
+
- @pluv/io@0.38.5
|
|
10
|
+
- @pluv/types@0.38.5
|
|
11
|
+
|
|
12
|
+
## 0.38.4
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 15399b7: Fix webhook signature validation.
|
|
17
|
+
- @pluv/crdt@0.38.4
|
|
18
|
+
- @pluv/io@0.38.4
|
|
19
|
+
- @pluv/types@0.38.4
|
|
20
|
+
|
|
3
21
|
## 0.38.3
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -1,25 +1,11 @@
|
|
|
1
|
-
import { AbstractPlatform, JWTEncodeParams, AbstractWebSocket, ConvertWebSocketConfig, WebSocketSerializedState, AbstractPlatformConfig, CreateIOParams, PluvIOAuthorize, InferInitContextType, PluvContext } from '@pluv/io';
|
|
2
|
-
import { BaseUser, Id } from '@pluv/types';
|
|
1
|
+
import { BaseUser, AbstractPlatform, JWTEncodeParams, AbstractWebSocket, ConvertWebSocketConfig, WebSocketSerializedState, AbstractPlatformConfig, CreateIOParams, PluvIOAuthorize, InferInitContextType, PluvContext } from '@pluv/io';
|
|
2
|
+
import { BaseUser as BaseUser$1, Id } from '@pluv/types';
|
|
3
3
|
|
|
4
4
|
interface PluvIOEndpoints {
|
|
5
5
|
createToken: string;
|
|
6
6
|
}
|
|
7
|
-
type RoomDeletedMessageEventData = {
|
|
8
|
-
encodedState: string | null;
|
|
9
|
-
room: string;
|
|
10
|
-
};
|
|
11
|
-
type UserConnectedEventData = {
|
|
12
|
-
encodedState: string | null;
|
|
13
|
-
room: string;
|
|
14
|
-
user: any;
|
|
15
|
-
};
|
|
16
|
-
type UserDisconnectedEventData = {
|
|
17
|
-
encodedState: string | null;
|
|
18
|
-
room: string;
|
|
19
|
-
user: any;
|
|
20
|
-
};
|
|
21
7
|
|
|
22
|
-
interface PluvPlatformConfig {
|
|
8
|
+
interface PluvPlatformConfig<TContext extends Record<string, any> = {}> {
|
|
23
9
|
/**
|
|
24
10
|
* @ignore
|
|
25
11
|
* @readonly
|
|
@@ -29,11 +15,12 @@ interface PluvPlatformConfig {
|
|
|
29
15
|
endpoints?: PluvIOEndpoints;
|
|
30
16
|
};
|
|
31
17
|
basePath: string;
|
|
18
|
+
context?: TContext;
|
|
32
19
|
publicKey: string;
|
|
33
20
|
secretKey: string;
|
|
34
21
|
webhookSecret?: string;
|
|
35
22
|
}
|
|
36
|
-
declare class PluvPlatform extends AbstractPlatform<any, {}, {}, {
|
|
23
|
+
declare class PluvPlatform<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> extends AbstractPlatform<any, {}, {}, {
|
|
37
24
|
authorize: {
|
|
38
25
|
secret: false;
|
|
39
26
|
};
|
|
@@ -66,8 +53,10 @@ declare class PluvPlatform extends AbstractPlatform<any, {}, {}, {
|
|
|
66
53
|
router: false;
|
|
67
54
|
};
|
|
68
55
|
readonly _name = "platformPluv";
|
|
56
|
+
private readonly _app;
|
|
69
57
|
private _authorize;
|
|
70
58
|
private readonly _basePath;
|
|
59
|
+
private readonly _context;
|
|
71
60
|
private readonly _endpoints;
|
|
72
61
|
private _getInitialStorage?;
|
|
73
62
|
private _listeners?;
|
|
@@ -87,13 +76,13 @@ declare class PluvPlatform extends AbstractPlatform<any, {}, {}, {
|
|
|
87
76
|
randomUUID(): string;
|
|
88
77
|
setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
|
|
89
78
|
validateConfig(config: any): void;
|
|
90
|
-
private
|
|
79
|
+
private _webhooksRouter;
|
|
91
80
|
}
|
|
92
81
|
|
|
93
|
-
type PlatformPluvCreateIOParams<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> = Id<PluvPlatformConfig & Omit<CreateIOParams<PluvPlatform, TContext, TUser>, "authorize" | "context" | "platform"> & {
|
|
82
|
+
type PlatformPluvCreateIOParams<TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1> = Id<PluvPlatformConfig & Omit<CreateIOParams<PluvPlatform, TContext, TUser>, "authorize" | "context" | "platform"> & {
|
|
94
83
|
authorize: PluvIOAuthorize<PluvPlatform, TUser, InferInitContextType<PluvPlatform>>;
|
|
95
84
|
context?: PluvContext<PluvPlatform, TContext>;
|
|
96
85
|
}>;
|
|
97
|
-
declare const platformPluv: <TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser>(config: PlatformPluvCreateIOParams<TContext, TUser>) => CreateIOParams<PluvPlatform, TContext, TUser>;
|
|
86
|
+
declare const platformPluv: <TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1>(config: PlatformPluvCreateIOParams<TContext, TUser>) => CreateIOParams<PluvPlatform<TContext, TUser>, TContext, TUser>;
|
|
98
87
|
|
|
99
|
-
export { type PlatformPluvCreateIOParams, type PluvIOEndpoints, PluvPlatform,
|
|
88
|
+
export { type PlatformPluvCreateIOParams, type PluvIOEndpoints, PluvPlatform, platformPluv };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,11 @@
|
|
|
1
|
-
import { AbstractPlatform, JWTEncodeParams, AbstractWebSocket, ConvertWebSocketConfig, WebSocketSerializedState, AbstractPlatformConfig, CreateIOParams, PluvIOAuthorize, InferInitContextType, PluvContext } from '@pluv/io';
|
|
2
|
-
import { BaseUser, Id } from '@pluv/types';
|
|
1
|
+
import { BaseUser, AbstractPlatform, JWTEncodeParams, AbstractWebSocket, ConvertWebSocketConfig, WebSocketSerializedState, AbstractPlatformConfig, CreateIOParams, PluvIOAuthorize, InferInitContextType, PluvContext } from '@pluv/io';
|
|
2
|
+
import { BaseUser as BaseUser$1, Id } from '@pluv/types';
|
|
3
3
|
|
|
4
4
|
interface PluvIOEndpoints {
|
|
5
5
|
createToken: string;
|
|
6
6
|
}
|
|
7
|
-
type RoomDeletedMessageEventData = {
|
|
8
|
-
encodedState: string | null;
|
|
9
|
-
room: string;
|
|
10
|
-
};
|
|
11
|
-
type UserConnectedEventData = {
|
|
12
|
-
encodedState: string | null;
|
|
13
|
-
room: string;
|
|
14
|
-
user: any;
|
|
15
|
-
};
|
|
16
|
-
type UserDisconnectedEventData = {
|
|
17
|
-
encodedState: string | null;
|
|
18
|
-
room: string;
|
|
19
|
-
user: any;
|
|
20
|
-
};
|
|
21
7
|
|
|
22
|
-
interface PluvPlatformConfig {
|
|
8
|
+
interface PluvPlatformConfig<TContext extends Record<string, any> = {}> {
|
|
23
9
|
/**
|
|
24
10
|
* @ignore
|
|
25
11
|
* @readonly
|
|
@@ -29,11 +15,12 @@ interface PluvPlatformConfig {
|
|
|
29
15
|
endpoints?: PluvIOEndpoints;
|
|
30
16
|
};
|
|
31
17
|
basePath: string;
|
|
18
|
+
context?: TContext;
|
|
32
19
|
publicKey: string;
|
|
33
20
|
secretKey: string;
|
|
34
21
|
webhookSecret?: string;
|
|
35
22
|
}
|
|
36
|
-
declare class PluvPlatform extends AbstractPlatform<any, {}, {}, {
|
|
23
|
+
declare class PluvPlatform<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> extends AbstractPlatform<any, {}, {}, {
|
|
37
24
|
authorize: {
|
|
38
25
|
secret: false;
|
|
39
26
|
};
|
|
@@ -66,8 +53,10 @@ declare class PluvPlatform extends AbstractPlatform<any, {}, {}, {
|
|
|
66
53
|
router: false;
|
|
67
54
|
};
|
|
68
55
|
readonly _name = "platformPluv";
|
|
56
|
+
private readonly _app;
|
|
69
57
|
private _authorize;
|
|
70
58
|
private readonly _basePath;
|
|
59
|
+
private readonly _context;
|
|
71
60
|
private readonly _endpoints;
|
|
72
61
|
private _getInitialStorage?;
|
|
73
62
|
private _listeners?;
|
|
@@ -87,13 +76,13 @@ declare class PluvPlatform extends AbstractPlatform<any, {}, {}, {
|
|
|
87
76
|
randomUUID(): string;
|
|
88
77
|
setSerializedState(webSocket: AbstractWebSocket, state: WebSocketSerializedState): WebSocketSerializedState;
|
|
89
78
|
validateConfig(config: any): void;
|
|
90
|
-
private
|
|
79
|
+
private _webhooksRouter;
|
|
91
80
|
}
|
|
92
81
|
|
|
93
|
-
type PlatformPluvCreateIOParams<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> = Id<PluvPlatformConfig & Omit<CreateIOParams<PluvPlatform, TContext, TUser>, "authorize" | "context" | "platform"> & {
|
|
82
|
+
type PlatformPluvCreateIOParams<TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1> = Id<PluvPlatformConfig & Omit<CreateIOParams<PluvPlatform, TContext, TUser>, "authorize" | "context" | "platform"> & {
|
|
94
83
|
authorize: PluvIOAuthorize<PluvPlatform, TUser, InferInitContextType<PluvPlatform>>;
|
|
95
84
|
context?: PluvContext<PluvPlatform, TContext>;
|
|
96
85
|
}>;
|
|
97
|
-
declare const platformPluv: <TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser>(config: PlatformPluvCreateIOParams<TContext, TUser>) => CreateIOParams<PluvPlatform, TContext, TUser>;
|
|
86
|
+
declare const platformPluv: <TContext extends Record<string, any> = {}, TUser extends BaseUser$1 = BaseUser$1>(config: PlatformPluvCreateIOParams<TContext, TUser>) => CreateIOParams<PluvPlatform<TContext, TUser>, TContext, TUser>;
|
|
98
87
|
|
|
99
|
-
export { type PlatformPluvCreateIOParams, type PluvIOEndpoints, PluvPlatform,
|
|
88
|
+
export { type PlatformPluvCreateIOParams, type PluvIOEndpoints, PluvPlatform, platformPluv };
|
package/dist/index.js
CHANGED
|
@@ -75,6 +75,7 @@ var import_fast_json_stable_stringify = __toESM(require("fast-json-stable-string
|
|
|
75
75
|
var import_hono = require("hono");
|
|
76
76
|
|
|
77
77
|
// src/constants.ts
|
|
78
|
+
var SIGNATURE_ALGORITHM = "sha256";
|
|
78
79
|
var SIGNATURE_HEADER = "x-pluv-signature-256";
|
|
79
80
|
|
|
80
81
|
// src/schemas.ts
|
|
@@ -213,10 +214,12 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
213
214
|
if (typeof token !== "string") throw new Error("Authorization failed");
|
|
214
215
|
return token;
|
|
215
216
|
});
|
|
216
|
-
this.
|
|
217
|
-
var _a, _b, _c, _d, _e;
|
|
218
|
-
const signature = c.req.header(SIGNATURE_HEADER);
|
|
219
|
-
if (!this._webhookSecret
|
|
217
|
+
this._webhooksRouter = new import_hono.Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
|
|
218
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
219
|
+
const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
|
|
220
|
+
if (!this._webhookSecret) return c.json({ error: "Unauthorized" }, 401);
|
|
221
|
+
if (algorithm !== SIGNATURE_ALGORITHM) return c.json({ error: "Unauthorized" }, 401);
|
|
222
|
+
if (!signature) return c.json({ error: "Unauthorized" }, 401);
|
|
220
223
|
const payload = yield c.req.json();
|
|
221
224
|
const verified = yield verifyWebhook({
|
|
222
225
|
payload: (0, import_fast_json_stable_stringify.default)(payload),
|
|
@@ -227,43 +230,46 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
|
|
|
227
230
|
const parsed = ZodEvent.safeParse(payload);
|
|
228
231
|
if (!parsed.success) return c.json({ data: { ok: true } }, 200);
|
|
229
232
|
const { event, data } = parsed.data;
|
|
233
|
+
const context = this._context;
|
|
230
234
|
switch (event) {
|
|
231
235
|
case "initial-storage": {
|
|
232
236
|
const room = data.room;
|
|
233
|
-
const storage = typeof room === "string" ? (
|
|
237
|
+
const storage = typeof room === "string" ? (_d = yield (_c = this._getInitialStorage) == null ? void 0 : _c.call(this, { context, room })) != null ? _d : null : null;
|
|
234
238
|
return c.json({ data: { storage } }, 200);
|
|
235
239
|
}
|
|
236
240
|
case "room-deleted": {
|
|
237
241
|
const room = data.room;
|
|
238
242
|
const encodedState = data.storage;
|
|
239
|
-
yield Promise.resolve((
|
|
243
|
+
yield Promise.resolve((_e = this._listeners) == null ? void 0 : _e.onRoomDeleted({ context, encodedState, room }));
|
|
240
244
|
return c.json({ data: { room } }, 200);
|
|
241
245
|
}
|
|
242
246
|
case "user-connected": {
|
|
243
247
|
const room = data.room;
|
|
244
248
|
const encodedState = data.storage;
|
|
245
249
|
const user = data.user;
|
|
246
|
-
yield Promise.resolve((
|
|
250
|
+
yield Promise.resolve((_f = this._listeners) == null ? void 0 : _f.onUserConnected({ context, encodedState, room, user }));
|
|
247
251
|
}
|
|
248
252
|
case "user-disconnected": {
|
|
249
253
|
const room = data.room;
|
|
250
254
|
const encodedState = data.storage;
|
|
251
255
|
const user = data.user;
|
|
252
|
-
yield Promise.resolve((
|
|
256
|
+
yield Promise.resolve((_g = this._listeners) == null ? void 0 : _g.onUserDisconnected({ context, encodedState, room, user }));
|
|
253
257
|
}
|
|
254
258
|
default:
|
|
255
259
|
return c.json({ data: { ok: true } }, 200);
|
|
256
260
|
}
|
|
257
261
|
}));
|
|
258
|
-
const { _defs, basePath, publicKey, secretKey, webhookSecret } = params;
|
|
262
|
+
const { _defs, context, basePath, publicKey, secretKey, webhookSecret } = params;
|
|
259
263
|
this._basePath = basePath;
|
|
264
|
+
this._context = typeof context === "function" ? context(this._roomContext) : context;
|
|
260
265
|
this._endpoints = __spreadValues({
|
|
261
266
|
createToken: "https://pluv.io/api/room/token"
|
|
262
267
|
}, _defs == null ? void 0 : _defs.endpoints);
|
|
263
268
|
this._publicKey = publicKey;
|
|
264
269
|
this._secretKey = secretKey;
|
|
265
270
|
this._webhookSecret = webhookSecret;
|
|
266
|
-
this.
|
|
271
|
+
this._app = new import_hono.Hono().basePath(this._basePath).route("/", this._webhooksRouter);
|
|
272
|
+
this._fetch = this._app.fetch;
|
|
267
273
|
}
|
|
268
274
|
acceptWebSocket(webSocket) {
|
|
269
275
|
throw new Error("Not implemented");
|
package/dist/index.mjs
CHANGED
|
@@ -47,6 +47,7 @@ import stringify from "fast-json-stable-stringify";
|
|
|
47
47
|
import { Hono } from "hono";
|
|
48
48
|
|
|
49
49
|
// src/constants.ts
|
|
50
|
+
var SIGNATURE_ALGORITHM = "sha256";
|
|
50
51
|
var SIGNATURE_HEADER = "x-pluv-signature-256";
|
|
51
52
|
|
|
52
53
|
// src/schemas.ts
|
|
@@ -185,10 +186,12 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
185
186
|
if (typeof token !== "string") throw new Error("Authorization failed");
|
|
186
187
|
return token;
|
|
187
188
|
});
|
|
188
|
-
this.
|
|
189
|
-
var _a, _b, _c, _d, _e;
|
|
190
|
-
const signature = c.req.header(SIGNATURE_HEADER);
|
|
191
|
-
if (!this._webhookSecret
|
|
189
|
+
this._webhooksRouter = new Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
|
|
190
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
191
|
+
const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
|
|
192
|
+
if (!this._webhookSecret) return c.json({ error: "Unauthorized" }, 401);
|
|
193
|
+
if (algorithm !== SIGNATURE_ALGORITHM) return c.json({ error: "Unauthorized" }, 401);
|
|
194
|
+
if (!signature) return c.json({ error: "Unauthorized" }, 401);
|
|
192
195
|
const payload = yield c.req.json();
|
|
193
196
|
const verified = yield verifyWebhook({
|
|
194
197
|
payload: stringify(payload),
|
|
@@ -199,43 +202,46 @@ var PluvPlatform = class extends AbstractPlatform {
|
|
|
199
202
|
const parsed = ZodEvent.safeParse(payload);
|
|
200
203
|
if (!parsed.success) return c.json({ data: { ok: true } }, 200);
|
|
201
204
|
const { event, data } = parsed.data;
|
|
205
|
+
const context = this._context;
|
|
202
206
|
switch (event) {
|
|
203
207
|
case "initial-storage": {
|
|
204
208
|
const room = data.room;
|
|
205
|
-
const storage = typeof room === "string" ? (
|
|
209
|
+
const storage = typeof room === "string" ? (_d = yield (_c = this._getInitialStorage) == null ? void 0 : _c.call(this, { context, room })) != null ? _d : null : null;
|
|
206
210
|
return c.json({ data: { storage } }, 200);
|
|
207
211
|
}
|
|
208
212
|
case "room-deleted": {
|
|
209
213
|
const room = data.room;
|
|
210
214
|
const encodedState = data.storage;
|
|
211
|
-
yield Promise.resolve((
|
|
215
|
+
yield Promise.resolve((_e = this._listeners) == null ? void 0 : _e.onRoomDeleted({ context, encodedState, room }));
|
|
212
216
|
return c.json({ data: { room } }, 200);
|
|
213
217
|
}
|
|
214
218
|
case "user-connected": {
|
|
215
219
|
const room = data.room;
|
|
216
220
|
const encodedState = data.storage;
|
|
217
221
|
const user = data.user;
|
|
218
|
-
yield Promise.resolve((
|
|
222
|
+
yield Promise.resolve((_f = this._listeners) == null ? void 0 : _f.onUserConnected({ context, encodedState, room, user }));
|
|
219
223
|
}
|
|
220
224
|
case "user-disconnected": {
|
|
221
225
|
const room = data.room;
|
|
222
226
|
const encodedState = data.storage;
|
|
223
227
|
const user = data.user;
|
|
224
|
-
yield Promise.resolve((
|
|
228
|
+
yield Promise.resolve((_g = this._listeners) == null ? void 0 : _g.onUserDisconnected({ context, encodedState, room, user }));
|
|
225
229
|
}
|
|
226
230
|
default:
|
|
227
231
|
return c.json({ data: { ok: true } }, 200);
|
|
228
232
|
}
|
|
229
233
|
}));
|
|
230
|
-
const { _defs, basePath, publicKey, secretKey, webhookSecret } = params;
|
|
234
|
+
const { _defs, context, basePath, publicKey, secretKey, webhookSecret } = params;
|
|
231
235
|
this._basePath = basePath;
|
|
236
|
+
this._context = typeof context === "function" ? context(this._roomContext) : context;
|
|
232
237
|
this._endpoints = __spreadValues({
|
|
233
238
|
createToken: "https://pluv.io/api/room/token"
|
|
234
239
|
}, _defs == null ? void 0 : _defs.endpoints);
|
|
235
240
|
this._publicKey = publicKey;
|
|
236
241
|
this._secretKey = secretKey;
|
|
237
242
|
this._webhookSecret = webhookSecret;
|
|
238
|
-
this.
|
|
243
|
+
this._app = new Hono().basePath(this._basePath).route("/", this._webhooksRouter);
|
|
244
|
+
this._fetch = this._app.fetch;
|
|
239
245
|
}
|
|
240
246
|
acceptWebSocket(webSocket) {
|
|
241
247
|
throw new Error("Not implemented");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/platform-pluv",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.5",
|
|
4
4
|
"description": "@pluv/io adapter for pluv.io",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"fast-json-stable-stringify": "^2.1.0",
|
|
22
22
|
"hono": "^4.7.4",
|
|
23
23
|
"zod": "^3.24.2",
|
|
24
|
-
"@pluv/crdt": "^0.38.
|
|
25
|
-
"@pluv/
|
|
26
|
-
"@pluv/
|
|
24
|
+
"@pluv/crdt": "^0.38.5",
|
|
25
|
+
"@pluv/types": "^0.38.5",
|
|
26
|
+
"@pluv/io": "^0.38.5"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"eslint": "^8.57.1",
|
|
30
30
|
"tsup": "^8.4.0",
|
|
31
31
|
"typescript": "^5.8.2",
|
|
32
|
-
"@pluv/tsconfig": "^0.38.
|
|
33
|
-
"eslint-config-pluv": "^0.38.
|
|
32
|
+
"@pluv/tsconfig": "^0.38.5",
|
|
33
|
+
"eslint-config-pluv": "^0.38.5"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
package/src/PluvPlatform.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AbstractPlatformConfig,
|
|
3
3
|
AbstractWebSocket,
|
|
4
|
+
BaseUser,
|
|
4
5
|
ConvertWebSocketConfig,
|
|
5
6
|
GetInitialStorageFn,
|
|
6
7
|
JWTEncodeParams,
|
|
@@ -8,13 +9,15 @@ import type {
|
|
|
8
9
|
} from "@pluv/io";
|
|
9
10
|
import { AbstractPlatform } from "@pluv/io";
|
|
10
11
|
import stringify from "fast-json-stable-stringify";
|
|
12
|
+
import type { Context } from "hono";
|
|
11
13
|
import { Hono } from "hono";
|
|
12
|
-
import {
|
|
14
|
+
import type { BlankEnv, BlankInput } from "hono/types";
|
|
15
|
+
import { SIGNATURE_ALGORITHM, SIGNATURE_HEADER } from "./constants";
|
|
13
16
|
import { ZodEvent } from "./schemas";
|
|
14
17
|
import { verifyWebhook } from "./shared";
|
|
15
18
|
import type { PluvIOEndpoints, PluvIOListeners } from "./types";
|
|
16
19
|
|
|
17
|
-
export interface PluvPlatformConfig {
|
|
20
|
+
export interface PluvPlatformConfig<TContext extends Record<string, any> = {}> {
|
|
18
21
|
/**
|
|
19
22
|
* @ignore
|
|
20
23
|
* @readonly
|
|
@@ -24,12 +27,16 @@ export interface PluvPlatformConfig {
|
|
|
24
27
|
endpoints?: PluvIOEndpoints;
|
|
25
28
|
};
|
|
26
29
|
basePath: string;
|
|
30
|
+
context?: TContext;
|
|
27
31
|
publicKey: string;
|
|
28
32
|
secretKey: string;
|
|
29
33
|
webhookSecret?: string;
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
export class PluvPlatform
|
|
36
|
+
export class PluvPlatform<
|
|
37
|
+
TContext extends Record<string, any> = {},
|
|
38
|
+
TUser extends BaseUser = BaseUser,
|
|
39
|
+
> extends AbstractPlatform<
|
|
33
40
|
any,
|
|
34
41
|
{},
|
|
35
42
|
{},
|
|
@@ -68,8 +75,10 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
68
75
|
};
|
|
69
76
|
public readonly _name = "platformPluv";
|
|
70
77
|
|
|
78
|
+
private readonly _app: Hono;
|
|
71
79
|
private _authorize: any;
|
|
72
80
|
private readonly _basePath: string;
|
|
81
|
+
private readonly _context: any;
|
|
73
82
|
private readonly _endpoints: PluvIOEndpoints;
|
|
74
83
|
private _getInitialStorage?: GetInitialStorageFn<{}>;
|
|
75
84
|
private _listeners?: PluvIOListeners;
|
|
@@ -106,9 +115,10 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
106
115
|
constructor(params: PluvPlatformConfig) {
|
|
107
116
|
super();
|
|
108
117
|
|
|
109
|
-
const { _defs, basePath, publicKey, secretKey, webhookSecret } = params;
|
|
118
|
+
const { _defs, context, basePath, publicKey, secretKey, webhookSecret } = params;
|
|
110
119
|
|
|
111
120
|
this._basePath = basePath;
|
|
121
|
+
this._context = typeof context === "function" ? context(this._roomContext) : context;
|
|
112
122
|
this._endpoints = {
|
|
113
123
|
createToken: "https://pluv.io/api/room/token",
|
|
114
124
|
..._defs?.endpoints,
|
|
@@ -117,9 +127,8 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
117
127
|
this._secretKey = secretKey;
|
|
118
128
|
this._webhookSecret = webhookSecret;
|
|
119
129
|
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
) => Promise<any>;
|
|
130
|
+
this._app = new Hono().basePath(this._basePath).route("/", this._webhooksRouter);
|
|
131
|
+
this._fetch = this._app.fetch as (req: any) => Promise<any>;
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
public acceptWebSocket(webSocket: AbstractWebSocket): Promise<void> {
|
|
@@ -182,10 +191,12 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
182
191
|
};
|
|
183
192
|
}
|
|
184
193
|
|
|
185
|
-
private
|
|
186
|
-
const signature = c.req.header(SIGNATURE_HEADER);
|
|
194
|
+
private _webhooksRouter = new Hono().basePath("/").post("/", async (c: Context<BlankEnv, "/", BlankInput>) => {
|
|
195
|
+
const [algorithm, signature] = c.req.header(SIGNATURE_HEADER)?.split("=") ?? [];
|
|
187
196
|
|
|
188
|
-
if (!this._webhookSecret
|
|
197
|
+
if (!this._webhookSecret) return c.json({ error: "Unauthorized" }, 401);
|
|
198
|
+
if (algorithm !== SIGNATURE_ALGORITHM) return c.json({ error: "Unauthorized" }, 401);
|
|
199
|
+
if (!signature) return c.json({ error: "Unauthorized" }, 401);
|
|
189
200
|
|
|
190
201
|
const payload = await c.req.json();
|
|
191
202
|
|
|
@@ -203,13 +214,13 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
203
214
|
|
|
204
215
|
const { event, data } = parsed.data;
|
|
205
216
|
|
|
217
|
+
const context = this._context;
|
|
218
|
+
|
|
206
219
|
switch (event) {
|
|
207
220
|
case "initial-storage": {
|
|
208
221
|
const room = data.room;
|
|
209
222
|
const storage =
|
|
210
|
-
typeof room === "string"
|
|
211
|
-
? ((await this._getInitialStorage?.({ context: {}, room })) ?? null)
|
|
212
|
-
: null;
|
|
223
|
+
typeof room === "string" ? ((await this._getInitialStorage?.({ context, room })) ?? null) : null;
|
|
213
224
|
|
|
214
225
|
return c.json({ data: { storage } }, 200);
|
|
215
226
|
}
|
|
@@ -217,7 +228,7 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
217
228
|
const room = data.room;
|
|
218
229
|
const encodedState = data.storage;
|
|
219
230
|
|
|
220
|
-
await Promise.resolve(this._listeners?.onRoomDeleted({ encodedState, room }));
|
|
231
|
+
await Promise.resolve(this._listeners?.onRoomDeleted({ context, encodedState, room }));
|
|
221
232
|
|
|
222
233
|
return c.json({ data: { room } }, 200);
|
|
223
234
|
}
|
|
@@ -226,14 +237,14 @@ export class PluvPlatform extends AbstractPlatform<
|
|
|
226
237
|
const encodedState = data.storage;
|
|
227
238
|
const user = data.user as any;
|
|
228
239
|
|
|
229
|
-
await Promise.resolve(this._listeners?.onUserConnected({ encodedState, room, user }));
|
|
240
|
+
await Promise.resolve(this._listeners?.onUserConnected({ context, encodedState, room, user }));
|
|
230
241
|
}
|
|
231
242
|
case "user-disconnected": {
|
|
232
243
|
const room = data.room;
|
|
233
244
|
const encodedState = data.storage;
|
|
234
245
|
const user = data.user as any;
|
|
235
246
|
|
|
236
|
-
await Promise.resolve(this._listeners?.onUserDisconnected({ encodedState, room, user }));
|
|
247
|
+
await Promise.resolve(this._listeners?.onUserDisconnected({ context, encodedState, room, user }));
|
|
237
248
|
}
|
|
238
249
|
default:
|
|
239
250
|
return c.json({ data: { ok: true } }, 200);
|
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
export { platformPluv } from "./platformPluv";
|
|
2
2
|
export type { PlatformPluvCreateIOParams } from "./platformPluv";
|
|
3
3
|
export { PluvPlatform } from "./PluvPlatform";
|
|
4
|
-
export type {
|
|
5
|
-
PluvIOEndpoints,
|
|
6
|
-
RoomDeletedMessageEventData,
|
|
7
|
-
UserConnectedEventData,
|
|
8
|
-
UserDisconnectedEventData,
|
|
9
|
-
} from "./types";
|
|
4
|
+
export type { PluvIOEndpoints } from "./types";
|
package/src/platformPluv.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type PlatformPluvCreateIOParams<
|
|
|
16
16
|
|
|
17
17
|
export const platformPluv = <TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser>(
|
|
18
18
|
config: PlatformPluvCreateIOParams<TContext, TUser>,
|
|
19
|
-
): CreateIOParams<PluvPlatform, TContext, TUser> => {
|
|
19
|
+
): CreateIOParams<PluvPlatform<TContext, TUser>, TContext, TUser> => {
|
|
20
20
|
const { authorize, context, crdt, debug } = config;
|
|
21
21
|
|
|
22
22
|
return {
|
|
@@ -24,6 +24,6 @@ export const platformPluv = <TContext extends Record<string, any> = {}, TUser ex
|
|
|
24
24
|
context,
|
|
25
25
|
crdt,
|
|
26
26
|
debug,
|
|
27
|
-
platform: new PluvPlatform(config),
|
|
27
|
+
platform: new PluvPlatform<TContext, TUser>(config),
|
|
28
28
|
};
|
|
29
29
|
};
|
package/src/types.ts
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BaseUser,
|
|
3
|
+
GetInitialStorageFn,
|
|
4
|
+
IORoomListenerEvent,
|
|
5
|
+
IOUserConnectedEvent,
|
|
6
|
+
IOUserDisconnectedEvent,
|
|
7
|
+
} from "@pluv/io";
|
|
8
|
+
import type { InputZodLike } from "@pluv/types";
|
|
9
|
+
import type { PluvPlatform } from "./PluvPlatform";
|
|
2
10
|
|
|
3
11
|
export interface PluvIOEndpoints {
|
|
4
12
|
createToken: string;
|
|
5
13
|
}
|
|
6
14
|
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export type UserDisconnectedEventData = {
|
|
19
|
-
encodedState: string | null;
|
|
20
|
-
room: string;
|
|
21
|
-
user: any;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type PluvIOListeners = {
|
|
25
|
-
getInitialStorage?: GetInitialStorageFn<{}>;
|
|
26
|
-
onRoomDeleted: (event: RoomDeletedMessageEventData) => void;
|
|
27
|
-
onUserConnected: (event: UserConnectedEventData) => void;
|
|
28
|
-
onUserDisconnected: (event: UserDisconnectedEventData) => void;
|
|
15
|
+
export type PluvIOListeners<TContext extends Record<string, any> = {}, TUser extends BaseUser = BaseUser> = {
|
|
16
|
+
getInitialStorage?: GetInitialStorageFn<TContext>;
|
|
17
|
+
onRoomDeleted: (event: IORoomListenerEvent<TContext>) => void;
|
|
18
|
+
onUserConnected: (
|
|
19
|
+
event: IOUserConnectedEvent<PluvPlatform<TContext>, { user: InputZodLike<TUser> }, TContext>,
|
|
20
|
+
) => void;
|
|
21
|
+
onUserDisconnected: (
|
|
22
|
+
event: IOUserDisconnectedEvent<PluvPlatform<TContext>, { user: InputZodLike<TUser> }, TContext>,
|
|
23
|
+
) => void;
|
|
29
24
|
};
|