@mieweb/pulsevault 0.5.0 → 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 (51) hide show
  1. package/CHANGELOG.md +127 -1
  2. package/OPERATIONS.md +123 -46
  3. package/PROTOCOL.md +27 -5
  4. package/README.md +28 -8
  5. package/dist/app.d.ts +7 -6
  6. package/dist/app.d.ts.map +1 -1
  7. package/dist/app.js +4 -3
  8. package/dist/app.js.map +1 -1
  9. package/dist/core.d.ts +22 -8
  10. package/dist/core.d.ts.map +1 -1
  11. package/dist/core.js +90 -17
  12. package/dist/core.js.map +1 -1
  13. package/dist/lib/completion.d.ts +8 -5
  14. package/dist/lib/completion.d.ts.map +1 -1
  15. package/dist/lib/completion.js +121 -34
  16. package/dist/lib/completion.js.map +1 -1
  17. package/dist/lib/deeplinks.d.ts +18 -2
  18. package/dist/lib/deeplinks.d.ts.map +1 -1
  19. package/dist/lib/deeplinks.js +13 -2
  20. package/dist/lib/deeplinks.js.map +1 -1
  21. package/dist/lib/magic.d.ts +41 -1
  22. package/dist/lib/magic.d.ts.map +1 -1
  23. package/dist/lib/magic.js +104 -0
  24. package/dist/lib/magic.js.map +1 -1
  25. package/dist/lib/options.d.ts +2 -0
  26. package/dist/lib/options.d.ts.map +1 -1
  27. package/dist/lib/options.js +8 -4
  28. package/dist/lib/options.js.map +1 -1
  29. package/dist/lib/protocol-version.gen.js +1 -1
  30. package/dist/lib/pulsevaultTus.d.ts.map +1 -1
  31. package/dist/lib/pulsevaultTus.js +35 -1
  32. package/dist/lib/pulsevaultTus.js.map +1 -1
  33. package/dist/lib/web-ready.d.ts +138 -18
  34. package/dist/lib/web-ready.d.ts.map +1 -1
  35. package/dist/lib/web-ready.js +453 -91
  36. package/dist/lib/web-ready.js.map +1 -1
  37. package/dist/storage/local.d.ts.map +1 -1
  38. package/dist/storage/local.js +241 -50
  39. package/dist/storage/local.js.map +1 -1
  40. package/dist/storage/s3.d.ts.map +1 -1
  41. package/dist/storage/s3.js +21 -1
  42. package/dist/storage/s3.js.map +1 -1
  43. package/dist/storage/types.d.ts +57 -4
  44. package/dist/storage/types.d.ts.map +1 -1
  45. package/dist/storage/types.js +7 -0
  46. package/dist/storage/types.js.map +1 -1
  47. package/package.json +2 -2
  48. package/protocol/openapi.json +26 -3
  49. package/protocol/schemas/artifact-status.schema.json +13 -1
  50. package/protocol/schemas/deep-link.schema.json +2 -2
  51. package/scripts/web-ready-migrate.mjs +35 -11
@@ -1,5 +1,8 @@
1
- import { ensureWebReady } from './web-ready.js';
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { CONFORM_TARGET, ensureWebReady, validateWebReadyOptions, } from './web-ready.js';
2
4
  import { consoleLogger } from './request.js';
5
+ import { uploadIdOf } from '../storage/types.js';
3
6
  const DEFAULT_REPLAY_INTERVAL_SECONDS = 300;
4
7
  /** The first replay after start: late enough for the host to finish booting. */
5
8
  const FIRST_REPLAY_DELAY_MS = 5_000;
