@mieweb/pulsevault 0.4.2 → 0.6.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +216 -1
  2. package/OPERATIONS.md +135 -44
  3. package/PROTOCOL.md +63 -4
  4. package/README.md +186 -34
  5. package/dist/app.d.ts +30 -5
  6. package/dist/app.d.ts.map +1 -1
  7. package/dist/app.js +24 -5
  8. package/dist/app.js.map +1 -1
  9. package/dist/augment.d.ts +3 -0
  10. package/dist/augment.d.ts.map +1 -1
  11. package/dist/augment.js.map +1 -1
  12. package/dist/core.d.ts +107 -8
  13. package/dist/core.d.ts.map +1 -1
  14. package/dist/core.js +381 -47
  15. package/dist/core.js.map +1 -1
  16. package/dist/lib/authorize.d.ts +28 -6
  17. package/dist/lib/authorize.d.ts.map +1 -1
  18. package/dist/lib/capability-token.d.ts +26 -0
  19. package/dist/lib/capability-token.d.ts.map +1 -1
  20. package/dist/lib/capability-token.js +73 -5
  21. package/dist/lib/capability-token.js.map +1 -1
  22. package/dist/lib/completion.d.ts +138 -0
  23. package/dist/lib/completion.d.ts.map +1 -0
  24. package/dist/lib/completion.js +375 -0
  25. package/dist/lib/completion.js.map +1 -0
  26. package/dist/lib/deeplinks.d.ts +18 -2
  27. package/dist/lib/deeplinks.d.ts.map +1 -1
  28. package/dist/lib/deeplinks.js +13 -2
  29. package/dist/lib/deeplinks.js.map +1 -1
  30. package/dist/lib/magic.d.ts +41 -1
  31. package/dist/lib/magic.d.ts.map +1 -1
  32. package/dist/lib/magic.js +104 -0
  33. package/dist/lib/magic.js.map +1 -1
  34. package/dist/lib/options.d.ts +2 -0
  35. package/dist/lib/options.d.ts.map +1 -1
  36. package/dist/lib/options.js +8 -2
  37. package/dist/lib/options.js.map +1 -1
  38. package/dist/lib/protocol-version.gen.js +1 -1
  39. package/dist/lib/pulsevaultTus.d.ts +28 -26
  40. package/dist/lib/pulsevaultTus.d.ts.map +1 -1
  41. package/dist/lib/pulsevaultTus.js +149 -32
  42. package/dist/lib/pulsevaultTus.js.map +1 -1
  43. package/dist/lib/web-ready.d.ts +138 -18
  44. package/dist/lib/web-ready.d.ts.map +1 -1
  45. package/dist/lib/web-ready.js +453 -91
  46. package/dist/lib/web-ready.js.map +1 -1
  47. package/dist/routes/pulsevault.d.ts +12 -1
  48. package/dist/routes/pulsevault.d.ts.map +1 -1
  49. package/dist/routes/pulsevault.js +92 -1
  50. package/dist/routes/pulsevault.js.map +1 -1
  51. package/dist/storage/local.d.ts +7 -1
  52. package/dist/storage/local.d.ts.map +1 -1
  53. package/dist/storage/local.js +408 -52
  54. package/dist/storage/local.js.map +1 -1
  55. package/dist/storage/s3.d.ts +7 -1
  56. package/dist/storage/s3.d.ts.map +1 -1
  57. package/dist/storage/s3.js +256 -14
  58. package/dist/storage/s3.js.map +1 -1
  59. package/dist/storage/types.d.ts +126 -0
  60. package/dist/storage/types.d.ts.map +1 -1
  61. package/dist/storage/types.js +7 -0
  62. package/dist/storage/types.js.map +1 -1
  63. package/package.json +2 -2
  64. package/protocol/openapi.json +270 -1
  65. package/protocol/schemas/artifact-status.schema.json +61 -0
  66. package/protocol/schemas/capability-token.schema.json +3 -0
  67. package/protocol/schemas/deep-link.schema.json +2 -2
  68. package/scripts/web-ready-migrate.mjs +35 -11
