@pluv/platform-pluv 2.2.8 → 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.8 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
- ESM dist/index.mjs 13.11 KB
12
- ESM ⚡️ Build success in 80ms
13
- CJS dist/index.js 14.95 KB
14
- CJS ⚡️ Build success in 81ms
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 6513ms
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,17 @@
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
+
3
15
  ## 2.2.8
4
16
 
5
17
  ### 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);
@@ -390,12 +443,15 @@ var PluvPlatform = class extends import_io.AbstractPlatform {
390
443
  validateConfig(config) {
391
444
  this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
392
445
  if (!config.authorize) {
446
+ this._logDebug("Config `authorize` must be provided to `platformPluv`");
393
447
  throw new Error("Config `authorize` must be provided to `platformPluv`");
394
448
  }
395
449
  if (!!config.onRoomMessage) {
450
+ this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
396
451
  throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
397
452
  }
398
453
  if (!!config.onStorageUpdated) {
454
+ this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
399
455
  throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
400
456
  }
401
457
  this._getInitialStorage = config.getInitialStorage;
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);
@@ -360,12 +413,15 @@ var PluvPlatform = class extends AbstractPlatform {
360
413
  validateConfig(config) {
361
414
  this._logDebug("validating config with properties:", Object.keys(config != null ? config : {}));
362
415
  if (!config.authorize) {
416
+ this._logDebug("Config `authorize` must be provided to `platformPluv`");
363
417
  throw new Error("Config `authorize` must be provided to `platformPluv`");
364
418
  }
365
419
  if (!!config.onRoomMessage) {
420
+ this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
366
421
  throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
367
422
  }
368
423
  if (!!config.onStorageUpdated) {
424
+ this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
369
425
  throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
370
426
  }
371
427
  this._getInitialStorage = config.getInitialStorage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/platform-pluv",
3
- "version": "2.2.8",
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.8",
25
- "@pluv/io": "^2.2.8",
26
- "@pluv/types": "^2.2.8"
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.8",
33
- "eslint-config-pluv": "^2.2.8"
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",
@@ -202,12 +202,15 @@ export class PluvPlatform<
202
202
  this._logDebug("validating config with properties:", Object.keys(config ?? {}));
203
203
 
204
204
  if (!config.authorize) {
205
+ this._logDebug("Config `authorize` must be provided to `platformPluv`");
205
206
  throw new Error("Config `authorize` must be provided to `platformPluv`");
206
207
  }
207
208
  if (!!config.onRoomMessage) {
209
+ this._logDebug("Config `onRoomMessage` is not supported on `platformPluv`");
208
210
  throw new Error("Config `onRoomMessage` is not supported on `platformPluv`");
209
211
  }
210
212
  if (!!config.onStorageUpdated) {
213
+ this._logDebug("Config `onStorageUpdated` is not supported on `platformPluv`");
211
214
  throw new Error("Config `onStorageUpdated` is not supported on `platformPluv`");
212
215
  }
213
216
 
@@ -225,28 +228,62 @@ export class PluvPlatform<
225
228
  const [algorithm, signature] = c.req.header(SIGNATURE_HEADER)?.split("=") ?? [];
226
229
 
227
230
  try {
228
- if (!this._webhookSecret) throw new HttpError("Unauthorized", 401);
229
- if (algorithm !== SIGNATURE_ALGORITHM) throw new HttpError("Unauthorized", 401);
230
- 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
+ }
231
246
 
232
247
  const [payload, webhookSecret] = await Promise.all([
233
248
  c.req.json(),
234
249
  typeof this._webhookSecret === "string"
235
250
  ? this._webhookSecret
236
251
  : await this._webhookSecret(),
237
- ]);
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
+ });
238
259
 
239
260
  const verified = await verifyWebhook({
240
261
  payload: stringify(payload),
241
262
  signature,
242
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;
243
271
  });
244
272
 
245
- if (!verified) throw new HttpError("Unauthorized", 401);
273
+ if (!verified) {
274
+ this._logDebug("Failed to verify webhook");
275
+ throw new HttpError("Unauthorized", 401);
276
+ }
246
277
 
247
278
  const parsed = ZodEvent.safeParse(payload);
248
279
 
249
- 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
+ }
250
287
 
251
288
  const { event, data } = parsed.data;
252
289
  const context = this._getContext();
@@ -259,7 +296,12 @@ export class PluvPlatform<
259
296
  ? ((await this._getInitialStorage?.({ context, room })) ?? null)
260
297
  : null;
261
298
 
262
- 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
+ }
263
305
  }
264
306
  case "room-deleted": {
265
307
  const room = data.room;
@@ -269,7 +311,12 @@ export class PluvPlatform<
269
311
  this._listeners?.onRoomDeleted({ context, encodedState, room }),
270
312
  );
271
313
 
272
- 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
+ }
273
320
  }
274
321
  case "user-connected": {
275
322
  const room = data.room;
@@ -286,7 +333,12 @@ export class PluvPlatform<
286
333
  }),
287
334
  );
288
335
 
289
- 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
+ }
290
342
  }
291
343
  case "user-disconnected": {
292
344
  const room = data.room;
@@ -303,7 +355,12 @@ export class PluvPlatform<
303
355
  }),
304
356
  );
305
357
 
306
- 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
+ }
307
364
  }
308
365
  default: {
309
366
  throw new HttpError("Unknown event", 400);