@replayio-app-building/netlify-recorder 0.41.0 → 0.43.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/dist/index.d.ts CHANGED
@@ -72,6 +72,10 @@ interface NetworkCall {
72
72
  responseHeaders: Record<string, string>;
73
73
  responseBody?: string;
74
74
  timestamp: number;
75
+ /** Epoch ms when the fetch call started. */
76
+ startTime: number;
77
+ /** Epoch ms when the response was received. */
78
+ endTime: number;
75
79
  }
76
80
  interface EnvRead {
77
81
  key: string;
@@ -344,9 +348,8 @@ interface RecordingEndpointResponse {
344
348
  error?: string;
345
349
  }
346
350
  /**
347
- * Payload sent by the recorder service when a recording completes or fails.
348
- * Used for both the PUT callback to this endpoint and the downstream
349
- * notification to the user-configured `webhookUrl`.
351
+ * Payload the recorder service POSTs when a recording completes or fails.
352
+ * Also the shape forwarded to the user-configured `webhookUrl`.
350
353
  */
351
354
  interface RecordingWebhookPayload {
352
355
  requestId: string;
@@ -362,13 +365,15 @@ interface RecordingWebhookPayload {
362
365
  *
363
366
  * **GET** `?requestId=<uuid>` — returns the current recording status.
364
367
  *
365
- * **POST** `{ "requestId": "<uuid>" }` triggers recording creation if needed.
366
- * Idempotent: re-posting the same request ID will not re-queue.
368
+ * **POST** two contracts distinguished by body shape:
369
+ *
370
+ * *Trigger:* `{ "requestId": "<uuid>" }` — triggers recording creation if
371
+ * needed. Idempotent: re-posting won't re-queue.
367
372
  *
368
- * **PUT** `RecordingWebhookPayload` — webhook callback from the recorder
369
- * service when a recording completes or fails. Body must include
370
- * `requestId`, `status` (`"recorded"` | `"failed"`), and either
371
- * `recordingId` or `error`.
373
+ * *Callback:* `RecordingWebhookPayload` — sent by the recorder service when
374
+ * a recording completes or fails. Body must include `requestId` and `status`
375
+ * (`"recorded"` | `"failed"`). The presence of `status` distinguishes a
376
+ * callback from a trigger.
372
377
  *
373
378
  * When `secret` is provided, every request must include an
374
379
  * `Authorization: Bearer <secret>` header or receive a 401 response.
package/dist/index.js CHANGED
@@ -87,7 +87,9 @@ function ensureCaptureInterceptor() {
87
87
  calls
88
88
  );
89
89
  }
90
+ const startTime = Date.now();
90
91
  const response = await _realOriginalFetch(input, init);
92
+ const endTime = Date.now();
91
93
  const responseBody = await response.clone().text();
92
94
  const responseHeaders = {};
93
95
  response.headers.forEach((v, k) => {
@@ -101,7 +103,9 @@ function ensureCaptureInterceptor() {
101
103
  responseStatus: response.status,
102
104
  responseHeaders,
103
105
  responseBody,
104
- timestamp: Date.now()
106
+ timestamp: endTime,
107
+ startTime,
108
+ endTime
105
109
  });
106
110
  return response;
107
111
  };
@@ -154,7 +158,9 @@ function installNetworkInterceptor(mode, calls) {
154
158
  calls
155
159
  );
156
160
  }
161
+ const startTime = Date.now();
157
162
  const response = await originalFetch2(input, init);
163
+ const endTime = Date.now();
158
164
  const responseBody = await response.clone().text();
159
165
  const responseHeaders = {};
160
166
  response.headers.forEach((v, k) => {
@@ -168,7 +174,9 @@ function installNetworkInterceptor(mode, calls) {
168
174
  responseStatus: response.status,
169
175
  responseHeaders,
170
176
  responseBody,
171
- timestamp: Date.now()
177
+ timestamp: endTime,
178
+ startTime,
179
+ endTime
172
180
  });
173
181
  return response;
174
182
  };
@@ -280,7 +288,9 @@ async function handleNeonSqlRequest(originalFetch, input, init, url, method, req
280
288
  ...init,
281
289
  body: JSON.stringify({ queries: txBody })
282
290
  };
291
+ const startTime = Date.now();
283
292
  const response = await originalFetch(input, modifiedInit);
293
+ const endTime = Date.now();
284
294
  const rawBody = await response.clone().text();
285
295
  const responseHeaders = {};
286
296
  response.headers.forEach((v, k) => {
@@ -306,7 +316,9 @@ async function handleNeonSqlRequest(originalFetch, input, init, url, method, req
306
316
  responseStatus: response.status,
307
317
  responseHeaders,
308
318
  responseBody: recordedBody,
309
- timestamp: Date.now()
319
+ timestamp: endTime,
320
+ startTime,
321
+ endTime
310
322
  });
311
323
  return new Response(recordedBody, {
312
324
  status: response.status,
@@ -1559,10 +1571,6 @@ function createRecordingEndpoint(options) {
1559
1571
  }
1560
1572
  return jsonResponse(formatStatus(request), 200);
1561
1573
  }
1562
- if (req.method === "PUT") {
1563
- const body = await req.json();
1564
- return handleCallback(body);
1565
- }
1566
1574
  if (req.method === "POST") {
1567
1575
  const body = await req.json();
1568
1576
  if (body.status) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@replayio-app-building/netlify-recorder",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "description": "Capture and replay Netlify function executions as Replay recordings",
5
5
  "type": "module",
6
6
  "exports": {
@@ -29,7 +29,7 @@
29
29
  }
30
30
  },
31
31
  "devDependencies": {
32
- "@replayio/app-building": "^1.28.0",
32
+ "@replayio/app-building": "^1.29.0",
33
33
  "@types/node": "^25.6.0",
34
34
  "tsup": "^8.5.1",
35
35
  "typescript": "^5.7.3"