@pluv/platform-pluv 2.2.7 → 2.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @pluv/platform-pluv@2.2.7 build /home/runner/work/pluv/pluv/packages/platform-pluv
2
+ > @pluv/platform-pluv@2.3.0 build /home/runner/work/pluv/pluv/packages/platform-pluv
3
3
  > tsup src/index.ts --format esm,cjs --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,11 +8,11 @@
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- CJS dist/index.js 14.82 KB
12
- CJS ⚡️ Build success in 137ms
13
- ESM dist/index.mjs 12.99 KB
14
- ESM ⚡️ Build success in 141ms
11
+ CJS dist/index.js 16.82 KB
12
+ CJS ⚡️ Build success in 64ms
13
+ ESM dist/index.mjs 14.98 KB
14
+ ESM ⚡️ Build success in 65ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 7116ms
16
+ DTS ⚡️ Build success in 6964ms
17
17
  DTS dist/index.d.mts 3.79 KB
18
18
  DTS dist/index.d.ts 3.79 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @pluv/platform-pluv
2
2
 
3
+ ## 2.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e48e5d8: Added webhook debug logging.
8
+
9
+ ### Patch Changes
10
+
11
+ - @pluv/crdt@2.3.0
12
+ - @pluv/io@2.3.0
13
+ - @pluv/types@2.3.0
14
+
15
+ ## 2.2.8
16
+
17
+ ### Patch Changes
18
+
19
+ - b60ccd8: Fix `PluvServer` fetch config validation.
20
+ - Updated dependencies [b60ccd8]
21
+ - @pluv/io@2.2.8
22
+ - @pluv/crdt@2.2.8
23
+ - @pluv/types@2.2.8
24
+
3
25
  ## 2.2.7
4
26
 
5
27
  ### Patch Changes
package/dist/index.js CHANGED
@@ -270,46 +270,89 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
270
270
  return token;
271
271
  });
272
272
  this._webhooksRouter = new import_hono.Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
273
- var _a, _b, _c, _d, _e, _f, _g;
273
+ var _a, _b, _c, _d, _e, _f, _g, _h;
274
274
  const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
275
275
  try {
276
- if (!this._webhookSecret) throw new HttpError("Unauthorized", 401);
277
- if (algorithm !== SIGNATURE_ALGORITHM) throw new HttpError("Unauthorized", 401);
278
- if (!signature) throw new HttpError("Unauthorized", 401);
276
+ if (!this._webhookSecret) {
277
+ this._logDebug("Missing webhook secret");
278
+ throw new HttpError("Unauthorized", 401);
279
+ }
280
+ if (algorithm !== SIGNATURE_ALGORITHM) {
281
+ this._logDebug(
282
+ `Verification algorithm is not ${SIGNATURE_ALGORITHM}. Found: `,
283
+ algorithm
284
+ );
285
+ throw new HttpError("Unauthorized", 401);
286
+ }
287
+ if (!signature) {
288
+ this._logDebug("Missing webhook signature");
289
+ throw new HttpError("Unauthorized", 401);
290
+ }
279
291
  const [payload, webhookSecret] = yield Promise.all([
280
292
  c.req.json(),
281
293
  typeof this._webhookSecret === "string" ? this._webhookSecret : yield this._webhookSecret()
282
- ]);
294
+ ]).catch((error) => {
295
+ this._logDebug(
296
+ "Could not derive webhook secret: ",
297
+ error instanceof Error ? error.message : "Unexpected error"
298
+ );
299
+ throw error;
300
+ });
283
301
  const verified = yield verifyWebhook({
284
302
  payload: (0, import_fast_json_stable_stringify.default)(payload),
285
303
  signature,
286
304
  secret: webhookSecret
305
+ }).catch((error) => {
306
+ this._logDebug(
307
+ "Error while verifying webhook: ",
308
+ error instanceof Error ? error.message : "Unexpected error"
309
+ );
310
+ return false;
287
311
  });
288
- if (!verified) throw new HttpError("Unauthorized", 401);
312
+ if (!verified) {
313
+ this._logDebug("Failed to verify webhook");
314
+ throw new HttpError("Unauthorized", 401);
315
+ }
289
316
  const parsed = ZodEvent.safeParse(payload);
290
- if (!parsed.success) throw new HttpError("Invalid request", 400);
317
+ if (!parsed.success) {
318
+ this._logDebug(
319
+ "Failed to validate event payload:",
320
+ JSON.stringify((_c = parsed.data) != null ? _c : {}, null, 4)
321
+ );
322
+ throw new HttpError("Invalid request", 400);
323
+ }
291
324
  const { event, data } = parsed.data;