package/dist/lib/magic.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
+ import { consoleLogger } from './request.js';
3
+ import { isBinaryAvailable, probeVideo, ProbeTimeoutError } from './web-ready.js';
2
4
  /**
3
5
  * Check whether a file's first bytes match the ISO base media file format
4
6
  * (`ftyp` box at offset 4), which covers MP4, MOV, M4V, 3GP, and related
@@ -100,4 +102,106 @@ export function createS3Mp4Sniffer(storage) {
100
102
  }
101
103
  };
102
104
  }
105
+ /**
106
+ * Whether a file's first bytes open one of the video containers PulseVault accepts: ISO base
107
+ * media (`ftyp`: MP4, MOV, M4V, 3GP), EBML (WebM, MKV) or RIFF `AVI `. A ~12-byte sniff, for
108
+ * when ffprobe isn't installed: it tells a video container from a renamed document, not a
109
+ * playable video from a broken one.
110
+ */
111
+ export async function sniffVideo(filePath) {
112
+ let fd;
113
+ try {
114
+ fd = await fs.open(filePath, 'r');
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ try {
120
+ const buf = Buffer.alloc(12);
121
+ const { bytesRead } = await fd.read(buf, 0, 12, 0);
122
+ if (bytesRead < 12)
123
+ return false;
124
+ const ebml = buf[0] === 0x1a && buf[1] === 0x45 && buf[2] === 0xdf && buf[3] === 0xa3;
125
+ const avi = buf.toString('latin1', 0, 4) === 'RIFF' && buf.toString('latin1', 8, 12) === 'AVI ';
126
+ return hasFtypBox(buf) || ebml || avi;
127
+ }
128
+ finally {
129
+ await fd.close();
130
+ }
131
+ }
132
+ /** The limit exactly, as said: `600` → "10 minutes", `61` → "1 minute 1 second", `45.5` → "45.5 seconds". */
133
+ function formatDuration(seconds) {
134
+ const unit = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`;
135
+ const minutes = Math.floor(seconds / 60);
136
+ // To the millisecond, so 61.25 reads "1 minute 1.25 seconds", never a rounded neighbour.
137
+ const rest = Math.round((seconds - minutes * 60) * 1000) / 1000;
138
+ if (minutes === 0)
139
+ return unit(rest, 'second');
140
+ return rest === 0 ? unit(minutes, 'minute') : `${unit(minutes, 'minute')} ${unit(rest, 'second')}`;
141
+ }
142
+ const warnedNoProbe = new Set();
143
+ /**
144
+ * Build a `validatePayload` hook that checks a video by what it is, not its file name: ffprobe
145
+ * must find a video stream with a duration above zero (and, with `maxDurationSeconds`, not
146
+ * longer than that). Without ffprobe on the host it falls back to `sniffVideo` and logs once.
147
+ * Other kinds pass untouched. Needs the bytes on local disk (the local adapter).
148
+ *
149
+ * A refusal is a `422` whose message a host can show as it is: "That file isn't a video.",
150
+ * "That video is longer than the limit of 10 minutes." or, when ffprobe runs past
151
+ * `probeTimeoutSeconds` (a malformed file), "That video couldn't be checked in time."
152
+ *
153
+ * Usage:
154
+ * ```ts
155
+ * await app.register(pulseVault, {
156
+ * storage: createLocalStorage({ workspaceDir: "./data" }),
157
+ * validatePayload: createVideoValidator({ maxDurationSeconds: 600 }),
158
+ * // ...
159
+ * });
160
+ * ```
161
+ */
162
+ export function createVideoValidator(options = {}) {
163
+ const ffprobePath = options.ffprobePath ?? 'ffprobe';
164
+ const logger = options.logger ?? consoleLogger;
165
+ const { maxDurationSeconds, probeTimeoutSeconds } = options;
166
+ for (const [name, value] of [['maxDurationSeconds', maxDurationSeconds], ['probeTimeoutSeconds', probeTimeoutSeconds]]) {
167
+ if (value !== undefined && !(value > 0 && Number.isFinite(value))) {
168
+ throw new TypeError(`\`${name}\` must be a positive number of seconds`);
169
+ }
170
+ }
171
+ const refuse = (message) => {
172
+ throw Object.assign(new Error(message), { statusCode: 422 });
173
+ };
174
+ return async (_request, { artifactId, kind, localPath }) => {
175
+ if (kind !== 'video')
176
+ return;
177
+ if (!localPath) {
178
+ throw Object.assign(new Error(`Cannot validate upload ${artifactId}: no local path available`), { statusCode: 500 });
179
+ }
180
+ if (!(await isBinaryAvailable(ffprobePath))) {
181
+ if (!warnedNoProbe.has(ffprobePath)) {
182
+ warnedNoProbe.add(ffprobePath);
183
+ logger.error({ ffprobePath }, 'pulsevault video check: ffprobe not found — only the container bytes are checked. ' +
184
+ 'Install ffmpeg (apt install ffmpeg / brew install ffmpeg) to check videos fully.');
185
+ }
186
+ if (!(await sniffVideo(localPath)))
187
+ refuse("That file isn't a video.");
188
+ return;
189
+ }
190
+ let probe;
191
+ try {
192
+ probe = await probeVideo(localPath, { ffprobePath, timeoutSeconds: probeTimeoutSeconds });
193
+ }
194
+ catch (err) {
195
+ if (!(err instanceof ProbeTimeoutError))
196
+ throw err;
197
+ logger.error({ err, artifactId }, 'pulsevault video check: ffprobe timed out');
198
+ return refuse("That video couldn't be checked in time.");
199
+ }
200
+ if (!probe || probe.durationSeconds === null)
201
+ refuse("That file isn't a video.");
202
+ if (maxDurationSeconds !== undefined && (probe?.durationSeconds ?? 0) > maxDurationSeconds) {
203
+ refuse(`That video is longer than the limit of ${formatDuration(maxDurationSeconds)}.`);
204
+ }
205
+ };
206
+ }
103
207
  //# sourceMappingURL=magic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"magic.js","sourceRoot":"","sources":["../../src/lib/magic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAiClC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,EAAiB,CAAC;IACtB,IAAI,CAAC;QACH,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,SAAS,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;QACjC,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAClF,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAqB;IACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACxC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,0BAA0B,UAAU,2BAA2B,CAAC,EAC1E,EAAE,UAAU,EAAE,GAAG,EAAE,CACpB,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0DAA0D,CAAC,EAAE;gBACzF,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAkB;IACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,0BAA0B,UAAU,6BAA6B,CAAC,EAC5E,EAAE,UAAU,EAAE,GAAG,EAAE,CACpB,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0DAA0D,CAAC,EAAE;gBACzF,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"magic.js","sourceRoot":"","sources":["../../src/lib/magic.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@ export type PulseVaultAllowedExtensions = {
14
14
  captions: readonly string[];
15
15
  thumbnail: readonly string[];
16
16
  };
