@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.
- package/CHANGELOG.md +127 -1
- package/OPERATIONS.md +123 -46
- package/PROTOCOL.md +27 -5
- package/README.md +28 -8
- package/dist/app.d.ts +7 -6
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +4 -3
- package/dist/app.js.map +1 -1
- package/dist/core.d.ts +22 -8
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +90 -17
- package/dist/core.js.map +1 -1
- package/dist/lib/completion.d.ts +8 -5
- package/dist/lib/completion.d.ts.map +1 -1
- package/dist/lib/completion.js +121 -34
- package/dist/lib/completion.js.map +1 -1
- package/dist/lib/deeplinks.d.ts +18 -2
- package/dist/lib/deeplinks.d.ts.map +1 -1
- package/dist/lib/deeplinks.js +13 -2
- package/dist/lib/deeplinks.js.map +1 -1
- package/dist/lib/magic.d.ts +41 -1
- package/dist/lib/magic.d.ts.map +1 -1
- package/dist/lib/magic.js +104 -0
- package/dist/lib/magic.js.map +1 -1
- package/dist/lib/options.d.ts +2 -0
- package/dist/lib/options.d.ts.map +1 -1
- package/dist/lib/options.js +8 -4
- package/dist/lib/options.js.map +1 -1
- package/dist/lib/protocol-version.gen.js +1 -1
- package/dist/lib/pulsevaultTus.d.ts.map +1 -1
- package/dist/lib/pulsevaultTus.js +35 -1
- package/dist/lib/pulsevaultTus.js.map +1 -1
- package/dist/lib/web-ready.d.ts +138 -18
- package/dist/lib/web-ready.d.ts.map +1 -1
- package/dist/lib/web-ready.js +453 -91
- package/dist/lib/web-ready.js.map +1 -1
- package/dist/storage/local.d.ts.map +1 -1
- package/dist/storage/local.js +241 -50
- package/dist/storage/local.js.map +1 -1
- package/dist/storage/s3.d.ts.map +1 -1
- package/dist/storage/s3.js +21 -1
- package/dist/storage/s3.js.map +1 -1
- package/dist/storage/types.d.ts +57 -4
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/types.js +7 -0
- package/dist/storage/types.js.map +1 -1
- package/package.json +2 -2
- package/protocol/openapi.json +26 -3
- package/protocol/schemas/artifact-status.schema.json +13 -1
- package/protocol/schemas/deep-link.schema.json +2 -2
- package/scripts/web-ready-migrate.mjs +35 -11
package/dist/lib/completion.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import
|
|
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
|
-
|
|
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
|
-
/**
|
|
118
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
/**
|
|
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
|
|
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(
|
|
183
|
-
void run.finally(() => settling.delete(
|
|
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(
|
|
281
|
+
void conversion.finally(() => settling.delete(key));
|
|
195
282
|
}
|
|
196
283
|
})();
|
|
197
|
-
settling.set(
|
|
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
|
|
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 =
|
|
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":"AAAA,OAAO,EAAE,cAAc,EAA6C,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAiD,MAAM,cAAc,CAAC;AA2H5F,MAAM,+BAA+B,GAAG,GAAG,CAAC;AAC5C,gFAAgF;AAChF,MAAM,qBAAqB,GAAG,KAAK,CAAC;AACpC,kFAAkF;AAClF,MAAM,cAAc,GAAsB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAM1D,2FAA2F;AAC3F,MAAM,UAAU,yBAAyB,CACvC,IAAsE;IAEtE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,IAAI,OAAQ,IAAI,CAAC,OAA4B,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YAC1E,MAAM,IAAI,SAAS,CACjB,+GAA+G,CAChH,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;YACrD,MAAM,IAAI,SAAS,CAAC,yDAAyD,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YACtC,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC;gBACtF,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QACxC,IAAI,eAAe,KAAK,SAAS,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;YAChG,MAAM,IAAI,SAAS,CAAC,0EAA0E,CAAC,CAAC;QAClG,CAAC;QACD,4FAA4F;QAC5F,6CAA6C;QAC7C,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxE,IAAI,OAAO,aAAa,KAAK,UAAU,IAAI,OAAO,gBAAgB,KAAK,UAAU,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE,CAAC;YACzH,MAAM,IAAI,SAAS,CACjB,kIAAkI,CACnI,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,SAAS,UAAU,CACjB,IAAmC,EACnC,MAAsB,EACtB,MAAe;IAEf,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE;QAC9B,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE;QACpB,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM;KACP,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,SAAS,WAAW,CAAC,WAAmB;IACtC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiB,CAAC;IACzC,MAAM,GAAG,GAAG,CAAC,GAAwB,EAAiB,EAAE;QACtD,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE;YACvB,IAAI,MAAM,IAAI,WAAW;gBAAE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACvF,MAAM,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,MAAM,GAAG,EAAE,CAAC;YACd,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;QACtC,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC;YAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC;IACF,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAA6B;IAClE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC;IAC5C,MAAM,QAAQ,GAA0C,IAAI,CAAC,QAAQ;QACnE,CAAC,CAAC,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;YACjC,CAAC,CAAC,IAAI,CAAC,QAAQ;YACf,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,aAAa,GAAG,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACvD,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,EAAE,WAAW,IAAI,CAAC,CAAC,CAAC;IACtD,MAAM,WAAW,GACf,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,IAAI,+BAA+B,CAAC,GAAG,IAAI,CAAC;IAE1G,MAAM,QAAQ,GAAG,CAAC,IAAgB,EAAW,EAAE,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,CAAC;IAE3F,MAAM,QAAQ,GAAG,CAAC,UAAkB,EAA0C,EAAE,CAC9E,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1F,MAAM,MAAM,GAAG,KAAK,EAAE,UAAkB,EAAE,KAAgD,EAAE,EAAE;QAC5F,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,0FAA0F;YAC1F,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,+CAA+C,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC,CAAC;IAEF,oGAAoG;IACpG,MAAM,OAAO,GAAG,CAAC,GAAoC,EAAuC,EAAE,CAC5F,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACtB,KAAK,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAO,OAA4B,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACrF,MAAM,MAAM,GACV,OAAO,SAAS,KAAK,QAAQ;oBAC3B,CAAC,CAAC,MAAM,cAAc,CAAC,SAAS,EAAE,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,CAAC;oBAC1D,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;gBACvE,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,MAAM,eAAe,EAAE,CAAC;oBACtB,KAAK,EAAE,WAAW;oBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,QAAQ,EAAE,MAAM;iBACjB,CAAC,CAAC;gBACH,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,EAAE,wCAAwC,CAAC,CAAC;gBAC5F,OAAO,CAAC,SAAS,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,4CAA4C;IAC5C,MAAM,IAAI,GAAG,KAAK,EAChB,OAA0B,EAC1B,GAAoC,EACrB,EAAE;QACjB,IAAI,gBAAgB;YAAE,MAAM,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC3D,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC;IAEF,wFAAwF;IACxF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAElD;;;;;;OAMG;IACH,MAAM,MAAM,GAAG,CACb,OAA0B,EAC1B,IAAmC,EACnC,MAAsB,EACtB,MAAe,EACA,EAAE;QACjB,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7C,0FAA0F;QAC1F,8DAA8D;QAC9D,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAClF,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QACnD,IAAI,CAAC,eAAe,IAAI,CAAC,SAAS;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAE7D,IAAI,GAAkB,CAAC;QACvB,IAAI,eAAe,IAAI,aAAa,EAAE,CAAC;YACrC,uEAAuE;YACvE,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE;gBAChB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,SAAS;oBAAE,OAAO;gBACvB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC3E,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CACV,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EACnD,4EAA4E,CAC7E,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YACL,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YACrC,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QACD,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC/E,IAAI,CAAC;gBACH,IAAI,SAAS;oBAAE,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC1C,CAAC;oBAAS,CAAC;gBACT,sFAAsF;gBACtF,KAAK,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,EAAE,OAA0B,EAAE,MAAsB,EAAiB,EAAE,CAC3F,MAAM,CAAC,OAAO,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAEpE,8FAA8F;IAC9F,MAAM,UAAU,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;QAC7D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC3D,OAAO,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,SAAS,GAA6B,IAAI,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAsB,EAAE;QACrC,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,SAAS,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,IAAI,OAAO,OAAO,CAAC,aAAa,KAAK,UAAU,IAAI,OAAO,OAAO,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;gBAClG,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,MAAM,OAAO,GAAoB,EAAE,CAAC;YACpC,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;gBACnD,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;oBAAE,SAAS;gBAC/D,IAAI,IAAmC,CAAC;gBACxC,IAAI,CAAC;oBACH,IAAI,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3D,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,8CAA8C,CAAC,CAAC;oBACrG,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;oBAAE,SAAS;gBACpE,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;oBAAE,SAAS;gBAC7E,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC9D,MAAM,MAAM,GAAmB;oBAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI,EAAE,MAAM,UAAU,CAAC,QAAQ,CAAC;oBAChC,QAAQ;iBACT,CAAC;gBACF,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/B,OAAO,CAAC,IAAI,CACV,MAAM,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACvD,MAAM,CAAC,KAAK,CACV,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EACrD,sEAAsE,CACvE,CAAC;gBACJ,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3B,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,IAAI,KAAK,GAA0B,IAAI,CAAC;IACxC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAQ,EAAE;QACzC,IAAI,OAAO,IAAI,WAAW,KAAK,IAAI;YAAE,OAAO;QAC5C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,KAAK,GAAG,IAAI,CAAC;YACb,KAAK,MAAM,EAAE;iBACV,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,qCAAqC,CAAC,CAAC;iBAC5E,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;QAC1C,CAAC,EAAE,OAAO,CAAC,CAAC;QACZ,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,MAAM;QACN,QAAQ;QACR,KAAK,EAAE,GAAG,EAAE;YACV,IAAI,KAAK,IAAI,OAAO;gBAAE,OAAO;YAC7B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,IAAI,qBAAqB,CAAC,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,KAAK,GAAG,IAAI,CAAC;YACb,MAAM,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACjC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/deeplinks.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
22
|
-
*
|
|
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;
|
|
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"}
|
package/dist/lib/deeplinks.js
CHANGED
|
@@ -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
|
|
27
|
-
*
|
|
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":"
|
|
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"}
|
package/dist/lib/magic.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
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
|
package/dist/lib/magic.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
package/dist/lib/magic.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic.js","sourceRoot":"","sources":["../../src/lib/magic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"magic.js","sourceRoot":"","sources":["../../src/lib/magic.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/options.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/lib/options.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
|
|
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
|
-
|
|
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
|