@mieweb/pulsevault 0.0.2 → 0.1.1

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.
Files changed (76) hide show
  1. package/CHANGELOG.md +258 -0
  2. package/LICENSE +15 -39
  3. package/OPERATIONS.md +223 -0
  4. package/PROTOCOL.md +345 -0
  5. package/README.md +548 -122
  6. package/augment.d.ts +1 -0
  7. package/augment.js +3 -0
  8. package/core.d.ts +1 -0
  9. package/core.js +7 -0
  10. package/dist/app.d.ts +91 -34
  11. package/dist/app.d.ts.map +1 -1
  12. package/dist/app.js +23 -33
  13. package/dist/app.js.map +1 -1
  14. package/dist/augment.d.ts +14 -7
  15. package/dist/augment.d.ts.map +1 -1
  16. package/dist/augment.js.map +1 -1
  17. package/dist/core.d.ts +108 -0
  18. package/dist/core.d.ts.map +1 -0
  19. package/dist/core.js +494 -0
  20. package/dist/core.js.map +1 -0
  21. package/dist/lib/authorize.d.ts +19 -0
  22. package/dist/lib/authorize.d.ts.map +1 -0
  23. package/dist/lib/authorize.js +2 -0
  24. package/dist/lib/authorize.js.map +1 -0
  25. package/dist/lib/capability-token.d.ts +80 -0
  26. package/dist/lib/capability-token.d.ts.map +1 -0
  27. package/dist/lib/capability-token.js +134 -0
  28. package/dist/lib/capability-token.js.map +1 -0
  29. package/dist/lib/checksum.d.ts +45 -0
  30. package/dist/lib/checksum.d.ts.map +1 -0
  31. package/dist/lib/checksum.js +105 -0
  32. package/dist/lib/checksum.js.map +1 -0
  33. package/dist/lib/deeplinks.d.ts +37 -21
  34. package/dist/lib/deeplinks.d.ts.map +1 -1
  35. package/dist/lib/deeplinks.js +54 -13
  36. package/dist/lib/deeplinks.js.map +1 -1
  37. package/dist/lib/errors.d.ts +7 -0
  38. package/dist/lib/errors.d.ts.map +1 -1
  39. package/dist/lib/errors.js +18 -0
  40. package/dist/lib/errors.js.map +1 -1
  41. package/dist/lib/magic.d.ts +30 -5
  42. package/dist/lib/magic.d.ts.map +1 -1
  43. package/dist/lib/magic.js +51 -14
  44. package/dist/lib/magic.js.map +1 -1
  45. package/dist/lib/options.d.ts +41 -0
  46. package/dist/lib/options.d.ts.map +1 -0
  47. package/dist/lib/options.js +111 -0
  48. package/dist/lib/options.js.map +1 -0
  49. package/dist/lib/pulsevaultTus.d.ts +53 -26
  50. package/dist/lib/pulsevaultTus.d.ts.map +1 -1
  51. package/dist/lib/pulsevaultTus.js +174 -55
  52. package/dist/lib/pulsevaultTus.js.map +1 -1
  53. package/dist/lib/request.d.ts +26 -0
  54. package/dist/lib/request.d.ts.map +1 -0
  55. package/dist/lib/request.js +22 -0
  56. package/dist/lib/request.js.map +1 -0
  57. package/dist/lib/uuid.d.ts.map +1 -1
  58. package/dist/lib/uuid.js +1 -1
  59. package/dist/lib/uuid.js.map +1 -1
  60. package/dist/routes/pulsevault.d.ts +18 -16
  61. package/dist/routes/pulsevault.d.ts.map +1 -1
  62. package/dist/routes/pulsevault.js +121 -251
  63. package/dist/routes/pulsevault.js.map +1 -1
  64. package/dist/storage/local.d.ts +31 -10
  65. package/dist/storage/local.d.ts.map +1 -1
  66. package/dist/storage/local.js +205 -84
  67. package/dist/storage/local.js.map +1 -1
  68. package/dist/storage/s3.d.ts +109 -0
  69. package/dist/storage/s3.d.ts.map +1 -0
  70. package/dist/storage/s3.js +438 -0
  71. package/dist/storage/s3.js.map +1 -0
  72. package/dist/storage/types.d.ts +80 -17
  73. package/dist/storage/types.d.ts.map +1 -1
  74. package/dist/storage/types.js +13 -1
  75. package/dist/storage/types.js.map +1 -1
  76. package/package.json +29 -7