17
+ /** An allowed extension: one dot, then no dot, whitespace or path separator. */
18
+ export declare const EXTENSION_REGEX: RegExp;
17
19
  /**
18
20
  * Normalize the consumer's `allowedExtensions` option (legacy array or per-kind
19
21
  * object) into the canonical `{ video, project, captions, thumbnail }` shape
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAErE,iHAAiH;AACjH,KAAK,uBAAuB,GAAG;IAC7B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,SAAS,MAAM,EAAE,GAAG,uBAAuB,CAAC;AAE3F,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAWF;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,gCAAgC,GAAG,SAAS,GAChD,2BAA2B,CAyB7B;AAED,6GAA6G;AAC7G,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAM3E;AAED,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAIjE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,gCAAgC,GAAG,SAAS,GAC9D,IAAI,CAiBN;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC,GAAG,IAAI,CAaP;AAED,8GAA8G;AAC9G,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,yBAAyB,GAAG,SAAS,EAC9C,aAAa,EAAE,yBAAyB,GAAG,SAAS,GACnD,yBAAyB,GAAG,SAAS,CASvC;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,0BAA0B,GAAG,SAAS,EAC/C,aAAa,EAAE,0BAA0B,GAAG,SAAS,GACpD,0BAA0B,GAAG,SAAS,CASxC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAErE,iHAAiH;AACjH,KAAK,uBAAuB,GAAG;IAC7B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,SAAS,MAAM,EAAE,GAAG,uBAAuB,CAAC;AAE3F,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC;AAaF,gFAAgF;AAChF,eAAO,MAAM,eAAe,QAAmB,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,gCAAgC,GAAG,SAAS,GAChD,2BAA2B,CAyB7B;AAED,6GAA6G;AAC7G,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAM3E;AAED,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAIjE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,gCAAgC,GAAG,SAAS,GAC9D,IAAI,CAiBN;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC,GAAG,IAAI,CAaP;AAED,8GAA8G;AAC9G,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,yBAAyB,GAAG,SAAS,EAC9C,aAAa,EAAE,yBAAyB,GAAG,SAAS,GACnD,yBAAyB,GAAG,SAAS,CASvC;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,0BAA0B,GAAG,SAAS,EAC/C,aAAa,EAAE,0BAA0B,GAAG,SAAS,GACpD,0BAA0B,GAAG,SAAS,CASxC"}
@@ -1,11 +1,17 @@
1
- const DEFAULT_VIDEO_EXTENSIONS = ['.mp4'];
1
+ import { CONFORM_VIDEO_EXTENSIONS } from './web-ready.js';
2
+ // Video: the containers `webReady` conforms to the format the Pulse app records (an `.mp4`), so
3
+ // a host's own file picker can take a screen recording, a camera-roll `.mov` or a browser's
4
+ // `.webm`. The other kinds are exactly what the Pulse app uploads; a host that accepts other
5
+ // clients adds their extensions (`.srt` is served with the right content type).
6
+ const DEFAULT_VIDEO_EXTENSIONS = CONFORM_VIDEO_EXTENSIONS;
2
7
  const DEFAULT_PROJECT_EXTENSIONS = ['.pulse', '.zip'];
3
8
  // WebVTT only — it's what the Pulse app uploads, and it carries word-level
4
9
  // inline cue timestamps (`<00:00:01.500>word`) for karaoke rendering.
5
10
  const DEFAULT_CAPTIONS_EXTENSIONS = ['.vtt'];
6
11
  // The pulse's poster frame (the draft's first-clip thumbnail).
7
12
  const DEFAULT_THUMBNAIL_EXTENSIONS = ['.jpg', '.jpeg', '.png'];
8
- const EXTENSION_REGEX = /^\.[^.\s/\\]+$/;
13
+ /** An allowed extension: one dot, then no dot, whitespace or path separator. */
14
+ export const EXTENSION_REGEX = /^\.[^.\s/\\]+$/;
9
15
  /**
10
16
  * Normalize the consumer's `allowedExtensions` option (legacy array or per-kind
11
17
  * object) into the canonical `{ video, project, captions, thumbnail }` shape
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  // GENERATED by scripts/gen-protocol-version.mjs from package.json `pulseProtocol`.
2
2
  // Do not edit: change package.json, then run `npm run build`.
3
3
  export const PULSE_PROTOCOL = {
4
- version: '2.2',
4
+ version: '2.5',
5
5
  min: 2,
6
6
  max: 2,
7
7
  };
@@ -4,6 +4,8 @@ import type { PulseVaultValidatePayload } from './magic.js';
4
4
  import { type PulseVaultRequest, type PulseVaultLogger } from './request.js';
5
5
  import type { PulseVaultStorage } from '../storage/types.js';
6
6
  import type { UploadKind } from '../storage/types.js';
7
+ import type { CompletionRunner, PulseVaultOnArtifactEvent } from './completion.js';
8
+ export type { PulseVaultOnUploadComplete, PulseVaultUploadCompleteContext, PulseVaultArtifactEvent, PulseVaultOnArtifactEvent, } from './completion.js';
7
9
  /**
8
10
  * Context the plugin stashes on each incoming request for the lifetime of a
9
11
  * TUS call. Shared with the tus hooks via `AsyncLocalStorage` because
@@ -19,32 +21,10 @@ export type PulseVaultTusContext = {
19
21
  relatedTo?: string;
20
22
  /** Raw `checksum` metadata value (`<algorithm>:<hex>`), if the client sent one. */
21
23
  checksum?: string;
24
+ /** The host data `authorize` returned for this create (the capability token's `context`), stored with the artifact. */
25
+ context?: unknown;
22
26
  };
23
27
  export declare const pulseVaultTusContext: AsyncLocalStorage<PulseVaultTusContext>;
