@mieweb/pulsevault 0.3.0 → 0.4.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 +98 -1
- package/OPERATIONS.md +24 -8
- package/PROTOCOL.md +187 -105
- package/README.md +102 -41
- package/dist/app.d.ts +28 -12
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +17 -4
- package/dist/app.js.map +1 -1
- package/dist/core.d.ts +18 -8
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +91 -23
- package/dist/core.js.map +1 -1
- package/dist/lib/authorize.d.ts +7 -1
- package/dist/lib/authorize.d.ts.map +1 -1
- package/dist/lib/capabilities.d.ts +30 -0
- package/dist/lib/capabilities.d.ts.map +1 -0
- package/dist/lib/capabilities.js +23 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/capability-token.d.ts +41 -7
- package/dist/lib/capability-token.d.ts.map +1 -1
- package/dist/lib/capability-token.js +68 -13
- package/dist/lib/capability-token.js.map +1 -1
- package/dist/lib/deeplinks.d.ts +0 -13
- package/dist/lib/deeplinks.d.ts.map +1 -1
- package/dist/lib/deeplinks.js +0 -5
- package/dist/lib/deeplinks.js.map +1 -1
- package/dist/lib/options.d.ts +6 -1
- package/dist/lib/options.d.ts.map +1 -1
- package/dist/lib/options.js +9 -4
- package/dist/lib/options.js.map +1 -1
- package/dist/lib/protocol.d.ts +31 -0
- package/dist/lib/protocol.d.ts.map +1 -0
- package/dist/lib/protocol.js +55 -0
- package/dist/lib/protocol.js.map +1 -0
- package/dist/lib/pulsevaultTus.d.ts +7 -2
- package/dist/lib/pulsevaultTus.d.ts.map +1 -1
- package/dist/lib/pulsevaultTus.js +80 -6
- package/dist/lib/pulsevaultTus.js.map +1 -1
- package/dist/lib/retention.d.ts +54 -0
- package/dist/lib/retention.d.ts.map +1 -0
- package/dist/lib/retention.js +119 -0
- package/dist/lib/retention.js.map +1 -0
- package/dist/lib/view-links.d.ts +49 -0
- package/dist/lib/view-links.d.ts.map +1 -0
- package/dist/lib/view-links.js +35 -0
- package/dist/lib/view-links.js.map +1 -0
- package/dist/routes/pulsevault.d.ts +2 -2
- package/dist/routes/pulsevault.d.ts.map +1 -1
- package/dist/routes/pulsevault.js +51 -30
- package/dist/routes/pulsevault.js.map +1 -1
- package/dist/storage/local.d.ts +5 -1
- package/dist/storage/local.d.ts.map +1 -1
- package/dist/storage/local.js +55 -1
- package/dist/storage/local.js.map +1 -1
- package/dist/storage/s3.d.ts +5 -1
- package/dist/storage/s3.d.ts.map +1 -1
- package/dist/storage/s3.js +52 -5
- package/dist/storage/s3.js.map +1 -1
- package/dist/storage/types.d.ts +34 -6
- package/dist/storage/types.d.ts.map +1 -1
- package/package.json +15 -3
- package/protocol/openapi.json +1058 -0
- package/protocol/schemas/beat-manifest.schema.json +54 -0
- package/protocol/schemas/capabilities.schema.json +65 -0
- package/protocol/schemas/capability-token.schema.json +36 -0
- package/protocol/schemas/deep-link.schema.json +29 -0
- package/protocol/schemas/pulse-client.schema.json +8 -0
- package/protocol/schemas/upload-metadata.schema.json +45 -0
- package/protocol/schemas/view-link.schema.json +23 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../src/lib/retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PulseVaultRequest } from './request.js';
|
|
2
|
+
import type { UploadKind } from '../storage/types.js';
|
|
3
|
+
/** A read-only view link, as `POST {prefix}/artifacts/<id>/view-link` returns it (PROTOCOL.md §6.4). */
|
|
4
|
+
export type PulseVaultViewLink = {
|
|
5
|
+
/** Opens the artifact as `GET {prefix}/artifacts/<id>?token=<token>`, and nothing more. */
|
|
6
|
+
token: string;
|
|
7
|
+
/** When the link stops working, in seconds since the Unix epoch. */
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
};
|
|
10
|
+
/** The finished artifact a view link is being minted for. */
|
|
11
|
+
export type PulseVaultViewLinkContext = {
|
|
12
|
+
artifactId: string;
|
|
13
|
+
kind: UploadKind;
|
|
14
|
+
relatedTo?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Mints a view link, or returns `null` to refuse one for this artifact. Called for a finished
|
|
18
|
+
* artifact after `authorize` allowed the request as `"share"`. The host decides each link —
|
|
19
|
+
* how long it works, whether this artifact gets one at all — so PulseVault sets no lifetime of
|
|
20
|
+
* its own.
|
|
21
|
+
*/
|
|
22
|
+
export type PulseVaultIssueViewLink = (request: PulseVaultRequest, ctx: PulseVaultViewLinkContext) => PulseVaultViewLink | null | Promise<PulseVaultViewLink | null>;
|
|
23
|
+
export type ViewLinkIssuerOptions = {
|
|
24
|
+
/** Key id to sign under — the same keys as capability tokens (view tokens derive their own key). */
|
|
25
|
+
keyId: string;
|
|
26
|
+
/** The secret for `keyId`. */
|
|
27
|
+
secret: string;
|
|
28
|
+
/** Issuing deployment's identity; must match what `createCapabilityAuthorize` verifies. */
|
|
29
|
+
issuer: string;
|
|
30
|
+
/**
|
|
31
|
+
* How long each link works, in seconds: a fixed number, or decided per link from the request
|
|
32
|
+
* and the artifact. Return `null` from the function to refuse a link.
|
|
33
|
+
*/
|
|
34
|
+
expirySeconds: number | ((request: PulseVaultRequest, ctx: PulseVaultViewLinkContext) => number | null | Promise<number | null>);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* A ready-made `issueViewLink` for deployments using capability tokens: signs a view token
|
|
38
|
+
* (`issueViewToken`) that `createCapabilityAuthorize` accepts for opening the artifact, and only
|
|
39
|
+
* that.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* issueViewLink: createViewLinkIssuer({
|
|
43
|
+
* keyId, secret, issuer,
|
|
44
|
+
* expirySeconds: (_request, { kind }) => (kind === 'video' ? 30 * 86_400 : 7 * 86_400),
|
|
45
|
+
* }),
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function createViewLinkIssuer(opts: ViewLinkIssuerOptions): PulseVaultIssueViewLink;
|
|
49
|
+
//# sourceMappingURL=view-links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-links.d.ts","sourceRoot":"","sources":["../../src/lib/view-links.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,wGAAwG;AACxG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2FAA2F;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,yBAAyB,KAC3B,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAAG;IAClC,oGAAoG;IACpG,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,aAAa,EACT,MAAM,GACN,CAAC,CACC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,yBAAyB,KAC3B,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAClD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,uBAAuB,CA0BzF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { issueViewToken } from './capability-token.js';
|
|
2
|
+
/**
|
|
3
|
+
* A ready-made `issueViewLink` for deployments using capability tokens: signs a view token
|
|
4
|
+
* (`issueViewToken`) that `createCapabilityAuthorize` accepts for opening the artifact, and only
|
|
5
|
+
* that.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* issueViewLink: createViewLinkIssuer({
|
|
9
|
+
* keyId, secret, issuer,
|
|
10
|
+
* expirySeconds: (_request, { kind }) => (kind === 'video' ? 30 * 86_400 : 7 * 86_400),
|
|
11
|
+
* }),
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function createViewLinkIssuer(opts) {
|
|
15
|
+
const { keyId, secret, issuer, expirySeconds } = opts;
|
|
16
|
+
// A fixed lifetime that can't work fails here, at boot — not as a 500 on every link.
|
|
17
|
+
if (typeof expirySeconds !== 'function' &&
|
|
18
|
+
!(typeof expirySeconds === 'number' && Number.isFinite(expirySeconds) && expirySeconds >= 1)) {
|
|
19
|
+
throw new TypeError('createViewLinkIssuer: `expirySeconds` must be a number of seconds (at least 1) or a function');
|
|
20
|
+
}
|
|
21
|
+
return async (request, ctx) => {
|
|
22
|
+
const seconds = typeof expirySeconds === 'function' ? await expirySeconds(request, ctx) : expirySeconds;
|
|
23
|
+
if (seconds === null)
|
|
24
|
+
return null;
|
|
25
|
+
const token = issueViewToken(ctx.artifactId, secret, {
|
|
26
|
+
keyId,
|
|
27
|
+
issuer,
|
|
28
|
+
expirySeconds: seconds,
|
|
29
|
+
});
|
|
30
|
+
// The token's own `exp`, so the two can't disagree by the second the signing took.
|
|
31
|
+
const claims = JSON.parse(Buffer.from(token.slice(0, token.indexOf('.')), 'base64url').toString('utf8'));
|
|
32
|
+
return { token, expiresAt: claims.exp };
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=view-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-links.js","sourceRoot":"","sources":["../../src/lib/view-links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiDvD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAA2B;IAC9D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACtD,qFAAqF;IACrF,IACE,OAAO,aAAa,KAAK,UAAU;QACnC,CAAC,CAAC,OAAO,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,IAAI,CAAC,CAAC,EAC5F,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,8FAA8F,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;QAC5B,MAAM,OAAO,GACX,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1F,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAClC,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE;YACnD,KAAK;YACL,MAAM;YACN,aAAa,EAAE,OAAO;SACvB,CAAC,CAAC;QACH,mFAAmF;QACnF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC3D,CAAC;QACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;IAC1C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { PROTOCOL_VERSION } from '../core.js';
|
|
|
4
4
|
import type { PulseVaultOnUploadComplete, PulseVaultOnArtifactEvent } from '../lib/pulsevaultTus.js';
|
|
5
5
|
import type { PulseVaultValidatePayload } from '../lib/magic.js';
|
|
6
6
|
import { type PulseVaultAuthorize } from '../lib/authorize.js';
|
|
7
|
+
import type { PulseVaultIssueViewLink } from '../lib/view-links.js';
|
|
7
8
|
import type { PulseVaultAllowedExtensions } from '../lib/options.js';
|
|
8
9
|
import type { PulseVaultStorage, UploadKind } from '../storage/types.js';
|
|
9
10
|
export type { PulseVaultAuthorize, PulseVaultAuthorizeContext, PulseVaultAuthorizePhase, } from '../lib/authorize.js';
|
|
@@ -20,13 +21,12 @@ export type PulseVaultRoutesOptions = {
|
|
|
20
21
|
storage: PulseVaultStorage;
|
|
21
22
|
maxUploadSize: number;
|
|
22
23
|
allowedExtensions: PulseVaultAllowedExtensions;
|
|
23
|
-
/** Advertised via `GET /capabilities` so the client knows which upload strategy this server expects. */
|
|
24
|
-
uploadUnit: 'segment' | 'merged';
|
|
25
24
|
cache?: PulseVaultCacheOptions;
|
|
26
25
|
authorize?: PulseVaultAuthorize;
|
|
27
26
|
validatePayload?: PulseVaultValidatePayload;
|
|
28
27
|
onUploadComplete?: PulseVaultOnUploadComplete;
|
|
29
28
|
onArtifactEvent?: PulseVaultOnArtifactEvent;
|
|
29
|
+
issueViewLink?: PulseVaultIssueViewLink;
|
|
30
30
|
} & FastifyPluginOptions;
|
|
31
31
|
declare const pulseVaultRoutes: FastifyPluginAsync<PulseVaultRoutesOptions>;
|
|
32
32
|
export default pulseVaultRoutes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pulsevault.d.ts","sourceRoot":"","sources":["../../src/routes/pulsevault.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pulsevault.d.ts","sourceRoot":"","sources":["../../src/routes/pulsevault.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EAIrB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAwB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEzE,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAkB7B,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,UAAU,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,UAAU,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3E;CACF;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,2BAA2B,CAAC;IAC/C,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACzC,GAAG,oBAAoB,CAAC;AAqKzB,QAAA,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,uBAAuB,CAwFjE,CAAC;AAEF,eAAe,gBAAgB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
import { createPulseVaultCore, PROTOCOL_VERSION } from '../core.js';
|
|
2
3
|
import {} from '../lib/authorize.js';
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
/**
|
|
6
|
+
* A schema from `protocol/schemas/` — the protocol's single source (PROTOCOL.md §7) — for use
|
|
7
|
+
* as a route schema, without the JSON Schema `$schema`/`$id` keys Fastify's compilers don't take.
|
|
8
|
+
*/
|
|
9
|
+
function protocolSchema(name) {
|
|
10
|
+
const { $schema: _schema, $id: _id, ...schema } = require(`../../protocol/schemas/${name}.schema.json`);
|
|
11
|
+
return schema;
|
|
12
|
+
}
|
|
3
13
|
const pulseVaultErrorResponse = {
|
|
4
14
|
type: 'object',
|
|
5
15
|
properties: {
|
|
@@ -16,11 +26,11 @@ const tusRouteSchema = {
|
|
|
16
26
|
' - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n' +
|
|
17
27
|
" - `filename` — original filename; the extension must match the kind's allowed list.\n" +
|
|
18
28
|
' - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n' +
|
|
19
|
-
" - `relatedTo` — optional UUID of another artifact this one belongs to (e.g.
|
|
29
|
+
" - `relatedTo` — optional UUID of another artifact this one belongs to (e.g. the captions, beat manifest or thumbnail belonging to a pulse's video).\n" +
|
|
20
30
|
' - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n' +
|
|
21
31
|
'- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n' +
|
|
22
32
|
'- `HEAD` returns the current offset for a resumable upload.\n' +
|
|
23
|
-
'- `DELETE`
|
|
33
|
+
'- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\n' +
|
|
24
34
|
'See https://tus.io/protocols/resumable-upload for the full protocol.',
|
|
25
35
|
response: {
|
|
26
36
|
400: { description: 'Invalid request.', ...pulseVaultErrorResponse },
|
|
@@ -97,43 +107,49 @@ const artifactGetSchema = {
|
|
|
97
107
|
404: { description: 'Artifact not found.', ...pulseVaultErrorResponse },
|
|
98
108
|
},
|
|
99
109
|
};
|
|
100
|
-
const
|
|
110
|
+
const viewLinkSchema = {
|
|
101
111
|
tags: ['pulsevault'],
|
|
102
|
-
summary:
|
|
103
|
-
description: '
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
uploadUnit: { type: 'string', enum: ['segment', 'merged'] },
|
|
112
|
-
kinds: { type: 'array', items: { type: 'string' } },
|
|
113
|
-
allowedExtensions: {
|
|
114
|
-
type: 'object',
|
|
115
|
-
properties: {
|
|
116
|
-
video: { type: 'array', items: { type: 'string' } },
|
|
117
|
-
project: { type: 'array', items: { type: 'string' } },
|
|
118
|
-
captions: { type: 'array', items: { type: 'string' } },
|
|
119
|
-
thumbnail: { type: 'array', items: { type: 'string' } },
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
maxUploadSize: { type: 'number' },
|
|
123
|
-
checksum: {
|
|
124
|
-
type: 'object',
|
|
125
|
-
properties: { algorithms: { type: 'array', items: { type: 'string' } } },
|
|
126
|
-
},
|
|
112
|
+
summary: 'Mint a read-only view link for a finished artifact',
|
|
113
|
+
description: 'Returns a token that opens the artifact (and the artifacts `relatedTo` it) as `GET /artifacts/:artifactId?token=`, and nothing more — no uploads, deletes or further links. Runs the `authorize` hook with `phase: "share"`; the host\'s `issueViewLink` decides how long the link works. 404 unless the server enables view links (`/capabilities` `viewLinks`) and the artifact is finished; 403 when the host refuses a link for it.',
|
|
114
|
+
params: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
artifactId: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
format: 'uuid',
|
|
120
|
+
description: 'UUID of the finished artifact to link to.',
|
|
127
121
|
},
|
|
128
122
|
},
|
|
123
|
+
required: ['artifactId'],
|
|
124
|
+
},
|
|
125
|
+
response: {
|
|
126
|
+
200: protocolSchema('view-link'),
|
|
127
|
+
400: {
|
|
128
|
+
description: '`artifactId` is not a valid UUID.',
|
|
129
|
+
...pulseVaultErrorResponse,
|
|
130
|
+
},
|
|
131
|
+
403: {
|
|
132
|
+
description: 'Authorize hook rejected the request, or the host refused a link for this artifact.',
|
|
133
|
+
...pulseVaultErrorResponse,
|
|
134
|
+
},
|
|
135
|
+
404: {
|
|
136
|
+
description: 'View links are not enabled, or the artifact is not found or not finished.',
|
|
137
|
+
...pulseVaultErrorResponse,
|
|
138
|
+
},
|
|
129
139
|
},
|
|
130
140
|
};
|
|
141
|
+
const capabilitiesSchema = {
|
|
142
|
+
tags: ['pulsevault'],
|
|
143
|
+
summary: "Discover this deployment's protocol version and configuration",
|
|
144
|
+
description: 'Unauthenticated — the response carries no secrets. Lets a client detect protocol compatibility, allowed artifact kinds/extensions and the upload size cap before pairing.',
|
|
145
|
+
response: { 200: protocolSchema('capabilities') },
|
|
146
|
+
};
|
|
131
147
|
/** Coerce the raw route param to a string; an invalid UUID is rejected by the core's own check either way. */
|
|
132
148
|
function paramToString(value) {
|
|
133
149
|
return typeof value === 'string' ? value : '';
|
|
134
150
|
}
|
|
135
151
|
const pulseVaultRoutes = async (fastify, opts) => {
|
|
136
|
-
const { storage, maxUploadSize, allowedExtensions,
|
|
152
|
+
const { storage, maxUploadSize, allowedExtensions, cache, authorize, validatePayload, onUploadComplete, onArtifactEvent, issueViewLink, } = opts;
|
|
137
153
|
// All hook orchestration, tus glue, and artifact GET/DELETE logic lives in
|
|
138
154
|
// the framework-agnostic core (`../core.js`); this file only wires Fastify's
|
|
139
155
|
// routing/schema/lifecycle around it, so behavior can't drift from the
|
|
@@ -143,13 +159,13 @@ const pulseVaultRoutes = async (fastify, opts) => {
|
|
|
143
159
|
// `fastify.prefix` is `""` when the plugin is mounted at the root.
|
|
144
160
|
basePath: fastify.prefix,
|
|
145
161
|
maxUploadSize,
|
|
146
|
-
uploadUnit,
|
|
147
162
|
allowedExtensions,
|
|
148
163
|
cache,
|
|
149
164
|
authorize,
|
|
150
165
|
validatePayload,
|
|
151
166
|
onUploadComplete,
|
|
152
167
|
onArtifactEvent,
|
|
168
|
+
issueViewLink,
|
|
153
169
|
logger: fastify.log,
|
|
154
170
|
});
|
|
155
171
|
fastify.addContentTypeParser('application/offset+octet-stream', (_request, _payload, done) => {
|
|
@@ -184,6 +200,11 @@ const pulseVaultRoutes = async (fastify, opts) => {
|
|
|
184
200
|
reply.hijack();
|
|
185
201
|
await core.handleArtifactDelete(request.raw, reply.raw, artifactId);
|
|
186
202
|
});
|
|
203
|
+
fastify.post('/artifacts/:artifactId/view-link', { schema: viewLinkSchema }, async (request, reply) => {
|
|
204
|
+
const artifactId = paramToString(request.params?.artifactId);
|
|
205
|
+
reply.hijack();
|
|
206
|
+
await core.handleViewLink(request.raw, reply.raw, artifactId);
|
|
207
|
+
});
|
|
187
208
|
fastify.get('/artifacts/:artifactId', { schema: artifactGetSchema }, async (request, reply) => {
|
|
188
209
|
const artifactId = paramToString(request.params?.artifactId);
|
|
189
210
|
const token = request.query?.token;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pulsevault.js","sourceRoot":"","sources":["../../src/routes/pulsevault.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pulsevault.js","sourceRoot":"","sources":["../../src/routes/pulsevault.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/local.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PulseVaultStorage, UploadKind } from './types.js';
|
|
1
|
+
import type { PulseVaultArtifactRecord, PulseVaultStorage, UploadKind } from './types.js';
|
|
2
2
|
export type LocalStorageOptions = {
|
|
3
3
|
/** Directory where uploads are stored (flat kind-scoped subdirs). Resolved against CWD if relative. */
|
|
4
4
|
workspaceDir: string;
|
|
@@ -52,6 +52,10 @@ export type LocalStorage = PulseVaultStorage & {
|
|
|
52
52
|
getChecksum(artifactId: string): Promise<string | null>;
|
|
53
53
|
/** Satisfies the optional `PulseVaultStorage.getName` contract. */
|
|
54
54
|
getName(artifactId: string): Promise<string | null>;
|
|
55
|
+
/** Satisfies the optional `PulseVaultStorage.listArtifacts` contract. */
|
|
56
|
+
listArtifacts(opts?: {
|
|
57
|
+
changedBefore?: number;
|
|
58
|
+
}): AsyncIterable<PulseVaultArtifactRecord>;
|
|
55
59
|
};
|
|
56
60
|
export declare function createLocalStorage(opts: LocalStorageOptions): LocalStorage;
|
|
57
61
|
//# sourceMappingURL=local.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,wBAAwB,EAExB,iBAAiB,EAEjB,UAAU,EACX,MAAM,YAAY,CAAC;AAoFpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,uGAAuG;IACvG,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD;;;;OAIG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACxD,wEAAwE;IACxE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,uEAAuE;IACvE,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,mEAAmE;IACnE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpD,yEAAyE;IACzE,aAAa,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,CAAC,wBAAwB,CAAC,CAAC;CAC3F,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,YAAY,CAiU1E"}
|
package/dist/storage/local.js
CHANGED
|
@@ -132,6 +132,7 @@ export function createLocalStorage(opts) {
|
|
|
132
132
|
relatedTo: typeof parsed.relatedTo === 'string' ? parsed.relatedTo : undefined,
|
|
133
133
|
checksum: typeof parsed.checksum === 'string' ? parsed.checksum : undefined,
|
|
134
134
|
name: typeof parsed.name === 'string' ? parsed.name : undefined,
|
|
135
|
+
appVersion: typeof parsed.appVersion === 'string' ? parsed.appVersion : undefined,
|
|
135
136
|
};
|
|
136
137
|
}
|
|
137
138
|
catch {
|
|
@@ -160,7 +161,7 @@ export function createLocalStorage(opts) {
|
|
|
160
161
|
// tighten it so the upload tree isn't world-writable under a permissive umask.
|
|
161
162
|
await fs.chmod(workspaceRoot, 0o750).catch(() => { });
|
|
162
163
|
};
|
|
163
|
-
const reserveUpload = async ({ artifactId, filename, ext, kind, relatedTo, checksum, name, }) => {
|
|
164
|
+
const reserveUpload = async ({ artifactId, filename, ext, kind, relatedTo, checksum, name, appVersion, }) => {
|
|
164
165
|
await fs.mkdir(path.join(workspaceRoot, kind), { recursive: true, mode: 0o750 });
|
|
165
166
|
await fs.mkdir(sidecarDir(), { recursive: true, mode: 0o750 });
|
|
166
167
|
const sidecar = {
|
|
@@ -172,6 +173,7 @@ export function createLocalStorage(opts) {
|
|
|
172
173
|
relatedTo,
|
|
173
174
|
checksum,
|
|
174
175
|
name,
|
|
176
|
+
appVersion,
|
|
175
177
|
};
|
|
176
178
|
// Collision guard: `wx` fails atomically with EEXIST if a sidecar already exists for
|
|
177
179
|
// this artifactId, rather than the previous read-then-write (`loadMeta` then
|
|
@@ -278,6 +280,57 @@ export function createLocalStorage(opts) {
|
|
|
278
280
|
const meta = await loadMeta(artifactId);
|
|
279
281
|
return meta?.name ?? null;
|
|
280
282
|
};
|
|
283
|
+
/**
|
|
284
|
+
* Walk the sidecars. A sidecar is rewritten only when its upload finishes, so its mtime is
|
|
285
|
+
* when the upload started (still uploading) or when it finished (ready). An upload in flight
|
|
286
|
+
* counts from its last write instead — the bytes file's mtime — so a long upload that's still
|
|
287
|
+
* moving is never taken for an abandoned one.
|
|
288
|
+
*/
|
|
289
|
+
async function* listArtifacts(opts = {}) {
|
|
290
|
+
let names;
|
|
291
|
+
try {
|
|
292
|
+
names = await fs.readdir(sidecarDir());
|
|
293
|
+
}
|
|
294
|
+
catch (err) {
|
|
295
|
+
if (err?.code === 'ENOENT')
|
|
296
|
+
return;
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
299
|
+
for (const name of names) {
|
|
300
|
+
if (!name.endsWith('.json'))
|
|
301
|
+
continue;
|
|
302
|
+
const artifactId = name.slice(0, -'.json'.length);
|
|
303
|
+
if (!isUuid(artifactId))
|
|
304
|
+
continue;
|
|
305
|
+
let updatedAt;
|
|
306
|
+
try {
|
|
307
|
+
updatedAt = (await fs.stat(sidecarPath(artifactId))).mtimeMs;
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
continue; // Removed since the readdir.
|
|
311
|
+
}
|
|
312
|
+
if (opts.changedBefore !== undefined && updatedAt >= opts.changedBefore)
|
|
313
|
+
continue;
|
|
314
|
+
const sidecar = await readSidecar(artifactId);
|
|
315
|
+
if (!sidecar)
|
|
316
|
+
continue;
|
|
317
|
+
const kind = sidecar.kind ?? 'video';
|
|
318
|
+
if (sidecar.status === 'uploading') {
|
|
319
|
+
const bytes = path.join(workspaceRoot, kind, `${artifactId}${sidecar.ext}`);
|
|
320
|
+
const written = await fs.stat(bytes).then((stats) => stats.mtimeMs, () => 0);
|
|
321
|
+
updatedAt = Math.max(updatedAt, written);
|
|
322
|
+
if (opts.changedBefore !== undefined && updatedAt >= opts.changedBefore)
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
yield {
|
|
326
|
+
artifactId,
|
|
327
|
+
kind,
|
|
328
|
+
...(sidecar.relatedTo ? { relatedTo: sidecar.relatedTo } : {}),
|
|
329
|
+
ready: sidecar.status === 'ready',
|
|
330
|
+
updatedAt,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
}
|
|
281
334
|
return {
|
|
282
335
|
datastore,
|
|
283
336
|
workspaceRoot,
|
|
@@ -291,6 +344,7 @@ export function createLocalStorage(opts) {
|
|
|
291
344
|
getRelatedTo,
|
|
292
345
|
getChecksum,
|
|
293
346
|
getName,
|
|
347
|
+
listArtifacts,
|
|
294
348
|
};
|
|
295
349
|
}
|
|
296
350
|
//# sourceMappingURL=local.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/s3.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { S3ClientConfig } from '@aws-sdk/client-s3';
|
|
2
|
-
import type { PulseVaultStorage, UploadKind } from './types.js';
|
|
2
|
+
import type { PulseVaultArtifactRecord, PulseVaultStorage, UploadKind } from './types.js';
|
|
3
3
|
export type S3StorageOptions = {
|
|
4
4
|
/** Target bucket. Must already exist (the integrator provisions it). */
|
|
5
5
|
bucket: string;
|
|
@@ -90,6 +90,10 @@ export type S3Storage = PulseVaultStorage & {
|
|
|
90
90
|
getChecksum(artifactId: string): Promise<string | null>;
|
|
91
91
|
/** Satisfies the optional `PulseVaultStorage.getName` contract. */
|
|
92
92
|
getName(artifactId: string): Promise<string | null>;
|
|
93
|
+
/** Satisfies the optional `PulseVaultStorage.listArtifacts` contract. */
|
|
94
|
+
listArtifacts(opts?: {
|
|
95
|
+
changedBefore?: number;
|
|
96
|
+
}): AsyncIterable<PulseVaultArtifactRecord>;
|
|
93
97
|
};
|
|
94
98
|
/**
|
|
95
99
|
* Build an S3/R2-backed storage adapter.
|
package/dist/storage/s3.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EACV,wBAAwB,EAExB,iBAAiB,EAEjB,UAAU,EACX,MAAM,YAAY,CAAC;AAqFpB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,iBAAiB,GAAG;IAC1C,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClE;;;;;OAKG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpD;;;;;;OAMG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5F,4EAA4E;IAC5E,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACxD,wEAAwE;IACxE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,uEAAuE;IACvE,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,mEAAmE;IACnE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpD,yEAAyE;IACzE,aAAa,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,CAAC,wBAAwB,CAAC,CAAC;CAC3F,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAmZhF"}
|
package/dist/storage/s3.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { parseUploadKind } from './types.js';
|
|
3
|
+
import { isUuid } from '../lib/uuid.js';
|
|
3
4
|
const SIDECAR_VERSION = 1;
|
|
4
5
|
/** Key prefix inside the bucket that holds the per-upload sidecar objects. */
|
|
5
6
|
const PULSEVAULT_META_PREFIX = '.pulsevault';
|
|
@@ -69,7 +70,7 @@ export async function createS3Storage(opts) {
|
|
|
69
70
|
' npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner @tus/s3-store\n' +
|
|
70
71
|
`(original error: ${err instanceof Error ? err.message : String(err)})`);
|
|
71
72
|
}
|
|
72
|
-
const { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } = s3;
|
|
73
|
+
const { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, ListObjectsV2Command, } = s3;
|
|
73
74
|
const { getSignedUrl } = presigner;
|
|
74
75
|
const { S3Store } = s3store;
|
|
75
76
|
const bucket = opts.bucket;
|
|
@@ -149,6 +150,7 @@ export async function createS3Storage(opts) {
|
|
|
149
150
|
relatedTo: typeof parsed.relatedTo === 'string' ? parsed.relatedTo : undefined,
|
|
150
151
|
checksum: typeof parsed.checksum === 'string' ? parsed.checksum : undefined,
|
|
151
152
|
name: typeof parsed.name === 'string' ? parsed.name : undefined,
|
|
153
|
+
appVersion: typeof parsed.appVersion === 'string' ? parsed.appVersion : undefined,
|
|
152
154
|
};
|
|
153
155
|
}
|
|
154
156
|
catch {
|
|
@@ -167,7 +169,7 @@ export async function createS3Storage(opts) {
|
|
|
167
169
|
cacheSet(artifactId, meta);
|
|
168
170
|
return meta;
|
|
169
171
|
};
|
|
170
|
-
const reserveUpload = async ({ artifactId, filename, ext, kind, relatedTo, checksum, name, }) => {
|
|
172
|
+
const reserveUpload = async ({ artifactId, filename, ext, kind, relatedTo, checksum, name, appVersion, }) => {
|
|
171
173
|
const sidecar = {
|
|
172
174
|
version: SIDECAR_VERSION,
|
|
173
175
|
ext,
|
|
@@ -177,6 +179,7 @@ export async function createS3Storage(opts) {
|
|
|
177
179
|
relatedTo,
|
|
178
180
|
checksum,
|
|
179
181
|
name,
|
|
182
|
+
appVersion,
|
|
180
183
|
};
|
|
181
184
|
// Fast-path rejection for the common case. Not atomic by itself (two concurrent
|
|
182
185
|
// requests can both observe no existing meta before either writes) — the conditional
|
|
@@ -274,12 +277,18 @@ export async function createS3Storage(opts) {
|
|
|
274
277
|
await Promise.allSettled([
|
|
275
278
|
datastore.remove?.(key),
|
|
276
279
|
]);
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
+
// @tus/s3-store caches an upload's metadata, and its own removal of a finished upload fails
|
|
281
|
+
// (NoSuchUpload) before clearing it — a HEAD would then still report the deleted upload as
|
|
282
|
+
// complete.
|
|
283
|
+
await datastore.clearCache?.(key);
|
|
284
|
+
// Delete the finalized object, the @tus/s3-store `.info` sidecar, the incomplete part it
|
|
285
|
+
// parks between PATCHes (`.part`, left behind by its own removal), and our metadata
|
|
286
|
+
// sidecar. DeleteObject is idempotent, so this is safe whether or not the multipart abort
|
|
287
|
+
// above already removed some of them.
|
|
280
288
|
await Promise.all([
|
|
281
289
|
client.send(new DeleteObjectCommand({ Bucket: bucket, Key: key })),
|
|
282
290
|
client.send(new DeleteObjectCommand({ Bucket: bucket, Key: `${key}.info` })),
|
|
291
|
+
client.send(new DeleteObjectCommand({ Bucket: bucket, Key: `${key}.part` })),
|
|
283
292
|
client.send(new DeleteObjectCommand({ Bucket: bucket, Key: sidecarKey(artifactId) })),
|
|
284
293
|
]);
|
|
285
294
|
return true;
|
|
@@ -349,6 +358,43 @@ export async function createS3Storage(opts) {
|
|
|
349
358
|
const meta = await loadMeta(artifactId);
|
|
350
359
|
return meta?.name ?? null;
|
|
351
360
|
};
|
|
361
|
+
/**
|
|
362
|
+
* Walk the sidecar objects. A sidecar is rewritten only when its upload finishes, so its
|
|
363
|
+
* `LastModified` is when the upload started (still uploading) or when it finished (ready).
|
|
364
|
+
* Sidecars changed at or after `changedBefore` are skipped without being read.
|
|
365
|
+
*/
|
|
366
|
+
async function* listArtifacts(opts = {}) {
|
|
367
|
+
let continuationToken;
|
|
368
|
+
do {
|
|
369
|
+
const page = await client.send(new ListObjectsV2Command({
|
|
370
|
+
Bucket: bucket,
|
|
371
|
+
Prefix: `${PULSEVAULT_META_PREFIX}/`,
|
|
372
|
+
...(continuationToken ? { ContinuationToken: continuationToken } : {}),
|
|
373
|
+
}));
|
|
374
|
+
for (const object of page.Contents ?? []) {
|
|
375
|
+
const name = object.Key?.slice(PULSEVAULT_META_PREFIX.length + 1) ?? '';
|
|
376
|
+
if (!name.endsWith('.json'))
|
|
377
|
+
continue;
|
|
378
|
+
const artifactId = name.slice(0, -'.json'.length);
|
|
379
|
+
if (!isUuid(artifactId))
|
|
380
|
+
continue;
|
|
381
|
+
const updatedAt = object.LastModified?.getTime() ?? 0;
|
|
382
|
+
if (opts.changedBefore !== undefined && updatedAt >= opts.changedBefore)
|
|
383
|
+
continue;
|
|
384
|
+
const sidecar = await readSidecar(artifactId);
|
|
385
|
+
if (!sidecar)
|
|
386
|
+
continue;
|
|
387
|
+
yield {
|
|
388
|
+
artifactId,
|
|
389
|
+
kind: sidecar.kind ?? 'video',
|
|
390
|
+
...(sidecar.relatedTo ? { relatedTo: sidecar.relatedTo } : {}),
|
|
391
|
+
ready: sidecar.status === 'ready',
|
|
392
|
+
updatedAt,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
continuationToken = page.IsTruncated ? page.NextContinuationToken : undefined;
|
|
396
|
+
} while (continuationToken);
|
|
397
|
+
}
|
|
352
398
|
const shutdown = async () => {
|
|
353
399
|
client.destroy();
|
|
354
400
|
};
|
|
@@ -366,6 +412,7 @@ export async function createS3Storage(opts) {
|
|
|
366
412
|
getRelatedTo,
|
|
367
413
|
getChecksum,
|
|
368
414
|
getName,
|
|
415
|
+
listArtifacts,
|
|
369
416
|
shutdown,
|
|
370
417
|
};
|
|
371
418
|
}
|