@@ -1,7 +1,10 @@
1
- import { Server } from "@tus/server";
2
- import { AsyncLocalStorage } from "node:async_hooks";
3
- import path from "node:path";
4
- import { isUuid } from "./uuid.js";
1
+ import { Server } from '@tus/server';
2
+ import { AsyncLocalStorage } from 'node:async_hooks';
3
+ import path from 'node:path';
4
+ import { isUuid } from './uuid.js';
5
+ import { statusCodeOf } from './errors.js';
6
+ import { consoleLogger } from './request.js';
7
+ import { parseUploadKind } from '../storage/types.js';
5
8
  export const pulseVaultTusContext = new AsyncLocalStorage();
6
9
  /**
7
10
  * Shape `@tus/server` recognizes for sending an error response. We tag both
@@ -16,50 +19,74 @@ export function tusError(status, body) {
16
19
  body,
17
20
  });
18
21
  }
19
- /** Parse the first path segment of a tus upload id as the videoid. */
20
- function videoidFromUploadId(id) {
21
- const first = id.split("/", 1)[0];
22
- return isUuid(first) ? first : undefined;
22
+ /** Parse the artifactId UUID from a tus upload id of the form `<kind>/<artifactId><ext>`. */
23
+ export function artifactIdFromUploadId(id) {
24
+ const [, nameWithExt] = id.split('/');
25
+ if (!nameWithExt)
26
+ return undefined;
27
+ const ext = path.extname(nameWithExt);
28
+ const candidate = ext ? nameWithExt.slice(0, -ext.length) : nameWithExt;
29
+ return isUuid(candidate) ? candidate : undefined;
23
30
  }
24
31
  /**
25
- * Extract a numeric HTTP status from a thrown error, honoring both
26
- * `statusCode` (Fastify) and `status_code` (tus).
32
+ * Extract and normalize the fields `namingFunction` cares about from raw
33
+ * `Upload-Metadata`. Doesn't validate — the caller still checks `artifactId`
34
+ * is a UUID and `filename`'s extension is allowed for `kind`.
27
35
  */
28
- function statusCodeOf(err, fallback) {
29
- const e = err;
30
- if (typeof e?.statusCode === "number")
31
- return e.statusCode;
32
- if (typeof e?.status_code === "number")
33
- return e.status_code;
34
- return fallback;
36
+ function parseUploadMetadata(metadata) {
37
+ // Accept `artifactId` plus the legacy `videoid`/`projectid` aliases for
38
+ // back-compat with pre-`artifactId` clients.
39
+ const artifactId = (metadata?.artifactId ??
40
+ metadata?.videoid ??
41
+ metadata?.projectid ??
42
+ '').trim();
43
+ const filename = (metadata?.filename ?? '').trim();
44
+ // `kind` defaults to `"video"` so existing clients that don't send the field continue to work unchanged.
45
+ const kind = parseUploadKind(metadata?.kind);
46
+ const rawRelatedTo = (metadata?.relatedTo ?? '').trim();
47
+ const relatedTo = isUuid(rawRelatedTo) ? rawRelatedTo : undefined;
48
+ const checksum = (metadata?.checksum ?? '').trim() || undefined;
49
+ return { artifactId, filename, kind, relatedTo, checksum };
35
50
  }
36
51
  export function createPulsevaultTusServer(options) {
37
- const { storage, tusPath, maxSize, allowedExtensions, validatePayload, onUploadComplete, } = options;
38
- return new Server({
52
+ const { storage, tusPath, maxSize, allowedExtensions, validatePayload, onUploadComplete, onArtifactEvent, logger = consoleLogger, } = options;
53
+ const server = new Server({
39
54
  path: tusPath,
40
55
  datastore: storage.datastore,
41
56
  maxSize,
42
57
  namingFunction: async (_req, metadata) => {
43
- const videoid = metadata?.videoid ?? "";
44
- const filename = (metadata?.filename ?? "").trim();
45
- if (!isUuid(videoid)) {
46
- throw tusError(400, "Upload-Metadata must include a valid `videoid` (UUID).\n");
58
+ const { artifactId, filename, kind, relatedTo, checksum } = parseUploadMetadata(metadata);
59
+ if (!isUuid(artifactId)) {
60
+ throw tusError(400, 'Upload-Metadata must include a valid `artifactId` UUID.\n');
47
61
  }
48
62
  const ext = path.extname(filename).toLowerCase();
49
- if (!ext || !allowedExtensions.includes(ext)) {
50
- throw tusError(400, `Upload-Metadata \`filename\` must end with one of: ${allowedExtensions.join(", ")}\n`);
63
+ const allowed = allowedExtensions[kind];
64
+ if (!ext || !allowed.includes(ext)) {
65
+ throw tusError(400, `Upload-Metadata \`filename\` for kind="${kind}" must end with one of: ${allowed.join(', ')}\n`);
51
66
  }
52
- return storage.reserveUpload({ videoid, filename, ext });
67
+ // Store kind/relatedTo/checksum in the AsyncLocalStorage context so the
68
+ // authorize hook (already running) and onUploadFinish (same-request
69
+ // uploads) can read them without a storage round-trip.
70
+ const store = pulseVaultTusContext.getStore();
71
+ if (store) {
72
+ store.kind = kind;
73
+ store.relatedTo = relatedTo;
74
+ store.checksum = checksum;
75
+ }
76
+ return storage.reserveUpload({ artifactId, filename, ext, kind, relatedTo, checksum });
53
77
  },
54
- generateUrl(_req, { proto, host, path: tusBasePath, id }) {
55
- const encoded = Buffer.from(id, "utf8").toString("base64url");
56
- return `${proto}://${host}${tusBasePath}/${encoded}`;
78
+ // Relative Location (RFC 7231 §7.1.2) so the upload URL is correct behind
79
+ // any TLS-terminating proxy without trusting spoofable X-Forwarded-*
80
+ // headers; clients resolve it against the request URL they already used.
81
+ generateUrl(_req, { path: tusBasePath, id }) {
82
+ const encoded = Buffer.from(id, 'utf8').toString('base64url');
83
+ return `${tusBasePath}/${encoded}`;
57
84
  },
58
85
  getFileIdFromRequest(_req, lastPath) {
59
86
  if (!lastPath) {
60
87
  return;
61
88
  }
62
- return Buffer.from(lastPath, "base64url").toString("utf8");
89
+ return Buffer.from(lastPath, 'base64url').toString('utf8');
63
90
  },
64
91
  onUploadFinish: async (_req, upload) => {
65
92
  // Completion sequence: validate → markReady → consumer hook. Each step
@@ -71,76 +98,168 @@ export function createPulsevaultTusServer(options) {
71
98
  // before calling into tus. Bail quietly rather than crash.
72
99
  return {};
73
100
  }
74
- const videoid = videoidFromUploadId(upload.id);
75
- if (!videoid) {
101
+ const artifactId = artifactIdFromUploadId(upload.id);
102
+ if (!artifactId) {
76
103
  return {};
77
104
  }
78
105
  const size = upload.size ?? 0;
79
106
  const uploadId = upload.id;
80
- // 1. Validate payload (magic bytes, virus scan, etc.). If this throws
81
- // we wipe the bytes from storage — the client gets a 4xx, the
82
- // sidecar is gone, and they can safely retry with a corrected file.
107
+ // Resolve kind/checksum: prefer the context value (set during the same
108
+ // request's namingFunction for single-request uploads), fall back to a
109
+ // storage lookup (cheap in-memory cache hit) for chunked uploads, or —
110
+ // just as commonly — a single-PATCH upload sent as two separate HTTP
111
+ // requests (create, then patch), where `onUploadFinish` runs on the
112
+ // PATCH request's own fresh context, not the one `namingFunction`
113
+ // populated during the earlier POST.
114
+ const kind = store.kind ?? (await resolveKind(storage, artifactId));
115
+ const checksum = store.checksum ?? (await resolveChecksum(storage, artifactId));
116
+ // 1. Validate payload (magic bytes, checksum, virus scan, etc.). If
117
+ // this throws we wipe the bytes from storage — the client gets a
118
+ // 4xx, the sidecar is gone, and they can safely retry with a
119
+ // corrected file. The same hook runs for every kind; consumers that
120
+ // want kind-specific behavior branch on `ctx.kind` themselves.
83
121
  if (validatePayload) {
84
122
  try {
85
123
  await validatePayload(store.request, {
86
- videoid,
124
+ artifactId,
87
125
  size,
88
126
  uploadId,
89
- localPath: await resolveLocalPath(storage, videoid),
127
+ localPath: await resolveLocalPath(storage, artifactId),
128
+ ...(checksum ? { checksum } : {}),
129
+ kind,
90
130
  });
91
131
  }
92
132
  catch (err) {
93
133
  const status = statusCodeOf(err, 422);
94
- const message = err instanceof Error ? err.message : "Payload validation failed";
134
+ const message = err instanceof Error ? err.message : 'Payload validation failed';
95
135
  try {
96
- await storage.remove?.(videoid);
136
+ await storage.remove?.(artifactId);
97
137
  }
98
138
  catch (rmErr) {
99
- store.request.log.error({ err: rmErr, videoid }, "pulsevault failed to remove rejected upload");
139
+ logger.error({ err: rmErr, artifactId }, 'pulsevault failed to remove rejected upload');
140
+ }
141
+ await onArtifactEvent?.({ phase: 'reject', artifactId, kind, size, reason: message });
142
+ // 4xx rejection reasons are the client's business (e.g. "Checksum
143
+ // mismatch: …"); 5xx means *our* side broke — log the real error and
144
+ // return a generic body so internals (adapter wiring, stack detail)
145
+ // never reach the client.
146
+ if (status >= 500) {
147
+ logger.error({ err, artifactId, kind }, 'pulsevault payload validation errored');
148
+ throw tusError(status, 'Payload validation failed\n');
100
149
  }
101
150
  throw tusError(status, `${message}\n`);
102
151
  }
103
152
  }
104
153
  // 2. Flip the sidecar to "ready" so `resolve` will serve the bytes.
105
154
  // Done *before* the consumer hook so a downstream service that
106
- // reacts to `onUploadComplete` can immediately GET the video.
155
+ // reacts to `onUploadComplete` can immediately GET the artifact.
107
156
  try {
108
- await storage.markReady?.(videoid);
157
+ await storage.markReady?.(artifactId);
109
158
  }
110
159
  catch (err) {
111
- const message = err instanceof Error ? err.message : "markReady failed";
112
- throw tusError(500, `${message}\n`);
160
+ // Internal failure — log the real error server-side, return a generic
161
+ // body (a storage error message can leak paths/config to the client).
162
+ logger.error({ err, artifactId, kind }, 'pulsevault markReady failed');
163
+ throw tusError(500, 'Upload finalization failed\n');
113
164
  }
114
165
  // 3. Consumer hook — business logic (DB writes, queue jobs).
115
166
  if (onUploadComplete) {
116
167
  try {
117
- await onUploadComplete(store.request, { videoid, size, uploadId });
168
+ await onUploadComplete(store.request, { artifactId, kind, size, uploadId });
118
169
  }
119
170
  catch (err) {
120
171
  // Propagate as a tus error so the client sees a non-2xx and can
121
172
  // distinguish "bytes stored but completion hook failed" from
122
- // success. The video is marked ready at this point — consumers
173
+ // success. The artifact is marked ready at this point — consumers
123
174
  // who want "all-or-nothing" should `storage.remove` before
124
175
  // throwing.
125
- const message = err instanceof Error ? err.message : "onUploadComplete failed";
126
- throw tusError(500, `${message}\n`);
176
+ // The real error (often a consumer DB failure whose message can leak
177
+ // schema/infra detail) stays in the server log, not the client body.
178
+ logger.error({ err, artifactId, kind }, 'pulsevault onUploadComplete failed');
179
+ throw tusError(500, 'Upload completion hook failed\n');
127
180
  }
128
181
  }
182
+ await onArtifactEvent?.({ phase: 'complete', artifactId, kind, size });
129
183
  return {};
130
184
  },
131
185
  });
186
+ hardenAgainstClientAbort(server, logger);
187
+ return server;
188
+ }
189
+ /**
190
+ * Stops a dropped upload connection from crashing the whole server process.
191
+ *
192
+ * @tus/server@2's `BaseHandler.writeToStore` (used by both the PATCH handler and the POST handler's
193
+ * creation-with-upload path) pipes the incoming body (`Readable.fromWeb(req.body)`) into an internal
194
+ * proxy via `data.pipe(proxy)` and attaches an 'error' handler to the *proxy* — but never to `data`
195
+ * itself. `.pipe()` doesn't forward source errors, so when the client drops the connection
196
+ * mid-transfer (a mobile app killed during an upload, a network reset, a cancelled transfer) `data`
197
+ * emits an 'error' ('aborted' / ECONNRESET) with no listener. An unhandled stream 'error' is fatal
198
+ * to Node: the process crashes, taking down every other in-flight upload (observed as the server
199
+ * dying and subsequent requests 502-ing).
200
+ *
201
+ * We wrap each body-carrying handler's `writeToStore` to attach a no-op 'error' listener to `data`
202
+ * before delegating. The abort then unwinds normally — the proxy/pipeline still rejects the write
203
+ * and the stored offset simply doesn't advance, so the client resumes from the last persisted byte
204
+ * on its next PATCH. Defensive: it no-ops if a future @tus version renames/fixes this, and the
205
+ * extra listener is harmless if they add their own. (Long-term fix: upgrade @tus/server once it
206
+ * handles the source-stream error itself.)
207
+ */
208
+ function hardenAgainstClientAbort(server, logger) {
209
+ const handlers = server.handlers ?? {};
210
+ for (const method of ['PATCH', 'POST']) {
211
+ const handler = handlers[method];
212
+ if (!handler || typeof handler.writeToStore !== 'function') {
213
+ logger.info({ method }, 'pulsevault: could not harden handler against client abort (API changed?)');
214
+ continue;
215
+ }
216
+ const original = handler.writeToStore.bind(handler);
217
+ handler.writeToStore = (data, ...rest) => {
218
+ if (data && typeof data.on === 'function') {
219
+ data.on('error', (err) => {
220
+ // Debug (falling back to info for loggers without it): a client dropping mid-upload is
221
+ // an expected, per-request event on flaky mobile networks — not something to page over.
222
+ const obj = { err: err instanceof Error ? err.message : String(err), method };
223
+ const msg = 'pulsevault: upload body stream aborted (client disconnected mid-transfer)';
224
+ if (logger.debug)
225
+ logger.debug(obj, msg);
226
+ else
227
+ logger.info(obj, msg);
228
+ });
229
+ }
230
+ return original(data, ...rest);
231
+ };
232
+ }
233
+ }
234
+ /**
235
+ * Resolve the artifact kind from storage for a known artifactId. Used by
236
+ * `onUploadFinish` for chunked uploads where the kind is not in the current
237
+ * request's context. Defaults to `"video"` for adapters that don't implement
238
+ * `getKind` or when the artifactId is not found.
239
+ */
240
+ async function resolveKind(storage, artifactId) {
241
+ const result = await storage.getKind?.(artifactId);
242
+ return result ?? 'video';
243
+ }
244
+ /**
245
+ * Resolve the `checksum` metadata from storage for a known artifactId. Same
246
+ * rationale as `resolveKind` — `namingFunction`'s in-memory context doesn't
247
+ * survive past the request it ran on, so completion (which may run on a
248
+ * later, separate request) needs a storage-backed fallback.
249
+ */
250
+ async function resolveChecksum(storage, artifactId) {
251
+ const result = await storage.getChecksum?.(artifactId);
252
+ return result ?? undefined;
132
253
  }
133
254
  /**
134
255
  * If the adapter exposes `getLocalPath` (the built-in local adapter does),
135
- * resolve the videoid to an absolute disk path for `validatePayload`. For
256
+ * resolve the artifactId to an absolute disk path for `validatePayload`. For
136
257
  * other adapters, returns `null` and the validator is expected to fetch
137
258
  * bytes through whatever API it knows about.
138
259
  */
139
- async function resolveLocalPath(storage, videoid) {
140
- const candidate = storage.getLocalPath;
141
- if (typeof candidate !== "function")
142
- return null;
143
- const result = await candidate(videoid);
144
- return typeof result === "string" ? result : null;
260
+ async function resolveLocalPath(storage, artifactId) {
261
+ const adapter = storage;
262
+ const result = await adapter.getLocalPath?.(artifactId);
263
+ return typeof result === 'string' ? result : null;
145
264
  }
146
265
  //# sourceMappingURL=pulsevaultTus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pulsevaultTus.js","sourceRoot":"","sources":["../../src/lib/pulsevaultTus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAcnC,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,iBAAiB,EAAwB,CAAC;AAmClF;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,IAAY;IACnD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;QACpC,UAAU,EAAE,MAAM;QAClB,WAAW,EAAE,MAAM;QACnB,IAAI;KACL,CAAC,CAAC;AACL,CAAC;AAED,sEAAsE;AACtE,SAAS,mBAAmB,CAAC,EAAU;IACrC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,GAAY,EAAE,QAAgB;IAClD,MAAM,CAAC,GAAG,GAAsD,CAAC;IACjE,IAAI,OAAO,CAAC,EAAE,UAAU,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,UAAU,CAAC;IAC3D,IAAI,OAAO,CAAC,EAAE,WAAW,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,WAAW,CAAC;IAC7D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,OAA6B;IACrE,MAAM,EACJ,OAAO,EACP,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,GAAG,OAAO,CAAC;IAEZ,OAAO,IAAI,MAAM,CAAC;QAChB,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO;QACP,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACvC,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAEnD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrB,MAAM,QAAQ,CACZ,GAAG,EACH,0DAA0D,CAC3D,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,MAAM,QAAQ,CACZ,GAAG,EACH,sDAAsD,iBAAiB,CAAC,IAAI,CAC1E,IAAI,CACL,IAAI,CACN,CAAC;YACJ,CAAC;YAED,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,WAAW,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YACtD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC9D,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC;QACvD,CAAC;QACD,oBAAoB,CAAC,IAAI,EAAE,QAAQ;YACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QACD,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;YACrC,uEAAuE;YACvE,mEAAmE;YACnE,mEAAmE;YACnE,MAAM,KAAK,GAAG,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,mEAAmE;gBACnE,2DAA2D;gBAC3D,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;YAE3B,sEAAsE;YACtE,iEAAiE;YACjE,uEAAuE;YACvE,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE;wBACnC,OAAO;wBACP,IAAI;wBACJ,QAAQ;wBACR,SAAS,EAAE,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC;qBACpD,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;oBACtC,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;oBACnE,IAAI,CAAC;wBACH,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;oBAClC,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CACrB,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,EACvB,6CAA6C,CAC9C,CAAC;oBACJ,CAAC;oBACD,MAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YAED,oEAAoE;YACpE,kEAAkE;YAClE,iEAAiE;YACjE,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;gBAC1D,MAAM,QAAQ,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;YACtC,CAAC;YAED,6DAA6D;YAC7D,IAAI,gBAAgB,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,MAAM,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACrE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,gEAAgE;oBAChE,6DAA6D;oBAC7D,+DAA+D;oBAC/D,2DAA2D;oBAC3D,YAAY;oBACZ,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;oBACjE,MAAM,QAAQ,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,gBAAgB,CAC7B,OAA0B,EAC1B,OAAe;IAEf,MAAM,SAAS,GAAI,OAAsC,CAAC,YAAY,CAAC;IACvE,IAAI,OAAO,SAAS,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,MAAM,GAAG,MAAO,SAAoD,CACxE,OAAO,CACR,CAAC;IACF,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"pulsevaultTus.js","sourceRoot":"","sources":["../../src/lib/pulsevaultTus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { IncomingHttpHeaders } from 'node:http';
2
+ /**
3
+ * Structural request shape the plugin's internals and hooks rely on.
4
+ * `FastifyRequest`, Express's `req`, and a raw `http.IncomingMessage` all
5
+ * satisfy this already (they all expose `.headers`), so the same hook
6
+ * implementations work unmodified under the Fastify plugin and the
7
+ * framework-agnostic core.
8
+ */
9
+ export type PulseVaultRequest = {
10
+ headers: IncomingHttpHeaders;
11
+ };
12
+ /**
13
+ * Structural logger shape used for the plugin's own internal diagnostics
14
+ * (authorize rejections, tus handler failures, cleanup errors) — satisfied
15
+ * by Pino (Fastify's `request.log`) and by the `consoleLogger` fallback
16
+ * below, so non-Fastify hosts don't need to bring their own logger.
17
+ */
18
+ export type PulseVaultLogger = {
19
+ info(obj: unknown, msg?: string): void;
20
+ error(obj: unknown, msg?: string): void;
21
+ /** Optional low-noise level for expected, per-request events (e.g. a client aborting mid-upload). */
22
+ debug?(obj: unknown, msg?: string): void;
23
+ };
24
+ /** Default logger for hosts that don't supply one. */
25
+ export declare const consoleLogger: PulseVaultLogger;
26
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,mBAAmB,CAAC;CAC9B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,qGAAqG;IACrG,KAAK,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,aAAa,EAAE,gBAa3B,CAAC"}
@@ -0,0 +1,22 @@
1
+ /** Default logger for hosts that don't supply one. */
2
+ export const consoleLogger = {
3
+ info(obj, msg) {
4
+ if (msg)
5
+ console.info(msg, obj);
6
+ else
7
+ console.info(obj);
8
+ },
9
+ error(obj, msg) {
10
+ if (msg)
11
+ console.error(msg, obj);
12
+ else
13
+ console.error(obj);
14
+ },
15
+ debug(obj, msg) {
16
+ if (msg)
17
+ console.debug(msg, obj);
18
+ else
19
+ console.debug(obj);
20
+ },
21
+ };
22
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"AA0BA,sDAAsD;AACtD,MAAM,CAAC,MAAM,aAAa,GAAqB;IAC7C,IAAI,CAAC,GAAG,EAAE,GAAG;QACX,IAAI,GAAG;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;;YAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,KAAK,CAAC,GAAG,EAAE,GAAG;QACZ,IAAI,GAAG;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;;YAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,CAAC,GAAG,EAAE,GAAG;QACZ,IAAI,GAAG;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;;YAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../src/lib/uuid.ts"],"names":[],"mappings":"AAGA,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEtD"}
1
+ {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../src/lib/uuid.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEtD"}
package/dist/lib/uuid.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2
2
  export function isUuid(value) {
3
- return typeof value === "string" && UUID_REGEX.test(value);
3
+ return typeof value === 'string' && UUID_REGEX.test(value);
4
4
  }
5
5
  //# sourceMappingURL=uuid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/lib/uuid.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GACd,iEAAiE,CAAC;AAEpE,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/lib/uuid.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,iEAAiE,CAAC;AAErF,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC"}
@@ -1,32 +1,34 @@
1
- import type { FastifyPluginAsync, FastifyPluginOptions, FastifyRequest } from "fastify";
2
- import type { PulseVaultCacheOptions } from "../app.js";
3
- import { type PulseVaultOnUploadComplete } from "../lib/pulsevaultTus.js";
4
- import type { PulseVaultValidatePayload } from "../lib/magic.js";
5
- import type { PulseVaultStorage } from "../storage/types.js";
6
- declare module "fastify" {
1
+ import type { FastifyPluginAsync, FastifyPluginOptions } from 'fastify';
2
+ import type { PulseVaultCacheOptions } from '../app.js';
3
+ import { PROTOCOL_VERSION } from '../core.js';
4
+ import type { PulseVaultOnUploadComplete, PulseVaultOnArtifactEvent } from '../lib/pulsevaultTus.js';
5
+ import type { PulseVaultValidatePayload } from '../lib/magic.js';
6
+ import { type PulseVaultAuthorize } from '../lib/authorize.js';
7
+ import type { PulseVaultAllowedExtensions } from '../lib/options.js';
8
+ import type { PulseVaultStorage, UploadKind } from '../storage/types.js';
9
+ export type { PulseVaultAuthorize, PulseVaultAuthorizeContext, PulseVaultAuthorizePhase, } from '../lib/authorize.js';
10
+ declare module 'fastify' {
7
11
  interface FastifyRequest {
8
12
  pulseVault?: {
9
- videoid: string;
13
+ artifactId: string;
14
+ kind: UploadKind;
15
+ relatedTo?: string;
10
16
  };
11
17
  }
12
18
  }
13
- export type PulseVaultAuthorizePhase = "create" | "patch" | "resolve" | "delete";
14
- export type PulseVaultAuthorizeContext = {
15
- phase: PulseVaultAuthorizePhase;
16
- videoid: string;
17
- /** Bearer / query-string token forwarded from the watch URL, if present. Only populated during the `"resolve"` phase. */
18
- token?: string;
19
- };
20
- export type PulseVaultAuthorize = (request: FastifyRequest, ctx: PulseVaultAuthorizeContext) => void | Promise<void>;
21
19
  export type PulseVaultRoutesOptions = {
22
20
  storage: PulseVaultStorage;
23
21
  maxUploadSize: number;
24
- allowedExtensions: readonly string[];
22
+ allowedExtensions: PulseVaultAllowedExtensions;
23
+ /** Advertised via `GET /capabilities` so the client knows which upload strategy this server expects. */
24
+ uploadUnit: 'segment' | 'merged';
25
25
  cache?: PulseVaultCacheOptions;
26
26
  authorize?: PulseVaultAuthorize;
27
27
  validatePayload?: PulseVaultValidatePayload;
28
28
  onUploadComplete?: PulseVaultOnUploadComplete;
29
+ onArtifactEvent?: PulseVaultOnArtifactEvent;
29
30
  } & FastifyPluginOptions;
30
31
  declare const pulseVaultRoutes: FastifyPluginAsync<PulseVaultRoutesOptions>;
31
32
  export default pulseVaultRoutes;
33
+ export { PROTOCOL_VERSION };
32
34
  //# sourceMappingURL=pulsevault.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pulsevault.d.ts","sourceRoot":"","sources":["../../src/routes/pulsevault.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EAEpB,cAAc,EAEf,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,UAAU,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAClC;CACF;AAED,MAAM,MAAM,wBAAwB,GAChC,QAAQ,GACR,OAAO,GACP,SAAS,GACT,QAAQ,CAAC;AAEb,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,wBAAwB,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,yHAAyH;IACzH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,0BAA0B,KAC5B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;CAC/C,GAAG,oBAAoB,CAAC;AAwKzB,QAAA,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,uBAAuB,CA+NjE,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"pulsevault.d.ts","sourceRoot":"","sources":["../../src/routes/pulsevault.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EAIrB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAwB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEzE,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,UAAU,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,UAAU,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3E;CACF;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,2BAA2B,CAAC;IAC/C,wGAAwG;IACxG,UAAU,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C,GAAG,oBAAoB,CAAC;AA6JzB,QAAA,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,uBAAuB,CA8EjE,CAAC;AAEF,eAAe,gBAAgB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}