24
- export type PulseVaultOnUploadComplete = (request: PulseVaultRequest, ctx: {
25
- artifactId: string;
26
- kind: UploadKind;
27
- size: number;
28
- uploadId: string;
29
- }) => void | Promise<void>;
30
- /**
31
- * Fired at low-frequency, audit-worthy moments — never per chunk — so an
32
- * operator can wire one hook to get both ops metrics and a compliance audit
33
- * trail without hand-rolling both from the lower-level hooks. `remove` fires
34
- * after PulseVault removed an artifact: a `DELETE /artifacts/:id` or a TUS
35
- * `DELETE` (`reason: "deleted"`), or the `retention` sweep (`reason: "abandoned"`)
36
- * — so a host keeping its own index of artifacts can drop it.
37
- */
38
- export type PulseVaultArtifactEvent = {
39
- phase: 'authorize' | 'complete' | 'reject' | 'remove';
40
- artifactId: string;
41
- kind: UploadKind;
42
- size?: number;
43
- reason?: string;
44
- /** The uploading app's version, from `Upload-Metadata.appVersion` (`complete`/`reject` only). */
45
- appVersion?: string;
46
- };
47
- export type PulseVaultOnArtifactEvent = (event: PulseVaultArtifactEvent) => void | Promise<void>;
48
28
  export type PulsevaultTusOptions = {
49
29
  storage: PulseVaultStorage;
50
30
  /** Absolute URL path where TUS is mounted, e.g. `/pulsevault/upload`. */
@@ -68,10 +48,25 @@ export type PulsevaultTusOptions = {
68
48
  * `storage.remove?.(artifactId)` and a 4xx (default 422).
69
49
  */
70
50
  validatePayload?: PulseVaultValidatePayload;
71
- /** Fired once the final byte has been written and any `validatePayload` has passed, for every kind. */
72
- onUploadComplete?: PulseVaultOnUploadComplete;
51
+ /** Runs the host's `onUploadComplete` (and the web-ready queue) once the final byte has been written and any `validatePayload` has passed. */
52
+ completion: CompletionRunner;
73
53
  /** See `PulseVaultOnArtifactEvent`. */
74
54
  onArtifactEvent?: PulseVaultOnArtifactEvent;
55
+ /**
56
+ * Hold every create to the shape of a pulse: a video with no `relatedTo`; a thumbnail, beat
57
+ * manifest or captions under its own id, `relatedTo` another. See the core's `pulseShape`.
58
+ */
59
+ pulseShape: boolean;
60
+ /**
61
+ * Let a create take over an unfinished upload of the same artifactId, kind and `relatedTo`
62
+ * once it has been idle this long (so the same token authorizes both), instead of a `409`
63
+ * until `retention` runs. See the core's `reclaim`.
64
+ */
65
+ reclaim: {
66
+ idleSeconds: number;
67
+ } | false;
68
+ /** With the core's `lockWhenReady`: whether a TUS `DELETE` of this artifact must be refused. */
69
+ isLocked?: (artifactId: string) => Promise<boolean>;
75
70
  /** Logger for internal diagnostics (cleanup failures, etc). Defaults to `console`. */
76
71
  logger?: PulseVaultLogger;
77
72
  };
@@ -84,5 +79,12 @@ export type PulsevaultTusOptions = {
84
79
  export declare function tusError(status: number, body: string): Error;
85
80
  /** Parse the artifactId UUID from a tus upload id of the form `<kind>/<artifactId><ext>`. */
86
81
  export declare function artifactIdFromUploadId(id: string): string | undefined;
82
+ /**
83
+ * Trim a display name and hard-cap its length so a hostile or buggy client can't bloat the
84
+ * sidecar; an all-whitespace/empty value is dropped. Capped by code point (Array.from iterates
85
+ * code points) rather than by `.slice()`'s UTF-16 units, so a title truncated at the boundary
86
+ * can't be left with a split surrogate pair (a half-emoji / lone surrogate).
87
+ */
88
+ export declare function normalizeArtifactName(value: string | null | undefined): string | undefined;
87
89
  export declare function createPulsevaultTusServer(options: PulsevaultTusOptions): Server;
88
90
  //# sourceMappingURL=pulsevaultTus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pulsevaultTus.d.ts","sourceRoot":"","sources":["../../src/lib/pulsevaultTus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAKrD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,oBAAoB,yCAAgD,CAAC;AAElF,MAAM,MAAM,0BAA0B,GAAG,CACvC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KAC1E,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjG,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,EAAE;QACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;QAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;KAC9B,CAAC;IACF;;;;;OAKG;IACH,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,uGAAuG;IACvG,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,uCAAuC;IACvC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,sFAAsF;IACtF,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAM5D;AAgDD,6FAA6F;AAC7F,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMrE;AA2DD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,UAyLtE"}
1
+ {"version":3,"file":"pulsevaultTus.d.ts","sourceRoot":"","sources":["../../src/lib/pulsevaultTus.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAKrD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEnF,YAAY,EACV,0BAA0B,EAC1B,+BAA+B,EAC/B,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uHAAuH;IACvH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,oBAAoB,yCAAgD,CAAC;AAElF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,EAAE;QACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;QAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;KAC9B,CAAC;IACF;;;;;OAKG;IACH,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,8IAA8I;IAC9I,UAAU,EAAE,gBAAgB,CAAC;IAC7B,uCAAuC;IACvC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACzC,gGAAgG;IAChG,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,sFAAsF;IACtF,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAM5D;AAuDD,6FAA6F;AAC7F,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMrE;AAWD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAM1F;AA2CD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,UA8RtE"}
@@ -1,4 +1,4 @@
1
- import { Server } from '@tus/server';
1
+ import { ERRORS, Server } from '@tus/server';
2
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
3
  import path from 'node:path';
4
4
  import { isUuid } from './uuid.js';
@@ -29,16 +29,22 @@ export function tusError(status, body) {
29
29
  * So both run: the datastore's removal, then `storage.remove`, which deletes the whole artifact,
30
30
  * in flight or finished. It 404s only when neither found anything to remove.
31
31
  */
32
- function withArtifactRemoval(storage, onRemoved) {
32
+ function withArtifactRemoval(storage, onRemoved, isLocked) {
33
33
  const { datastore } = storage;
34
- if (!storage.remove)
34
+ if (!storage.remove && !isLocked)
35
35
  return datastore;
36
- const removeArtifact = storage.remove.bind(storage);
36
+ const removeArtifact = storage.remove?.bind(storage);
37
37
  return new Proxy(datastore, {
38
38
  get(target, prop) {
39
39
  if (prop === 'remove') {
40
40
  return async (id) => {
41
41
  const artifactId = artifactIdFromUploadId(id);
42
+ // `lockWhenReady`, checked here because tus's DELETE handler holds the per-upload lock
43
+ // around this call: a DELETE racing the final PATCH of the same upload waits for it
44
+ // and then sees the artifact finished.
45
+ if (artifactId && isLocked && (await isLocked(artifactId))) {
46
+ throw tusError(403, 'A finished artifact is locked\n');
47
+ }
42
48
  const kind = artifactId ? await resolveKind(storage, artifactId) : undefined;
43
49
  // The datastore's own removal first — the upload's bytes and tus's records, which a
44
50
  // custom adapter's `remove` may not know about — then the artifact's.
@@ -52,7 +58,7 @@ function withArtifactRemoval(storage, onRemoved) {
52
58
  // Not there, or (S3) already completed: `storage.remove` below still removes it.
53
59
  uploadError = err;
54
60
  }
55
- const artifactRemoved = artifactId ? await removeArtifact(artifactId) : false;
61
+ const artifactRemoved = artifactId && removeArtifact ? await removeArtifact(artifactId) : false;
56
62
  if (artifactId && kind && artifactRemoved) {
57
63
  await onRemoved?.(artifactId, kind);
58
64
  }
@@ -82,6 +88,17 @@ export function artifactIdFromUploadId(id) {
82
88
  * should cap first; this is belt-and-suspenders so the server never trusts it.
83
89
  */
84
90
  const MAX_ARTIFACT_NAME_LENGTH = 512;
91
+ /**
92
+ * Trim a display name and hard-cap its length so a hostile or buggy client can't bloat the
93
+ * sidecar; an all-whitespace/empty value is dropped. Capped by code point (Array.from iterates
94
+ * code points) rather than by `.slice()`'s UTF-16 units, so a title truncated at the boundary
95
+ * can't be left with a split surrogate pair (a half-emoji / lone surrogate).
96
+ */
97
+ export function normalizeArtifactName(value) {
98
+ return (Array.from((value ?? '').trim())
99
+ .slice(0, MAX_ARTIFACT_NAME_LENGTH)
100
+ .join('') || undefined);
101
+ }
85
102
  /**
86
103
  * Extract and normalize the fields `namingFunction` cares about from raw
87
104
  * `Upload-Metadata`. Doesn't validate — the caller still checks `artifactId`
@@ -100,26 +117,57 @@ function parseUploadMetadata(metadata) {
100
117
  const rawRelatedTo = (metadata?.relatedTo ?? '').trim();
101
118
  const relatedTo = isUuid(rawRelatedTo) ? rawRelatedTo : undefined;
102
119
  const checksum = (metadata?.checksum ?? '').trim() || undefined;
103
- // Free-form display title. Trim, then hard-cap length so a hostile or buggy
104
- // client can't bloat the sidecar; an all-whitespace/empty value is dropped.
105
- // Cap by code point (Array.from iterates code points) rather than by
106
- // `.slice()`'s UTF-16 units, so a title truncated at the boundary can't be
107
- // left with a split surrogate pair (a half-emoji / lone surrogate).
108
- const name = Array.from((metadata?.name ?? '').trim())
109
- .slice(0, MAX_ARTIFACT_NAME_LENGTH)
110
- .join('') || undefined;
120
+ // Free-form display title, trimmed and capped (see `normalizeArtifactName`).
121
+ const name = normalizeArtifactName(metadata?.name);
111
122
  // The uploading app's version (PROTOCOL.md §4), trimmed and capped like `name`.
112
123
  const appVersion = normalizeAppVersion(metadata?.appVersion);
113
124
  return { artifactId, filename, kind, relatedTo, checksum, name, appVersion };
114
125
  }
115
126
  export function createPulsevaultTusServer(options) {
116
- const { storage, tusPath, maxSize, allowedExtensions, validatePayload, onUploadComplete, onArtifactEvent, logger = consoleLogger, } = options;
127
+ const { storage, tusPath, maxSize, allowedExtensions, validatePayload, completion, onArtifactEvent, pulseShape, reclaim, isLocked, logger = consoleLogger, } = options;
128
+ // Creates for one artifactId run one at a time in this process, so two creates that both
129
+ // find the same idle upload can't both remove it and the second clobber the first's
130
+ // replacement. (Across instances the local adapter's exclusive sidecar write still decides.)
131
+ const creating = new Map();
132
+ const serializeCreate = async (artifactId, work) => {
133
+ const previous = creating.get(artifactId) ?? Promise.resolve();
134
+ const run = previous.catch(() => { }).then(work);
135
+ creating.set(artifactId, run);
136
+ try {
137
+ return await run;
138
+ }
139
+ finally {
140
+ if (creating.get(artifactId) === run)
141
+ creating.delete(artifactId);
142
+ }
143
+ };
117
144
  const server = new Server({
118
145
  path: tusPath,
119
146
  datastore: withArtifactRemoval(storage, async (artifactId, kind) => {
120
147
  await onArtifactEvent?.({ phase: 'remove', artifactId, kind, reason: 'deleted' });
121
- }),
148
+ }, isLocked),
122
149
  maxSize,
150
+ // tus refuses an upload over `maxSize` with "Maximum size exceeded" at create (the constant)
151
+ // or mid-stream (`StreamLimiter`'s own error, same status and body), and one whose length was
152
+ // deferred with "upload's size exceeded" when a chunk would take it past `maxSize`. Say it in
153
+ // the words a host can show the person who picked the file. (That second error also means a
154
+ // chunk past the length the client declared — a client bug, left as tus words it.)
155
+ onResponseError: async (req, err) => {
156
+ const { status_code, body } = err;
157
+ const tooLarge = { status_code: 413, body: `That file is larger than ${formatBytes(maxSize)}.\n` };
158
+ if (status_code === ERRORS.ERR_MAX_SIZE_EXCEEDED.status_code && body === ERRORS.ERR_MAX_SIZE_EXCEEDED.body) {
159
+ return tooLarge;
160
+ }
161
+ if (status_code === ERRORS.ERR_SIZE_EXCEEDED.status_code && body === ERRORS.ERR_SIZE_EXCEEDED.body) {
162
+ const encoded = new URL(req.url).pathname.split('/').pop();
163
+ const upload = encoded
164
+ ? await storage.datastore.getUpload(Buffer.from(encoded, 'base64url').toString('utf8')).catch(() => null)
165
+ : null;
166
+ if (upload?.sizeIsDeferred)
167
+ return tooLarge;
168
+ }
169
+ return undefined;
170
+ },
123
171
  namingFunction: async (_req, metadata) => {
124
172
  const { artifactId, filename, kind, relatedTo, checksum, name, appVersion } = parseUploadMetadata(metadata);
125
173
  if (!isUuid(artifactId)) {
@@ -139,7 +187,19 @@ export function createPulsevaultTusServer(options) {
139
187
  store.relatedTo = relatedTo;
140
188
  store.checksum = checksum;
141
189
  }
142
- return storage.reserveUpload({
190
+ // The shape of a pulse (PROTOCOL.md §8): the video is the anchor, created under the id the
191
+ // pairing link named, with no `relatedTo`; its thumbnail, beat manifest and captions are
192
+ // created under ids of their own, `relatedTo` the video. `createCapabilityAuthorize` also
193
+ // ties the ids to the token; this structural check holds for any `authorize`.
194
+ if (pulseShape) {
195
+ if (kind === 'video' && relatedTo !== undefined) {
196
+ throw tusError(403, 'A video is uploaded under its own artifactId, with no `relatedTo`.\n');
197
+ }
198
+ if (kind !== 'video' && (relatedTo === undefined || relatedTo === artifactId)) {
199
+ throw tusError(403, `A ${kind} is uploaded under its own artifactId, \`relatedTo\` the video it belongs to.\n`);
200
+ }
201
+ }
202
+ const params = {
143
203
  artifactId,
144
204
  filename,
145
205
  ext,
@@ -148,6 +208,35 @@ export function createPulsevaultTusServer(options) {
148
208
  checksum,
149
209
  name,
150
210
  appVersion,
211
+ ...(store?.context !== undefined ? { context: store.context } : {}),
212
+ };
213
+ return serializeCreate(artifactId, async () => {
214
+ try {
215
+ return await storage.reserveUpload(params);
216
+ }
217
+ catch (err) {
218
+ if (statusCodeOf(err, 500) !== 409 || !reclaim)
219
+ throw err;
220
+ // The id is taken. If it's an unfinished upload of the same kind and `relatedTo` — so
221
+ // the token that authorized this create authorized that one — that has been idle long
222
+ // enough to be abandoned (an app killed mid-upload sends no TUS DELETE; the person
223
+ // scanned the same link again), take it over instead of answering 409 until `retention`.
224
+ const existing = await storage.describeArtifact?.(artifactId);
225
+ // An adapter that can't say when the upload last moved (`updatedAt` 0) never reclaims.
226
+ const idleMs = existing && existing.updatedAt > 0 ? Date.now() - existing.updatedAt : -1;
227
+ if (!existing ||
228
+ existing.ready ||
229
+ existing.kind !== kind ||
230
+ existing.relatedTo !== relatedTo ||
231
+ !(idleMs >= reclaim.idleSeconds * 1000)) {
232
+ throw err;
233
+ }
234
+ if (!(await storage.remove?.(artifactId)))
235
+ throw err;
236
+ logger.info({ artifactId, kind, idleMs }, 'pulsevault reclaimed an idle unfinished upload');
237
+ await onArtifactEvent?.({ phase: 'remove', artifactId, kind, reason: 'reclaimed' });
238
+ return storage.reserveUpload(params);
239
+ }
151
240
  });
152
241
  },
153
242
  // Relative Location (RFC 7231 §7.1.2) so the upload URL is correct behind
@@ -181,6 +270,21 @@ export function createPulsevaultTusServer(options) {
181
270
  const uploadId = upload.id;
182
271
  // Reported on the complete/reject events so an operator can see which app build sent it.
183
272
  const appVersion = normalizeAppVersion(upload.metadata?.appVersion);
273
+ // A final PATCH the client retried after losing the 204 finishes an upload that already
274
+ // finished. Its bytes were validated then, and may since have been rewritten for the web
275
+ // (so a checksum check would fail and remove a delivered video): only the completion
276
+ // bookkeeping runs again, which itself skips a hook that was recorded.
277
+ const finished = (await storage.describeArtifact?.(artifactId))?.ready ?? false;
278
+ if (finished) {
279
+ try {
280
+ await completion.complete(store.request, { artifactId, kind: await resolveKind(storage, artifactId), size, uploadId });
281
+ }
282
+ catch (err) {
283
+ logger.error({ err, artifactId }, 'pulsevault onUploadComplete failed');
284
+ throw tusError(500, 'Upload completion hook failed\n');
285
+ }
286
+ return {};
287
+ }
184
288
  // Resolve kind/checksum: prefer the context value (set during the same
185
289
  // request's namingFunction for single-request uploads), fall back to a
186
290
  // storage lookup (cheap in-memory cache hit) for chunked uploads, or —
@@ -246,22 +350,22 @@ export function createPulsevaultTusServer(options) {
246
350
  logger.error({ err, artifactId, kind }, 'pulsevault markReady failed');
247
351
  throw tusError(500, 'Upload finalization failed\n');
248
352
  }
249
- // 3. Consumer hook — business logic (DB writes, queue jobs).
250
- if (onUploadComplete) {
251
- try {
252
- await onUploadComplete(store.request, { artifactId, kind, size, uploadId });
253
- }
254
- catch (err) {
255
- // Propagate as a tus error so the client sees a non-2xx and can
256
- // distinguish "bytes stored but completion hook failed" from
257
- // success. The artifact is marked ready at this point — consumers
258
- // who want "all-or-nothing" should `storage.remove` before
259
- // throwing.
260
- // The real error (often a consumer DB failure whose message can leak
261
- // schema/infra detail) stays in the server log, not the client body.
262
- logger.error({ err, artifactId, kind }, 'pulsevault onUploadComplete failed');
263
- throw tusError(500, 'Upload completion hook failed\n');
264
- }
353
+ // 3. Consumer hook — business logic (DB writes, queue jobs) — through the completion
354
+ // runner, which records that the hook finished (so one that didn't is replayed) and
355
+ // runs the background web-ready conversion.
356
+ try {
357
+ await completion.complete(store.request, { artifactId, kind, size, uploadId });
358
+ }
359
+ catch (err) {
360
+ // Propagate as a tus error so the client sees a non-2xx and can
361
+ // distinguish "bytes stored but completion hook failed" from
362
+ // success. The artifact is marked ready at this point, and the
363
+ // completion is replayed later — consumers who want "all-or-nothing"
364
+ // should `storage.remove` before throwing.
365
+ // The real error (often a consumer DB failure whose message can leak
366
+ // schema/infra detail) stays in the server log, not the client body.
367
+ logger.error({ err, artifactId, kind }, 'pulsevault onUploadComplete failed');
368
+ throw tusError(500, 'Upload completion hook failed\n');
265
369
  }
266
370
  await onArtifactEvent?.({
267
371
  phase: 'complete',
@@ -321,6 +425,19 @@ function hardenAgainstClientAbort(server, logger) {
321
425
  };
322
426
  }
323
427
  }
428
+ /** `524288000` → "500 MB", `1610612736` → "1.5 GB" (binary units, as hosts usually set them). */
429
+ function formatBytes(bytes) {
430
+ if (bytes === 1)
431
+ return '1 byte';
432
+ const units = ['bytes', 'KB', 'MB', 'GB', 'TB'];
433
+ let value = bytes;
434
+ let unit = 0;
435
+ while (value >= 1024 && unit < units.length - 1) {
436
+ value /= 1024;
437
+ unit++;
438
+ }
439
+ return `${Math.round(value * 10) / 10} ${units[unit]}`;
440
+ }
324
441
  /**
325
442
  * Resolve the artifact kind from storage for a known artifactId. Used by
326
443
  * `onUploadFinish` for chunked uploads where the kind is not in the current
@@ -1 +1 @@
1
- {"version":3,"file":"pulsevaultTus.js","sourceRoot":"","sources":["../../src/lib/pulsevaultTus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pulsevaultTus.js","sourceRoot":"","sources":["../../src/lib/pulsevaultTus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAiD,aAAa,EAAE,MAAM,cAAc,CAAC;AAG5F,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AA6BtD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,iBAAiB,EAAwB,CAAC;AA8ClF;;;;;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;;;;;;;;GAQG;AACH,SAAS,mBAAmB,CAC1B,OAA0B,EAC1B,SAAmE,EACnE,QAAmD;IAEnD,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACnD,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE;QAC1B,GAAG,CAAC,MAAM,EAAE,IAAI;YACd,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,KAAK,EAAE,EAAU,EAAiB,EAAE;oBACzC,MAAM,UAAU,GAAG,sBAAsB,CAAC,EAAE,CAAC,CAAC;oBAC9C,uFAAuF;oBACvF,oFAAoF;oBACpF,uCAAuC;oBACvC,IAAI,UAAU,IAAI,QAAQ,IAAI,CAAC,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;wBAC3D,MAAM,QAAQ,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;oBACzD,CAAC;oBACD,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC7E,oFAAoF;oBACpF,sEAAsE;oBACtE,IAAI,aAAa,GAAG,KAAK,CAAC;oBAC1B,IAAI,WAAoB,CAAC;oBACzB,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBACxB,aAAa,GAAG,IAAI,CAAC;oBACvB,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,iFAAiF;wBACjF,WAAW,GAAG,GAAG,CAAC;oBACpB,CAAC;oBACD,MAAM,eAAe,GAAG,UAAU,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;oBAChG,IAAI,UAAU,IAAI,IAAI,IAAI,eAAe,EAAE,CAAC;wBAC1C,MAAM,SAAS,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;oBACtC,CAAC;oBACD,IAAI,CAAC,aAAa,IAAI,CAAC,eAAe;wBAAE,MAAM,WAAW,CAAC;gBAC5D,CAAC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACzD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAClE,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,sBAAsB,CAAC,EAAU;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IACxE,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAErC;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAgC;IACpE,OAAO,CACL,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SAC7B,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC;SAClC,IAAI,CAAC,EAAE,CAAC,IAAI,SAAS,CACzB,CAAC;AACJ,CAAC;AAYD;;;;GAIG;AACH,SAAS,mBAAmB,CAC1B,QAAmD;IAEnD,wEAAwE;IACxE,6CAA6C;IAC7C,MAAM,UAAU,GAAG,CACjB,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,OAAO;QACjB,QAAQ,EAAE,SAAS;QACnB,EAAE,CACH,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,yGAAyG;IACzG,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IAChE,6EAA6E;IAC7E,MAAM,IAAI,GAAG,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEnD,gFAAgF;IAChF,MAAM,UAAU,GAAG,mBAAmB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAE7D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,OAA6B;IACrE,MAAM,EACJ,OAAO,EACP,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,eAAe,EACf,UAAU,EACV,OAAO,EACP,QAAQ,EACR,MAAM,GAAG,aAAa,GACvB,GAAG,OAAO,CAAC;IAEZ,yFAAyF;IACzF,oFAAoF;IACpF,6FAA6F;IAC7F,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;IACrD,MAAM,eAAe,GAAG,KAAK,EAAK,UAAkB,EAAE,IAAsB,EAAc,EAAE;QAC1F,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,CAAC;QACnB,CAAC;gBAAS,CAAC;YACT,IAAI,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG;gBAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,mBAAmB,CAC5B,OAAO,EACP,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;YACzB,MAAM,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACpF,CAAC,EACD,QAAQ,CACT;QACD,OAAO;QACP,6FAA6F;QAC7F,8FAA8F;QAC9F,8FAA8F;QAC9F,4FAA4F;QAC5F,mFAAmF;QACnF,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YAClC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,GAA8C,CAAC;YAC7E,MAAM,QAAQ,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,4BAA4B,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnG,IAAI,WAAW,KAAK,MAAM,CAAC,qBAAqB,CAAC,WAAW,IAAI,IAAI,KAAK,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;gBAC3G,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,IAAI,WAAW,KAAK,MAAM,CAAC,iBAAiB,CAAC,WAAW,IAAI,IAAI,KAAK,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;gBACnG,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBAC3D,MAAM,MAAM,GAAG,OAAO;oBACpB,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;oBACzG,CAAC,CAAC,IAAI,CAAC;gBACT,IAAI,MAAM,EAAE,cAAc;oBAAE,OAAO,QAAQ,CAAC;YAC9C,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACvC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,GACzE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxB,MAAM,QAAQ,CAAC,GAAG,EAAE,2DAA2D,CAAC,CAAC;YACnF,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnC,MAAM,QAAQ,CACZ,GAAG,EACH,0CAA0C,IAAI,2BAA2B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAChG,CAAC;YACJ,CAAC;YAED,wEAAwE;YACxE,oEAAoE;YACpE,uDAAuD;YACvD,MAAM,KAAK,GAAG,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YAC9C,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;gBAClB,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC5B,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC5B,CAAC;YAED,2FAA2F;YAC3F,yFAAyF;YACzF,0FAA0F;YAC1F,8EAA8E;YAC9E,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,IAAI,KAAK,OAAO,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;oBAChD,MAAM,QAAQ,CAAC,GAAG,EAAE,sEAAsE,CAAC,CAAC;gBAC9F,CAAC;gBACD,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,UAAU,CAAC,EAAE,CAAC;oBAC9E,MAAM,QAAQ,CACZ,GAAG,EACH,KAAK,IAAI,iFAAiF,CAC3F,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG;gBACb,UAAU;gBACV,QAAQ;gBACR,GAAG;gBACH,IAAI;gBACJ,SAAS;gBACT,QAAQ;gBACR,IAAI;gBACJ,UAAU;gBACV,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpE,CAAC;YACF,OAAO,eAAe,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;gBAC9C,IAAI,CAAC;oBACH,OAAO,MAAM,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBAC7C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO;wBAAE,MAAM,GAAG,CAAC;oBAC1D,sFAAsF;oBACtF,sFAAsF;oBACtF,mFAAmF;oBACnF,yFAAyF;oBACzF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC,UAAU,CAAC,CAAC;oBAC9D,uFAAuF;oBACvF,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzF,IACE,CAAC,QAAQ;wBACT,QAAQ,CAAC,KAAK;wBACd,QAAQ,CAAC,IAAI,KAAK,IAAI;wBACtB,QAAQ,CAAC,SAAS,KAAK,SAAS;wBAChC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,EACvC,CAAC;wBACD,MAAM,GAAG,CAAC;oBACZ,CAAC;oBACD,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC;wBAAE,MAAM,GAAG,CAAC;oBACrD,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,gDAAgD,CAAC,CAAC;oBAC5F,MAAM,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;oBACpF,OAAO,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBACvC,CAAC;YACD,CAAC,CAAC,CAAC;QACL,CAAC;QACD,0EAA0E;QAC1E,qEAAqE;QACrE,yEAAyE;QACzE,WAAW,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC9D,OAAO,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC;QACrC,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,UAAU,GAAG,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;YAC3B,yFAAyF;YACzF,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAEpE,wFAAwF;YACxF,yFAAyF;YACzF,qFAAqF;YACrF,uEAAuE;YACvE,MAAM,QAAQ,GAAG,CAAC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC;YAChF,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC;oBACH,MAAM,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACzH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,oCAAoC,CAAC,CAAC;oBACxE,MAAM,QAAQ,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,uEAAuE;YACvE,uEAAuE;YACvE,uEAAuE;YACvE,qEAAqE;YACrE,oEAAoE;YACpE,kEAAkE;YAClE,qCAAqC;YACrC,MAAM,IAAI,GAAe,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;YAChF,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;YAEhF,oEAAoE;YACpE,oEAAoE;YACpE,gEAAgE;YAChE,uEAAuE;YACvE,kEAAkE;YAClE,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE;wBACnC,UAAU;wBACV,IAAI;wBACJ,QAAQ;wBACR,SAAS,EAAE,MAAM,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC;wBACtD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjC,IAAI;qBACL,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;oBACtC,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;oBACjF,IAAI,CAAC;wBACH,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC;oBACrC,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,6CAA6C,CAAC,CAAC;oBAC1F,CAAC;oBACD,MAAM,eAAe,EAAE,CAAC;wBACtB,KAAK,EAAE,QAAQ;wBACf,UAAU;wBACV,IAAI;wBACJ,IAAI;wBACJ,MAAM,EAAE,OAAO;wBACf,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACtC,CAAC,CAAC;oBACH,kEAAkE;oBAClE,qEAAqE;oBACrE,oEAAoE;oBACpE,0BAA0B;oBAC1B,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;wBAClB,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,uCAAuC,CAAC,CAAC;wBACjF,MAAM,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;oBACxD,CAAC;oBACD,MAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YAED,oEAAoE;YACpE,kEAAkE;YAClE,oEAAoE;YACpE,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,sEAAsE;gBACtE,sEAAsE;gBACtE,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,6BAA6B,CAAC,CAAC;gBACvE,MAAM,QAAQ,CAAC,GAAG,EAAE,8BAA8B,CAAC,CAAC;YACtD,CAAC;YAED,qFAAqF;YACrF,uFAAuF;YACvF,+CAA+C;YAC/C,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACjF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,gEAAgE;gBAChE,6DAA6D;gBAC7D,+DAA+D;gBAC/D,qEAAqE;gBACrE,2CAA2C;gBAC3C,qEAAqE;gBACrE,qEAAqE;gBACrE,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,oCAAoC,CAAC,CAAC;gBAC9E,MAAM,QAAQ,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;YACzD,CAAC;YAED,MAAM,eAAe,EAAE,CAAC;gBACtB,KAAK,EAAE,UAAU;gBACjB,UAAU;gBACV,IAAI;gBACJ,IAAI;gBACJ,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtC,CAAC,CAAC;YAEH,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC,CAAC;IAEH,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAS,wBAAwB,CAAC,MAAc,EAAE,MAAwB;IACxE,MAAM,QAAQ,GAAI,MAA4D,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC9F,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,MAAM,CAAU,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAElB,CAAC;QACd,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YAC3D,MAAM,CAAC,IAAI,CACT,EAAE,MAAM,EAAE,EACV,0EAA0E,CAC3E,CAAC;YACF,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,CAAC,YAAY,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE;YACvC,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC1C,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAY,EAAE,EAAE;oBAChC,uFAAuF;oBACvF,wFAAwF;oBACxF,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;oBAC9E,MAAM,GAAG,GAAG,2EAA2E,CAAC;oBACxF,IAAI,MAAM,CAAC,KAAK;wBAAE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;;wBACpC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC7B,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,IAAI,IAAI,CAAC;QACd,IAAI,EAAE,CAAC;IACT,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,WAAW,CAAC,OAA0B,EAAE,UAAkB;IACvE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;IACnD,OAAO,MAAM,IAAI,OAAO,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe,CAC5B,OAA0B,EAC1B,UAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,CAAC;IACvD,OAAO,MAAM,IAAI,SAAS,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,gBAAgB,CAC7B,OAA0B,EAC1B,UAAkB;IAElB,MAAM,OAAO,GAAG,OAA4E,CAAC;IAC7F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC"}