292
325
  const context = this._getContext();
293
326
  switch (event) {
294
327
  case "initial-storage": {
295
328
  const room = data.room;
296
- const storage = typeof room === "string" ? (_d = yield (_c = this._getInitialStorage) == null ? void 0 : _c.call(this, { context, room })) != null ? _d : null : null;
297
- return createSuccessResponse(c, { event, room, storage });
329
+ const storage = typeof room === "string" ? (_e = yield (_d = this._getInitialStorage) == null ? void 0 : _d.call(this, { context, room })) != null ? _e : null : null;
330
+ try {
331
+ return createSuccessResponse(c, { event, room, storage });
332
+ } catch (error) {
333
+ this._logDebug("Could not create getInitialStorage response");
334
+ throw error;
335
+ }
298
336
  }
299
337
  case "room-deleted": {
300
338
  const room = data.room;
301
339
  const encodedState = data.storage;
302
340
  yield Promise.resolve(
303
- (_e = this._listeners) == null ? void 0 : _e.onRoomDeleted({ context, encodedState, room })
341
+ (_f = this._listeners) == null ? void 0 : _f.onRoomDeleted({ context, encodedState, room })
304
342
  );
305
- return createSuccessResponse(c, { event, room });
343
+ try {
344
+ return createSuccessResponse(c, { event, room });
345
+ } catch (error) {
346
+ this._logDebug("Could not create onRoomDeleted response");
347
+ throw error;
348
+ }
306
349
  }
307
350
  case "user-connected": {
308
351
  const room = data.room;
309
352
  const encodedState = data.storage;
310
353
  const user = data.user;
311
354
  yield Promise.resolve(
312
- (_f = this._listeners) == null ? void 0 : _f.onUserConnected({
355
+ (_g = this._listeners) == null ? void 0 : _g.onUserConnected({
313
356
  context,
314
357
  encodedState,
315
358
  platform: this,
@@ -317,14 +360,19 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
317
360
  user
318
361
  })
319
362
  );
320
- return createSuccessResponse(c, { event, room });
363
+ try {
364
+ return createSuccessResponse(c, { event, room });
365
+ } catch (error) {
366
+ this._logDebug("Could not create onUserConnected response");
367
+ throw error;
368
+ }
321
369
  }
322
370
  case "user-disconnected": {
323
371
  const room = data.room;
324
372
  const encodedState = data.storage;
325
373
  const user = data.user;
326
374
  yield Promise.resolve(
327
- (_g = this._listeners) == null ? void 0 : _g.onUserDisconnected({
375
+ (_h = this._listeners) == null ? void 0 : _h.onUserDisconnected({
328
376
  context,
329
377
  encodedState,
330
378
  platform: this,
@@ -332,7 +380,12 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
332
380
  user
333
381
  })
334
382
  );
335
- return createSuccessResponse(c, { event, room });
383
+ try {
384
+ return createSuccessResponse(c, { event, room });
385
+ } catch (error) {
386
+ this._logDebug("Could not create onUserDisconnected response");
387
+ throw error;
388
+ }
336
389
  }
337
390
  default: {
338
391
  throw new HttpError("Unknown event", 400);
@@ -388,12 +441,19 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
388
441
  throw new Error("Not implemented");
389
442
  }
390
443
  validateConfig(config) {
391
- if (!config.authorize)
444
+ this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
445
+ if (!config.authorize) {
446
+ this._logDebug("Config `authorize` must be provided to `platformPluv`");
392
447
  throw new Error("Config `authorize` must be provided to `platformPluv`");
393
- if (!!config.onRoomMessage)
448
+ }
449
+ if (!!config.onRoomMessage) {
450
+ this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
394
451
  throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
395
- if (!!config.onStorageUpdated)
452
+ }
453
+ if (!!config.onStorageUpdated) {
454
+ this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
396
455
  throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
456
+ }
397
457
  this._getInitialStorage = config.getInitialStorage;
398
458
  this._listeners = {
399
459
  onRoomDeleted: (event) => {
package/dist/index.mjs CHANGED
@@ -240,46 +240,89 @@ var PluvPlatform = class extends AbstractPlatform {
240
240
  return token;
241
241
  });
242
242
  this._webhooksRouter = new Hono().basePath("/").post("/", (c) => __async(this, null, function* () {
243
- var _a, _b, _c, _d, _e, _f, _g;
243
+ var _a, _b, _c, _d, _e, _f, _g, _h;
244
244
  const [algorithm, signature] = (_b = (_a = c.req.header(SIGNATURE_HEADER)) == null ? void 0 : _a.split("=")) != null ? _b : [];
245
245
  try {
246
- if (!this._webhookSecret) throw new HttpError("Unauthorized", 401);
247
- if (algorithm !== SIGNATURE_ALGORITHM) throw new HttpError("Unauthorized", 401);
248
- if (!signature) throw new HttpError("Unauthorized", 401);
246
+ if (!this._webhookSecret) {
247
+ this._logDebug("Missing webhook secret");
248
+ throw new HttpError("Unauthorized", 401);
249
+ }
250
+ if (algorithm !== SIGNATURE_ALGORITHM) {
251
+ this._logDebug(
252
+ `Verification algorithm is not ${SIGNATURE_ALGORITHM}. Found: `,
253
+ algorithm
254
+ );
255
+ throw new HttpError("Unauthorized", 401);
256
+ }
257
+ if (!signature) {
258
+ this._logDebug("Missing webhook signature");
259
+ throw new HttpError("Unauthorized", 401);
260
+ }
249
261
  const [payload, webhookSecret] = yield Promise.all([
250
262
  c.req.json(),
251
263
  typeof this._webhookSecret === "string" ? this._webhookSecret : yield this._webhookSecret()
252
- ]);
264
+ ]).catch((error) => {
265
+ this._logDebug(
266
+ "Could not derive webhook secret: ",
267
+ error instanceof Error ? error.message : "Unexpected error"
268
+ );
269
+ throw error;
270
+ });
253
271
  const verified = yield verifyWebhook({
254
272
  payload: stringify(payload),
255
273
  signature,
256
274
  secret: webhookSecret
275
+ }).catch((error) => {
276
+ this._logDebug(
277
+ "Error while verifying webhook: ",
278
+ error instanceof Error ? error.message : "Unexpected error"
279
+ );
280
+ return false;
257
281
  });
258
- if (!verified) throw new HttpError("Unauthorized", 401);
282
+ if (!verified) {
283
+ this._logDebug("Failed to verify webhook");
284
+ throw new HttpError("Unauthorized", 401);
285
+ }
259
286
  const parsed = ZodEvent.safeParse(payload);
260
- if (!parsed.success) throw new HttpError("Invalid request", 400);
287
+ if (!parsed.success) {
288
+ this._logDebug(
289
+ "Failed to validate event payload:",
290
+ JSON.stringify((_c = parsed.data) != null ? _c : {}, null, 4)
291
+ );
292
+ throw new HttpError("Invalid request", 400);
293
+ }
261
294
  const { event, data } = parsed.data;
262
295
  const context = this._getContext();
263
296
  switch (event) {
264
297
  case "initial-storage": {
265
298
  const room = data.room;
266
- const storage = typeof room === "string" ? (_d = yield (_c = this._getInitialStorage) == null ? void 0 : _c.call(this, { context, room })) != null ? _d : null : null;
267
- return createSuccessResponse(c, { event, room, storage });
299
+ const storage = typeof room === "string" ? (_e = yield (_d = this._getInitialStorage) == null ? void 0 : _d.call(this, { context, room })) != null ? _e : null : null;
300
+ try {
301
+ return createSuccessResponse(c, { event, room, storage });
302
+ } catch (error) {
303
+ this._logDebug("Could not create getInitialStorage response");
304
+ throw error;
305
+ }
268
306
  }
269
307
  case "room-deleted": {
270
308
  const room = data.room;
271
309
  const encodedState = data.storage;
272
310
  yield Promise.resolve(
273
- (_e = this._listeners) == null ? void 0 : _e.onRoomDeleted({ context, encodedState, room })
311
+ (_f = this._listeners) == null ? void 0 : _f.onRoomDeleted({ context, encodedState, room })
274
312
  );
275
- return createSuccessResponse(c, { event, room });
313
+ try {
314
+ return createSuccessResponse(c, { event, room });
315
+ } catch (error) {
316
+ this._logDebug("Could not create onRoomDeleted response");
317
+ throw error;
318
+ }
276
319
  }
277
320
  case "user-connected": {
278
321
  const room = data.room;
279
322
  const encodedState = data.storage;
280
323
  const user = data.user;
281
324
  yield Promise.resolve(
282
- (_f = this._listeners) == null ? void 0 : _f.onUserConnected({
325
+ (_g = this._listeners) == null ? void 0 : _g.onUserConnected({
283
326
  context,
284
327
  encodedState,
285
328
  platform: this,
@@ -287,14 +330,19 @@ var PluvPlatform = class extends AbstractPlatform {
287
330
  user
288
331
  })
289
332
  );
290
- return createSuccessResponse(c, { event, room });
333
+ try {
334
+ return createSuccessResponse(c, { event, room });
335
+ } catch (error) {
336
+ this._logDebug("Could not create onUserConnected response");
337
+ throw error;
338
+ }
291
339
  }
292
340
  case "user-disconnected": {
293
341
  const room = data.room;
294
342
  const encodedState = data.storage;
295
343
  const user = data.user;
296
344
  yield Promise.resolve(
297
- (_g = this._listeners) == null ? void 0 : _g.onUserDisconnected({
345
+ (_h = this._listeners) == null ? void 0 : _h.onUserDisconnected({
298
346
  context,
299
347
  encodedState,
300
348
  platform: this,
@@ -302,7 +350,12 @@ var PluvPlatform = class extends AbstractPlatform {
302
350
  user
303
351
  })
304
352
  );
305
- return createSuccessResponse(c, { event, room });
353
+ try {
354
+ return createSuccessResponse(c, { event, room });
355
+ } catch (error) {
356
+ this._logDebug("Could not create onUserDisconnected response");
357
+ throw error;
358
+ }
306
359
  }
307
360
  default: {
308
361
  throw new HttpError("Unknown event", 400);
@@ -358,12 +411,19 @@ var PluvPlatform = class extends AbstractPlatform {
358
411
  throw new Error("Not implemented");
359
412
  }
360
413
  validateConfig(config) {
361
- if (!config.authorize)
414
+ this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
415
+ if (!config.authorize) {
416
+ this._logDebug("Config `authorize` must be provided to `platformPluv`");
362
417
  throw new Error("Config `authorize` must be provided to `platformPluv`");
363
- if (!!config.onRoomMessage)
418
+ }
419
+ if (!!config.onRoomMessage) {
420
+ this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
364
421
  throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
365
- if (!!config.onStorageUpdated)
422
+ }
423
+ if (!!config.onStorageUpdated) {
424
+ this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
366
425
  throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
426
+ }
367
427
  this._getInitialStorage = config.getInitialStorage;
368
428
  this._listeners = {
369
429
  onRoomDeleted: (event) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/platform-pluv",
3
- "version": "2.2.7",
3
+ "version": "2.3.0",
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.10",
23
23
  "zod": "^3.25.17",
24
- "@pluv/crdt": "^2.2.7",
25
- "@pluv/io": "^2.2.7",
26
- "@pluv/types": "^2.2.7"
24
+ "@pluv/types": "^2.3.0",
25
+ "@pluv/crdt": "^2.3.0",
26
+ "@pluv/io": "^2.3.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "eslint": "^9.27.0",
30
30
  "tsup": "^8.5.0",
31
31
  "typescript": "^5.8.3",
32
- "@pluv/tsconfig": "^2.2.7",
33
- "eslint-config-pluv": "^2.2.7"
32
+ "@pluv/tsconfig": "^2.3.0",
33
+ "eslint-config-pluv": "^2.3.0"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsup src/index.ts --format esm,cjs --dts",
@@ -199,12 +199,20 @@ export class PluvPlatform<
199
199
  }
200
200
 
201
201
  public validateConfig(config: any): void {
202
- if (!config.authorize)
202
+ this._logDebug("validating config with properties:", Object.keys(config ?? {}));
203
+
204
+ if (!config.authorize) {
205
+ this._logDebug("Config `authorize` must be provided to `platformPluv`");
203
206
  throw new Error("Config `authorize` must be provided to `platformPluv`");
204
- if (!!config.onRoomMessage)
207
+ }
208
+ if (!!config.onRoomMessage) {
209
+ this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
205
210
  throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
206
- if (!!config.onStorageUpdated)
211
+ }
212
+ if (!!config.onStorageUpdated) {
213
+ this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
207
214
  throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
215
+ }
208
216
 
209
217
  this._getInitialStorage = config.getInitialStorage;
210
218
  this._listeners = {
@@ -220,28 +228,62 @@ export class PluvPlatform<
220
228
  const [algorithm, signature] = c.req.header(SIGNATURE_HEADER)?.split("=") ?? [];
221
229
 
222
230
  try {
223
- if (!this._webhookSecret) throw new HttpError("Unauthorized", 401);
224
- if (algorithm !== SIGNATURE_ALGORITHM) throw new HttpError("Unauthorized", 401);
225
- if (!signature) throw new HttpError("Unauthorized", 401);
231
+ if (!this._webhookSecret) {
232
+ this._logDebug("Missing webhook secret");
233
+ throw new HttpError("Unauthorized", 401);
234
+ }
235
+ if (algorithm !== SIGNATURE_ALGORITHM) {
236
+ this._logDebug(
237
+ `Verification algorithm is not ${SIGNATURE_ALGORITHM}. Found: `,
238
+ algorithm,
239
+ );
240
+ throw new HttpError("Unauthorized", 401);
241
+ }
242
+ if (!signature) {
243
+ this._logDebug("Missing webhook signature");
244
+ throw new HttpError("Unauthorized", 401);
245
+ }
226
246
 
227
247
  const [payload, webhookSecret] = await Promise.all([
228
248
  c.req.json(),
229
249
  typeof this._webhookSecret === "string"
230
250
  ? this._webhookSecret
231
251
  : await this._webhookSecret(),
232
- ]);
252
+ ]).catch((error) => {
253
+ this._logDebug(
254
+ "Could not derive webhook secret: ",
255
+ error instanceof Error ? error.message : "Unexpected error",
256
+ );
257
+ throw error;
258
+ });
233
259
 
234
260
  const verified = await verifyWebhook({
235
261
  payload: stringify(payload),
236
262
  signature,
237
263
  secret: webhookSecret,
264
+ }).catch((error) => {
265
+ this._logDebug(
266
+ "Error while verifying webhook: ",
267
+ error instanceof Error ? error.message : "Unexpected error",
268
+ );
269
+
270
+ return false;
238
271
  });
239
272
 
240
- if (!verified) throw new HttpError("Unauthorized", 401);
273
+ if (!verified) {
274
+ this._logDebug("Failed to verify webhook");
275
+ throw new HttpError("Unauthorized", 401);
276
+ }
241
277
 
242
278
  const parsed = ZodEvent.safeParse(payload);
243
279
 
244
- if (!parsed.success) throw new HttpError("Invalid request", 400);
280
+ if (!parsed.success) {
281
+ this._logDebug(
282
+ "Failed to validate event payload:",
283
+ JSON.stringify(parsed.data ?? {}, null, 4),
284
+ );
285
+ throw new HttpError("Invalid request", 400);
286
+ }
245
287
 
246
288
  const { event, data } = parsed.data;
247
289
  const context = this._getContext();
@@ -254,7 +296,12 @@ export class PluvPlatform<
254
296
  ? ((await this._getInitialStorage?.({ context, room })) ?? null)
255
297
  : null;
256
298
 
257
- return createSuccessResponse(c, { event, room, storage });
299
+ try {
300
+ return createSuccessResponse(c, { event, room, storage });
301
+ } catch (error) {
302
+ this._logDebug("Could not create getInitialStorage response");
303
+ throw error;
304
+ }
258
305
  }
259
306
  case "room-deleted": {
260
307
  const room = data.room;
@@ -264,7 +311,12 @@ export class PluvPlatform<
264
311
  this._listeners?.onRoomDeleted({ context, encodedState, room }),
265
312
  );
266
313
 
267
- return createSuccessResponse(c, { event, room });
314
+ try {
315
+ return createSuccessResponse(c, { event, room });
316
+ } catch (error) {
317
+ this._logDebug("Could not create onRoomDeleted response");
318
+ throw error;
319
+ }
268
320
  }
269
321
  case "user-connected": {
270
322
  const room = data.room;
@@ -281,7 +333,12 @@ export class PluvPlatform<
281
333
  }),
282
334
  );
283
335
 
284
- return createSuccessResponse(c, { event, room });
336
+ try {
337
+ return createSuccessResponse(c, { event, room });
338
+ } catch (error) {
339
+ this._logDebug("Could not create onUserConnected response");
340
+ throw error;
341
+ }
285
342
  }
286
343
  case "user-disconnected": {
287
344
  const room = data.room;
@@ -298,7 +355,12 @@ export class PluvPlatform<
298
355
  }),
299
356
  );
300
357
 
301
- return createSuccessResponse(c, { event, room });
358
+ try {
359
+ return createSuccessResponse(c, { event, room });
360
+ } catch (error) {
361
+ this._logDebug("Could not create onUserDisconnected response");
362
+ throw error;
363
+ }
302
364
  }
303
365
  default: {
304
366
  throw new HttpError("Unknown event", 400);