@@ -11,14 +14,15 @@ export function validateCompletionOptions(opts) {
11
14
  if (typeof opts.storage.getLocalPath !== 'function') {
12
15
  throw new TypeError('`webReady` needs a storage adapter with `getLocalPath` (the local adapter): ffmpeg rewrites the file in place');
13
16
  }
14
- if (typeof opts.storage.patchArtifact !== 'function') {
15
- throw new TypeError('`webReady` needs a storage adapter with `patchArtifact`');
17
+ if (typeof opts.storage.patchArtifact !== 'function' || typeof opts.storage.describeArtifact !== 'function') {
18
+ throw new TypeError('`webReady` needs a storage adapter with `patchArtifact` and `describeArtifact`');
16
19
  }
17
20
  if (typeof opts.webReady === 'object') {
18
21
  const { concurrency } = opts.webReady;
19
22
  if (concurrency !== undefined && !(Number.isInteger(concurrency) && concurrency >= 1)) {
20
23
  throw new TypeError('`webReady.concurrency` must be a positive integer');
21
24
  }
25
+ validateWebReadyOptions(opts.webReady);
22
26
  }
23
27
  }
24
28
  if (opts.replay) {
@@ -42,11 +46,15 @@ function contextFor(meta, upload, replay) {
42
46
  size: upload.size,
43
47
  uploadId: upload.uploadId,
44
48
  filename: meta?.filename ?? '',
45
- ext: meta?.ext ?? '',
49
+ // `filename`'s extension, as documented: the uploaded one, even once a conversion changed it.
50
+ ext: meta ? (meta.sourceExt ?? meta.ext) : '',
46
51
  ...(meta?.relatedTo ? { relatedTo: meta.relatedTo } : {}),
47
52
  ...(meta?.name ? { name: meta.name } : {}),
48
53
  ...(meta?.appVersion ? { appVersion: meta.appVersion } : {}),
49
54
  ...(meta?.context !== undefined ? { context: meta.context } : {}),
55
+ // What a conversion did, once one was recorded: a replayed hook gets it too, so a host that
56
+ // names the file from it (an `.mp4` once a WebM was conformed) gets it right the second time.
57
+ ...(meta?.converted && meta.webReady ? { webReady: meta.webReady } : {}),
50
58
  replay,
51
59
  };
52
60
  }
@@ -114,23 +122,96 @@ export function createCompletionRunner(opts) {
114
122
  logger.error({ err, artifactId, patch }, 'pulsevault could not record a completion step');
115
123
  }
116
124
  };
117
- /** Rule 1. Never throws: a failed conversion serves the original bytes and is tried again later. */
118
- const convert = (ctx) => new Promise((resolve) => {
125
+ /**
126
+ * Record a conversion's result, and install the file it wrote (`outputPath`, a temporary
127
+ * `.mp4` beside the stored file), in one patch under the adapter's lock: only for the upload
128
+ * the conversion began on (`generation`) and only while no other pass has recorded one
129
+ * (`unlessConverted`). Another container's original is deleted by the patch once the sidecar
130
+ * names the `.mp4`. When the patch doesn't apply — the artifact was removed, or reserved again,
131
+ * or converted elsewhere meanwhile — or fails, the file it wrote goes and nothing else
132
+ * changes. Until a record is written the original serves and the next pass converts again.
133
+ * `storedExt`: the extension of the file the conversion ran on, when it isn't the one the
134
+ * sidecar names (the local adapter found the converted `.mp4` under a sidecar written from a
135
+ * copy older than the conversion): the record names that file again. Resolves whether this
136
+ * record applied.
137
+ */
138
+ const recordConversion = async (artifactId, generation, result, outputPath, storedExt) => {
139
+ let applied = false;
140
+ try {
141
+ applied =
142
+ (await storage.patchArtifact?.(artifactId, {
143
+ converted: true,
144
+ webReady: result,
145
+ unlessConverted: true,
146
+ generation,
147
+ ...(outputPath
148
+ ? { file: outputPath, ext: CONFORM_TARGET.extension }
149
+ : storedExt
150
+ ? { ext: storedExt }
151
+ : {}),
152
+ })) ?? false;
153
+ }
154
+ catch (err) {
155
+ logger.error({ err, artifactId }, 'pulsevault could not record a web-ready conversion');
156
+ }
157
+ if (!applied && outputPath)
158
+ await fs.rm(outputPath, { force: true });
159
+ return applied;
160
+ };
161
+ /**
162
+ * Rule 1, for the reservation the work was scheduled for (`generation`; `undefined` when the
163
+ * adapter can't say). Never throws: a failed conversion serves the original bytes, and says why.
164
+ */
165
+ const convert = (ctx, generation) => new Promise((resolve) => {
119
166
  void queue.run(async () => {
120
167
  try {
168
+ // What was read before this job waited for its slot may be stale: the artifact may
169
+ // have been removed — and its id reserved again by another upload, which isn't this
170
+ // job's — or converted by another instance on the same disk, meanwhile.
171
+ const fresh = await describe(ctx.artifactId);
172
+ if (!fresh || !fresh.ready || (generation !== undefined && (fresh.generation ?? null) !== generation)) {
173
+ resolve(undefined);
174
+ return;
175
+ }
176
+ if (fresh.converted) {
177
+ resolve(fresh.webReady);
178
+ return;
179
+ }
121
180
  const localPath = await storage.getLocalPath?.(ctx.artifactId);
122
- const result = typeof localPath === 'string'
123
- ? await ensureWebReady(localPath, { ...webReady, logger })
124
- : { action: 'skipped', reason: 'no local path for this artifact' };
125
- await record(ctx.artifactId, { converted: true });
126
- await onArtifactEvent?.({
127
- phase: 'processed',
128
- artifactId: ctx.artifactId,
129
- kind: ctx.kind,
130
- size: ctx.size,
131
- reason: result.reason,
132
- webReady: result,
133
- });
181
+ // `install: false`: the file is installed by the record below, under the adapter's
182
+ // lock and conditions, never renamed over the stored file from here. Only with a
183
+ // generation: a conversion takes long enough for the id to be removed and uploaded
184
+ // again, and without one the record couldn't tell this upload from that one.
185
+ const { outputPath, ...result } = typeof localPath !== 'string'
186
+ ? { action: 'skipped', reason: 'no local path for this artifact', outputPath: undefined }
187
+ : !fresh.generation
188
+ ? { action: 'skipped', reason: 'the storage adapter keeps no generation for this upload', outputPath: undefined }
189
+ : await ensureWebReady(localPath, { ...webReady, logger, install: false });
190
+ const expected = generation !== undefined ? generation : (fresh.generation ?? null);
191
+ const localExt = typeof localPath === 'string' ? path.extname(localPath).toLowerCase() : '';
192
+ const storedExt = localExt && localExt !== fresh.ext ? localExt : undefined;
193
+ if (!(await recordConversion(ctx.artifactId, expected, result, outputPath, storedExt))) {
194
+ // Lost to another pass: its result, but only while the id is still this reservation's
195
+ // (a removal and a new upload of the id would hand back the new upload's result).
196
+ const now = await describe(ctx.artifactId);
197
+ resolve(now && (now.generation ?? null) === expected ? now.webReady : undefined);
198
+ return;
199
+ }
200
+ // The result is recorded: an observer that throws is the observer's failure, not the
201
+ // conversion's, and doesn't hide the result from the hook that follows it.
202
+ try {
203
+ await onArtifactEvent?.({
204
+ phase: 'processed',
205
+ artifactId: ctx.artifactId,
206
+ kind: ctx.kind,
207
+ size: ctx.size,
208
+ reason: result.reason,
209
+ webReady: result,
210
+ });
211
+ }
212
+ catch (err) {
213
+ logger.error({ err, artifactId: ctx.artifactId }, 'pulsevault onArtifactEvent (processed) failed');
214
+ }
134
215
  resolve(result);
135
216
  }
136
217
  catch (err) {
@@ -139,14 +220,18 @@ export function createCompletionRunner(opts) {
139
220
  }
140
221
  });
141
222
  });
142
- /** Rule 2. Rethrows what the hook threw. */
143
- const hook = async (request, ctx) => {
223
+ /** Rule 2, recorded only on the reservation it ran for. Rethrows what the hook threw. */
224
+ const hook = async (request, ctx, generation) => {
144
225
  if (onUploadComplete)
145
226
  await onUploadComplete(request, ctx);
146
- await record(ctx.artifactId, { acknowledged: true });
227
+ await record(ctx.artifactId, { acknowledged: true, ...(generation !== undefined ? { generation } : {}) });
147
228
  };
148
- /** One artifact is settled by one caller at a time; a second caller joins the first. */
229
+ /**
230
+ * One upload is settled by one caller at a time; a second caller joins the first. Keyed by the
231
+ * reservation too: a new upload of an id that was removed is never joined to the old one's.
232
+ */
149
233
  const settling = new Map();
234
+ const settlingKey = (artifactId, generation) => `${artifactId}/${generation ?? ''}`;
150
235
  /**
151
236
  * Apply the rule to one finished artifact. The request that finished the upload waits on the
152
237
  * result: it rejects when the hook threw, so the client gets a non-2xx — except with
@@ -155,7 +240,9 @@ export function createCompletionRunner(opts) {
155
240
  * logged and left for the next pass.
156
241
  */
157
242
  const settle = (request, meta, upload, replay) => {
158
- const running = settling.get(upload.artifactId);
243
+ const generation = meta ? (meta.generation ?? null) : undefined;
244
+ const key = settlingKey(upload.artifactId, generation);
245
+ const running = settling.get(key);
159
246
  if (running)
160
247
  return running;
161
248
  const ctx = contextFor(meta, upload, replay);
@@ -169,32 +256,32 @@ export function createCompletionRunner(opts) {
169
256
  if (needsConversion && completeAfter) {
170
257
  // Nothing for the request to wait on: the hook follows the conversion.
171
258
  run = (async () => {
172
- const result = await convert(ctx);
259
+ const result = await convert(ctx, generation);
173
260
  if (!needsHook)
174
261
  return;
175
262
  try {
176
- await hook(request, { ...ctx, ...(result ? { webReady: result } : {}) });
263
+ await hook(request, { ...ctx, ...(result ? { webReady: result } : {}) }, generation);
177
264
  }
178
265
  catch (err) {
179
266
  logger.error({ err, artifactId: ctx.artifactId, kind: ctx.kind }, 'pulsevault onUploadComplete failed after web-ready; it will be tried again');
180
267
  }
181
268
  })();
182
- settling.set(upload.artifactId, run);
183
- void run.finally(() => settling.delete(upload.artifactId));
269
+ settling.set(key, run);
270
+ void run.finally(() => settling.delete(key));
184
271
  return Promise.resolve();
185
272
  }
186
273
  run = (async () => {
187
- const conversion = needsConversion ? convert(ctx) : Promise.resolve(undefined);
274
+ const conversion = needsConversion ? convert(ctx, generation) : Promise.resolve(undefined);
188
275
  try {
189
276
  if (needsHook)
190
- await hook(request, ctx);
277
+ await hook(request, ctx, generation);
191
278
  }
192
279
  finally {
193
280
  // The settle covers the conversion too, so a replay doesn't queue it again meanwhile.
194
- void conversion.finally(() => settling.delete(upload.artifactId));
281
+ void conversion.finally(() => settling.delete(key));
195
282
  }
196
283
  })();
197
- settling.set(upload.artifactId, run);
284
+ settling.set(key, run);
198
285
  return run;
199
286
  };
200
287
  const complete = async (request, upload) => settle(request, await describe(upload.artifactId), upload, false);
@@ -219,7 +306,7 @@ export function createCompletionRunner(opts) {
219
306
  }
220
307
  const pending = [];
221
308
  for await (const record of storage.listArtifacts()) {
222
- if (!record.ready || settling.has(record.artifactId))
309
+ if (!record.ready)
223
310
  continue;
224
311
  let meta;
225
312
  try {
@@ -229,11 +316,11 @@ export function createCompletionRunner(opts) {
229
316
  logger.error({ err, artifactId: record.artifactId }, 'pulsevault replay could not read an artifact');
230
317
  continue;
231
318
  }
232
- if (!meta || !meta.ready || settling.has(meta.artifactId))
319
+ if (!meta || !meta.ready || settling.has(settlingKey(meta.artifactId, meta.generation ?? null)))
233
320
  continue;
234
321
  if (meta.acknowledged && !(converts(meta.kind) && !meta.converted))
235
322
  continue;
236
- const uploadId = `${meta.kind}/${meta.artifactId}${meta.ext}`;
323
+ const uploadId = uploadIdOf(meta);
237
324
  const upload = {
238
325
  artifactId: meta.artifactId,
239
326
  kind: meta.kind,
@@ -1 +1 @@
1
- {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"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"}
@@ -16,10 +16,26 @@ export type UploadLinkOptions = {
16
16
  * step. Generate with `crypto.randomUUID()`.
17
17
  */
18
18
  artifactId: string;
19
+ /**
20
+ * Which of the two equivalent link forms to build (PROTOCOL.md §3):
21
+ * - `'pulsecam'` (default): `pulsecam://?<params>`, which every Pulse app opens.
22
+ * - `'https'`: `https://mieweb.github.io/pulse/open#<params>`, a Universal Link / App Link.
23
+ * Phone cameras open it, it opens Pulse when it's installed, and its page sends the person
24
+ * to the store when it isn't. The parameters ride in the fragment, so the link host never
25
+ * receives the token. Only Pulse releases that claim the link host open it directly; an
26
+ * older Pulse lands on the page, whose "Open it" button falls back to `pulsecam://`.
27
+ */
28
+ form?: 'pulsecam' | 'https';
19
29
  };
20
30
  /**
21
- * Build a `pulsecam://` deep link that opens the Pulse app directly on the
22
- * upload screen for a specific artifact, pointed at this server.
31
+ * Where the https form of a pairing link points: the page on the link host the Pulse app
32
+ * claims. Fixed, because an app can only claim domains it was built with.
33
+ */
34
+ export declare const PULSE_OPEN_URL = "https://mieweb.github.io/pulse/open";
35
+ /**
36
+ * Build a pairing link that opens the Pulse app directly on the upload screen
37
+ * for a specific artifact, pointed at this server: `pulsecam://?<params>`, or
38
+ * with `form: 'https'`, `${PULSE_OPEN_URL}#<params>`.
23
39
  *
24
40
  * No `mode` param — there's only one mode, so it was always redundant. `v`
25
41
  * lets the app refuse/explain a future incompatible link shape instead of
@@ -1 +1 @@
1
- {"version":3,"file":"deeplinks.d.ts","sourceRoot":"","sources":["../../src/lib/deeplinks.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,gJAAgJ;IAChJ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA4BF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAqB/D"}
1
+ {"version":3,"file":"deeplinks.d.ts","sourceRoot":"","sources":["../../src/lib/deeplinks.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,gJAAgJ;IAChJ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,wCAAwC,CAAC;AA4BpE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAyB/D"}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Where the https form of a pairing link points: the page on the link host the Pulse app
3
+ * claims. Fixed, because an app can only claim domains it was built with.
4
+ */
5
+ export const PULSE_OPEN_URL = 'https://mieweb.github.io/pulse/open';
1
6
  /** Deep-link wire format version. Bump when the param shape changes incompatibly. */
2
7
  const LINK_VERSION = '1';
3
8
  /**
@@ -23,8 +28,9 @@ function isPrivateDevOrigin(url) {
23
28
  );
24
29
  }
25
30
  /**
26
- * Build a `pulsecam://` deep link that opens the Pulse app directly on the
27
- * upload screen for a specific artifact, pointed at this server.
31
+ * Build a pairing link that opens the Pulse app directly on the upload screen
32
+ * for a specific artifact, pointed at this server: `pulsecam://?<params>`, or
33
+ * with `form: 'https'`, `${PULSE_OPEN_URL}#<params>`.
28
34
  *
29
35
  * No `mode` param — there's only one mode, so it was always redundant. `v`
30
36
  * lets the app refuse/explain a future incompatible link shape instead of
@@ -37,6 +43,9 @@ function isPrivateDevOrigin(url) {
37
43
  * issued in the first place.
38
44
  */
39
45
  export function buildUploadLink(opts) {
46
+ if (opts.form !== undefined && opts.form !== 'pulsecam' && opts.form !== 'https') {
47
+ throw new Error(`buildUploadLink: \`form\` must be 'pulsecam' or 'https' (got "${String(opts.form)}")`);
48
+ }
40
49
  let server;
41
50
  try {
42
51
  server = new URL(opts.server);
@@ -55,6 +64,8 @@ export function buildUploadLink(opts) {
55
64
  });
56
65
  if (opts.token)
57
66
  params.set('token', opts.token);
67
+ if (opts.form === 'https')
68
+ return `${PULSE_OPEN_URL}#${params.toString()}`;
58
69
  return `pulsecam://?${params.toString()}`;
59
70
  }
60
71
  //# sourceMappingURL=deeplinks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deeplinks.js","sourceRoot":"","sources":["../../src/lib/deeplinks.ts"],"names":[],"mappings":"AAoBA,qFAAqF;AACrF,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,GAAQ;IAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC1B,OAAO,CACL,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,WAAW;QACpB,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QACjC,qCAAqC,CAAC,IAAI,CAAC,IAAI,CAAC;QAChD,mDAAmD,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B;QAC5F,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa;KAChD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,IAAuB;IACrD,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mDAAmD,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,sDAAsD,IAAI,CAAC,MAAM,OAAO;YACtE,uFAAuF,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,CAAC,EAAE,YAAY;QACf,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,OAAO,eAAe,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"deeplinks.js","sourceRoot":"","sources":["../../src/lib/deeplinks.ts"],"names":[],"mappings":"AA8BA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,qCAAqC,CAAC;AAEpE,qFAAqF;AACrF,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,GAAQ;IAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC1B,OAAO,CACL,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,WAAW;QACpB,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QACjC,qCAAqC,CAAC,IAAI,CAAC,IAAI,CAAC;QAChD,mDAAmD,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B;QAC5F,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa;KAChD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAAC,IAAuB;IACrD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CAAC,iEAAiE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1G,CAAC;IACD,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mDAAmD,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,sDAAsD,IAAI,CAAC,MAAM,OAAO;YACtE,uFAAuF,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,CAAC,EAAE,YAAY;QACf,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,GAAG,cAAc,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC3E,OAAO,eAAe,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AAC5C,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { PulseVaultRequest } from './request.js';
1
+ import { type PulseVaultLogger, type PulseVaultRequest } from './request.js';
2
2
  import type { LocalStorage } from '../storage/local.js';
3
3
  import type { S3Storage } from '../storage/s3.js';
4
4
  import type { UploadKind } from '../storage/types.js';
@@ -72,4 +72,44 @@ export declare function createMp4Sniffer(storage: LocalStorage): PulseVaultValid
72
72
  * ```
73
73
  */
74
74
  export declare function createS3Mp4Sniffer(storage: S3Storage): PulseVaultValidatePayload;
75
+ /**
76
+ * Whether a file's first bytes open one of the video containers PulseVault accepts: ISO base
77
+ * media (`ftyp`: MP4, MOV, M4V, 3GP), EBML (WebM, MKV) or RIFF `AVI `. A ~12-byte sniff, for
78
+ * when ffprobe isn't installed: it tells a video container from a renamed document, not a
79
+ * playable video from a broken one.
80
+ */
81
+ export declare function sniffVideo(filePath: string): Promise<boolean>;
82
+ export type VideoValidatorOptions = {
83
+ /** Refuse a video longer than this many seconds. Default: no limit. */
84
+ maxDurationSeconds?: number;
85
+ /** Path to the ffprobe binary. Default `"ffprobe"` (resolved via PATH). */
86
+ ffprobePath?: string;
87
+ /**
88
+ * Wall-clock limit for each ffprobe run, in seconds, so a malformed file can't hold the
89
+ * final `PATCH` open. Default `60`.
90
+ */
91
+ probeTimeoutSeconds?: number;
92
+ /** Where the one-time "ffprobe not found" warning goes. Defaults to `console`. */
93
+ logger?: PulseVaultLogger;
94
+ };
95
+ /**
96
+ * Build a `validatePayload` hook that checks a video by what it is, not its file name: ffprobe
97
+ * must find a video stream with a duration above zero (and, with `maxDurationSeconds`, not
98
+ * longer than that). Without ffprobe on the host it falls back to `sniffVideo` and logs once.
99
+ * Other kinds pass untouched. Needs the bytes on local disk (the local adapter).
100
+ *
101
+ * A refusal is a `422` whose message a host can show as it is: "That file isn't a video.",
102
+ * "That video is longer than the limit of 10 minutes." or, when ffprobe runs past
103
+ * `probeTimeoutSeconds` (a malformed file), "That video couldn't be checked in time."
104
+ *
105
+ * Usage:
106
+ * ```ts
107
+ * await app.register(pulseVault, {
108
+ * storage: createLocalStorage({ workspaceDir: "./data" }),
109
+ * validatePayload: createVideoValidator({ maxDurationSeconds: 600 }),
110
+ * // ...
111
+ * });
112
+ * ```
113
+ */
114
+ export declare function createVideoValidator(options?: VideoValidatorOptions): PulseVaultValidatePayload;
75
115
  //# sourceMappingURL=magic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"magic.d.ts","sourceRoot":"","sources":["../../src/lib/magic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wHAAwH;IACxH,IAAI,EAAE,UAAU,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KACE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAejE;AAaD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,yBAAyB,CAgBjF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,GAAG,yBAAyB,CAehF"}
1
+ {"version":3,"file":"magic.d.ts","sourceRoot":"","sources":["../../src/lib/magic.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wHAAwH;IACxH,IAAI,EAAE,UAAU,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KACE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAejE;AAaD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,yBAAyB,CAgBjF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,GAAG,yBAAyB,CAehF;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBnE;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAcF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,yBAAyB,CA6CnG"}
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":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,aAAa,EAAiD,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAmB,MAAM,gBAAgB,CAAC;AAgCnG;;;;;;;;;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;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,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,MAAM,IAAI,GAAG,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;QACtF,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC;QAChG,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC;IACxC,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAgBD,6GAA6G;AAC7G,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,yFAAyF;IACzF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;AACrG,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;AAExC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAiC,EAAE;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,SAAS,CAAC;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAC/C,MAAM,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,EAAE,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAU,EAAE,CAAC;QAChI,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAClE,MAAM,IAAI,SAAS,CAAC,KAAK,IAAI,yCAAyC,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,OAAe,EAAS,EAAE;QACxC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC;IACF,OAAO,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;QACzD,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO;QAC7B,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,IAAI,CAAC,CAAC,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC/B,MAAM,CAAC,KAAK,CACV,EAAE,WAAW,EAAE,EACf,oFAAoF;oBAClF,kFAAkF,CACrF,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;gBAAE,MAAM,CAAC,0BAA0B,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QACD,IAAI,KAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAC5F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,GAAG,YAAY,iBAAiB,CAAC;gBAAE,MAAM,GAAG,CAAC;YACnD,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,2CAA2C,CAAC,CAAC;YAC/E,OAAO,MAAM,CAAC,yCAAyC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,eAAe,KAAK,IAAI;YAAE,MAAM,CAAC,0BAA0B,CAAC,CAAC;QACjF,IAAI,kBAAkB,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,eAAe,IAAI,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC;YAC3F,MAAM,CAAC,0CAA0C,cAAc,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -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;AAaF;;;;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,13 +1,17 @@
1
- // The defaults are exactly what the Pulse app uploads. A host that accepts other clients adds
2
- // their extensions (`.mov`, `.m4v`, `.srt` are served with the right content types).
3
- 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;
4
7
  const DEFAULT_PROJECT_EXTENSIONS = ['.pulse', '.zip'];
5
8
  // WebVTT only — it's what the Pulse app uploads, and it carries word-level
6
9
  // inline cue timestamps (`<00:00:01.500>word`) for karaoke rendering.
7
10
  const DEFAULT_CAPTIONS_EXTENSIONS = ['.vtt'];
8
11
  // The pulse's poster frame (the draft's first-clip thumbnail).
9
12
  const DEFAULT_THUMBNAIL_EXTENSIONS = ['.jpg', '.jpeg', '.png'];
10
- const EXTENSION_REGEX = /^\.[^.\s/\\]+$/;
13
+ /** An allowed extension: one dot, then no dot, whitespace or path separator. */
14
+ export const EXTENSION_REGEX = /^\.[^.\s/\\]+$/;
11
15
  /**
12
16
  * Normalize the consumer's `allowedExtensions` option (legacy array or per-kind
13
17
  * object) into the canonical `{ video, project, captions, thumbnail }` shape