@mieweb/pulsevault 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +258 -0
  2. package/LICENSE +15 -39
  3. package/OPERATIONS.md +223 -0
  4. package/PROTOCOL.md +345 -0
  5. package/README.md +548 -122
  6. package/augment.d.ts +1 -0
  7. package/augment.js +3 -0
  8. package/core.d.ts +1 -0
  9. package/core.js +7 -0
  10. package/dist/app.d.ts +91 -34
  11. package/dist/app.d.ts.map +1 -1
  12. package/dist/app.js +23 -33
  13. package/dist/app.js.map +1 -1
  14. package/dist/augment.d.ts +14 -7
  15. package/dist/augment.d.ts.map +1 -1
  16. package/dist/augment.js.map +1 -1
  17. package/dist/core.d.ts +108 -0
  18. package/dist/core.d.ts.map +1 -0
  19. package/dist/core.js +494 -0
  20. package/dist/core.js.map +1 -0
  21. package/dist/lib/authorize.d.ts +19 -0
  22. package/dist/lib/authorize.d.ts.map +1 -0
  23. package/dist/lib/authorize.js +2 -0
  24. package/dist/lib/authorize.js.map +1 -0
  25. package/dist/lib/capability-token.d.ts +80 -0
  26. package/dist/lib/capability-token.d.ts.map +1 -0
  27. package/dist/lib/capability-token.js +134 -0
  28. package/dist/lib/capability-token.js.map +1 -0
  29. package/dist/lib/checksum.d.ts +45 -0
  30. package/dist/lib/checksum.d.ts.map +1 -0
  31. package/dist/lib/checksum.js +105 -0
  32. package/dist/lib/checksum.js.map +1 -0
  33. package/dist/lib/deeplinks.d.ts +37 -21
  34. package/dist/lib/deeplinks.d.ts.map +1 -1
  35. package/dist/lib/deeplinks.js +54 -13
  36. package/dist/lib/deeplinks.js.map +1 -1
  37. package/dist/lib/errors.d.ts +7 -0
  38. package/dist/lib/errors.d.ts.map +1 -1
  39. package/dist/lib/errors.js +18 -0
  40. package/dist/lib/errors.js.map +1 -1
  41. package/dist/lib/magic.d.ts +30 -5
  42. package/dist/lib/magic.d.ts.map +1 -1
  43. package/dist/lib/magic.js +51 -14
  44. package/dist/lib/magic.js.map +1 -1
  45. package/dist/lib/options.d.ts +41 -0
  46. package/dist/lib/options.d.ts.map +1 -0
  47. package/dist/lib/options.js +111 -0
  48. package/dist/lib/options.js.map +1 -0
  49. package/dist/lib/pulsevaultTus.d.ts +53 -26
  50. package/dist/lib/pulsevaultTus.d.ts.map +1 -1
  51. package/dist/lib/pulsevaultTus.js +174 -55
  52. package/dist/lib/pulsevaultTus.js.map +1 -1
  53. package/dist/lib/request.d.ts +26 -0
  54. package/dist/lib/request.d.ts.map +1 -0
  55. package/dist/lib/request.js +22 -0
  56. package/dist/lib/request.js.map +1 -0
  57. package/dist/lib/uuid.d.ts.map +1 -1
  58. package/dist/lib/uuid.js +1 -1
  59. package/dist/lib/uuid.js.map +1 -1
  60. package/dist/routes/pulsevault.d.ts +18 -16
  61. package/dist/routes/pulsevault.d.ts.map +1 -1
  62. package/dist/routes/pulsevault.js +121 -251
  63. package/dist/routes/pulsevault.js.map +1 -1
  64. package/dist/storage/local.d.ts +31 -10
  65. package/dist/storage/local.d.ts.map +1 -1
  66. package/dist/storage/local.js +205 -84
  67. package/dist/storage/local.js.map +1 -1
  68. package/dist/storage/s3.d.ts +109 -0
  69. package/dist/storage/s3.d.ts.map +1 -0
  70. package/dist/storage/s3.js +438 -0
  71. package/dist/storage/s3.js.map +1 -0
  72. package/dist/storage/types.d.ts +80 -17
  73. package/dist/storage/types.d.ts.map +1 -1
  74. package/dist/storage/types.js +13 -1
  75. package/dist/storage/types.js.map +1 -1
  76. package/package.json +29 -7
package/augment.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./dist/augment.js";
package/augment.js ADDED
@@ -0,0 +1,3 @@
1
+ // Legacy-resolver fallback for the "./augment" subpath export — see core.js
2
+ // for why this file exists.
3
+ export * from "./dist/augment.js";
package/core.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./dist/core.js";
package/core.js ADDED
@@ -0,0 +1,7 @@
1
+ // Legacy-resolver fallback for the "./core" subpath export. Modern
2
+ // Node/bundlers resolve "@mieweb/pulsevault/core" via package.json's
3
+ // "exports" map straight to dist/core.js and never reach this file — it
4
+ // exists only for resolvers that don't understand "exports" subpath maps
5
+ // (e.g. Meteor's bundler as of Meteor 3.4 / modules@0.20.3), which fall back
6
+ // to plain relative-path resolution and need a real file at this path.
7
+ export * from "./dist/core.js";
package/dist/app.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type { FastifyPluginAsync } from "fastify";
2
- import { type PulseVaultAuthorize } from "./routes/pulsevault.js";
3
- import type { PulseVaultOnUploadComplete } from "./lib/pulsevaultTus.js";
4
- import type { PulseVaultValidatePayload } from "./lib/magic.js";
5
- import type { PulseVaultStorage } from "./storage/types.js";
1
+ import type { FastifyPluginAsync } from 'fastify';
2
+ import { type PulseVaultAuthorize } from './routes/pulsevault.js';
3
+ import type { PulseVaultOnUploadComplete, PulseVaultOnArtifactEvent } from './lib/pulsevaultTus.js';
4
+ import type { PulseVaultValidatePayload } from './lib/magic.js';
5
+ import type { PulseVaultStorage } from './storage/types.js';
6
6
  /**
7
7
  * Subset of `@fastify/send`'s cache-related options forwarded to the GET
8
8
  * route. All upload filenames are content-addressable (keyed by the upload
@@ -39,6 +39,15 @@ export type PulseVaultPluginOptions = {
39
39
  * explicit cap for their deployment. Use `Infinity` for no cap.
40
40
  */
41
41
  maxUploadSize: number;
42
+ /**
43
+ * Which upload strategy this deployment expects: `"segment"` uploads each
44
+ * clip individually (no client-side merge/re-encode pass) plus a manifest
45
+ * artifact for ordering, while `"merged"` expects one pre-merged video per
46
+ * pulse (plus its captions, beat manifest and thumbnail). Purely advertised
47
+ * via `GET /capabilities` for the client to branch on — `pulsevault` doesn't
48
+ * enforce either. Defaults to `"segment"`.
49
+ */
50
+ uploadUnit?: 'segment' | 'merged';
42
51
  /**
43
52
  * Fastify instance decorator name under which the storage adapter is
44
53
  * exposed. Defaults to `"pulseVault"`. Override when registering this
@@ -53,10 +62,21 @@ export type PulseVaultPluginOptions = {
53
62
  */
54
63
  decoratorName?: string;
55
64
  /**
56
- * File extensions allowed in the upload `filename` metadata. Must include
57
- * the leading dot; matched case-insensitively. Defaults to `[".mp4"]`.
65
+ * File extensions allowed per artifact kind. Accepts:
66
+ * - A flat array (`[".mp4"]`) — treated as video-only; project/captions
67
+ * default. This is the legacy form for back-compat.
68
+ * - An object with optional `video`/`project`/`captions` keys; unset keys
69
+ * fall back to their defaults.
70
+ * - Omitted entirely — defaults to
71
+ * `{ video: [".mp4"], project: [".pulse", ".zip"], captions: [".srt"] }`.
72
+ *
73
+ * All extensions must include the leading dot and are matched case-insensitively.
58
74
  */
59
- allowedExtensions?: readonly string[];
75
+ allowedExtensions?: readonly string[] | {
76
+ video?: readonly string[];
77
+ project?: readonly string[];
78
+ captions?: readonly string[];
79
+ };
60
80
  /**
61
81
  * Cache-control options forwarded to `@fastify/send` for the GET route.
62
82
  * When omitted, `@fastify/send`'s defaults apply (`Cache-Control: public,
@@ -68,47 +88,84 @@ export type PulseVaultPluginOptions = {
68
88
  * and before `resolve` on GET. Throw to reject the request; a thrown
69
89
  * `statusCode`/`status_code` number on the error is honored (default 403).
70
90
  *
71
- * The hook is called with the `FastifyRequest`, so consumers can look up
72
- * sessions, API keys, JWTs, etc. using whatever auth system they have
73
- * registered higher up in the Fastify tree.
91
+ * The hook is called with the actual `FastifyRequest` (typed more loosely
92
+ * as `PulseVaultRequest` — the shared shape this option also uses under
93
+ * `@mieweb/pulsevault/core` — since only `.headers` is guaranteed; cast if
94
+ * you need Fastify-specific fields), so consumers can look up sessions,
95
+ * API keys, JWTs, etc. using whatever auth system they have registered
96
+ * higher up in the Fastify tree. Use `createCapabilityAuthorize` (from
97
+ * `./lib/capability-token.js`) for a secure-by-default option that doesn't
98
+ * require writing your own.
74
99
  *
75
100
  * When omitted, the plugin performs no authorization. For production
76
101
  * deployments you almost certainly want to set this — register your auth
77
102
  * plugin on the parent scope and let the hook verify ownership of the
78
- * `videoid` before any bytes are written.
103
+ * `artifactId` before any bytes are written.
79
104
  */
80
105
  authorize?: PulseVaultAuthorize;
81
106
  /**
82
- * Optional payload-validation hook. Runs *after* TUS writes the final byte
83
- * but *before* the upload is marked ready or `onUploadComplete` fires.
84
- * Throw to reject — the plugin will call `storage.remove` to free the
85
- * bytes and return a 4xx (default 422) to the client. The sidecar never
86
- * flips to `"ready"`, so the video is never served.
107
+ * Optional payload-validation hook, called for every artifact kind with
108
+ * `ctx.kind` set accordingly. Runs *after* TUS writes the final byte but
109
+ * *before* the upload is marked ready or `onUploadComplete` fires. Throw to
110
+ * reject — the plugin will call `storage.remove` to free the bytes and
111
+ * return a 4xx (default 422) to the client. The sidecar never flips to
112
+ * `"ready"`, so the artifact is never served.
87
113
  *
88
- * Use this for magic-byte sniffing, virus scanning, or any check that
89
- * needs the final bytes. Ship-ready helpers are exported from this
90
- * package — see `createMp4Sniffer`.
114
+ * Use this for magic-byte sniffing, checksum verification, virus scanning,
115
+ * or any check that needs the final bytes. Ship-ready helpers are exported
116
+ * from this package — see `createMp4Sniffer`, `createChecksumValidator`.
91
117
  */
92
118
  validatePayload?: PulseVaultValidatePayload;
93
119
  /**
94
- * Optional post-upload hook. Fires once TUS writes the final byte *and*
120
+ * Optional post-upload hook, fired once TUS writes the final byte *and*
95
121
  * any `validatePayload` has passed, and after the adapter's `markReady`
96
- * has run. Use this to flip consumer state (DB row, queue job, audit
97
- * log). Throwing turns the upload into a 500 response; the video is
98
- * marked ready at this point, so consumers that want all-or-nothing
99
- * semantics should `storage.remove` before throwing.
122
+ * has run — for every artifact kind, with `ctx.kind` set accordingly. Use
123
+ * this to flip consumer state (DB row, queue job, audit log). Throwing
124
+ * turns the upload into a 500 response; the artifact is marked ready at
125
+ * this point, so consumers that want all-or-nothing semantics should
126
+ * `storage.remove` before throwing.
100
127
  */
101
128
  onUploadComplete?: PulseVaultOnUploadComplete;
129
+ /**
130
+ * Optional low-frequency event hook — fired on authorize rejection (create
131
+ * phase and delete/resolve, never per-chunk patch), upload completion, and
132
+ * payload-validation rejection. One hook covers both ops metrics and a
133
+ * compliance audit trail; see `OPERATIONS.md` for wiring examples.
134
+ */
135
+ onArtifactEvent?: PulseVaultOnArtifactEvent;
136
+ /**
137
+ * @deprecated Use `validatePayload` instead — it now receives `ctx.kind`
138
+ * and runs for every artifact kind, including `"project"`. Still honored
139
+ * this release (mapped onto `validatePayload` when `kind === "project"`),
140
+ * but will be removed in a future major version. Passing this triggers a
141
+ * one-time `DeprecationWarning` at registration.
142
+ */
143
+ validateProjectPayload?: PulseVaultValidatePayload;
144
+ /**
145
+ * @deprecated Use `onUploadComplete` instead — it now receives `ctx.kind`
146
+ * and runs for every artifact kind, including `"project"`. Still honored
147
+ * this release (mapped onto `onUploadComplete` when `kind === "project"`),
148
+ * but will be removed in a future major version. Passing this triggers a
149
+ * one-time `DeprecationWarning` at registration.
150
+ */
151
+ onProjectUploadComplete?: PulseVaultOnUploadComplete;
102
152
  };
103
153
  declare const _default: FastifyPluginAsync<PulseVaultPluginOptions>;
104
154
  export default _default;
105
- export { createLocalStorage } from "./storage/local.js";
106
- export type { LocalStorage, LocalStorageOptions } from "./storage/local.js";
107
- export type { PulseVaultResolution, PulseVaultStorage, ReserveUploadParams, } from "./storage/types.js";
108
- export type { PulseVaultAuthorize, PulseVaultAuthorizeContext, PulseVaultAuthorizePhase, } from "./routes/pulsevault.js";
109
- export type { PulseVaultOnUploadComplete } from "./lib/pulsevaultTus.js";
110
- export { sniffMp4, createMp4Sniffer } from "./lib/magic.js";
111
- export type { PulseVaultValidatePayload } from "./lib/magic.js";
112
- export { buildConfigureDestinationLink, buildUploadLink, } from "./lib/deeplinks.js";
113
- export type { ConfigureDestinationLinkOptions, UploadLinkOptions, } from "./lib/deeplinks.js";
155
+ export { createLocalStorage } from './storage/local.js';
156
+ export type { LocalStorage, LocalStorageOptions } from './storage/local.js';
157
+ export { createS3Storage } from './storage/s3.js';
158
+ export type { S3Storage, S3StorageOptions } from './storage/s3.js';
159
+ export type { PulseVaultResolution, PulseVaultStorage, ReserveUploadParams, UploadKind, } from './storage/types.js';
160
+ export type { PulseVaultAuthorize, PulseVaultAuthorizeContext, PulseVaultAuthorizePhase, } from './routes/pulsevault.js';
161
+ export type { PulseVaultOnUploadComplete, PulseVaultOnArtifactEvent, PulseVaultArtifactEvent, } from './lib/pulsevaultTus.js';
162
+ export { sniffMp4, createMp4Sniffer, createS3Mp4Sniffer } from './lib/magic.js';
163
+ export type { PulseVaultValidatePayload } from './lib/magic.js';
164
+ export { buildUploadLink } from './lib/deeplinks.js';
165
+ export type { UploadLinkOptions } from './lib/deeplinks.js';
166
+ export { issueCapabilityToken, verifyCapabilityToken, createCapabilityAuthorize, } from './lib/capability-token.js';
167
+ export type { CapabilityTokenClaims, IssueCapabilityTokenOptions, VerifyCapabilityTokenOptions, LookupSecret, } from './lib/capability-token.js';
168
+ export { createChecksumValidator, createS3ChecksumValidator, parseChecksumMetadata, } from './lib/checksum.js';
169
+ export type { ChecksumAlgorithm, ParsedChecksum } from './lib/checksum.js';
170
+ export type { PulseVaultRequest, PulseVaultLogger } from './lib/request.js';
114
171
  //# sourceMappingURL=app.d.ts.map
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,OAAyB,EACvB,KAAK,mBAAmB,EAGzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,sEAAsE;IACtE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,wFAAwF;IACxF,OAAO,EAAE,iBAAiB,CAAC;IAC3B;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;CAC/C,CAAC;;AAgEF,wBAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,6BAA6B,EAC7B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,+BAA+B,EAC/B,iBAAiB,GAClB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/app.js CHANGED
@@ -1,54 +1,44 @@
1
- import fp from "fastify-plugin";
2
- import pulseVaultRoutes, {} from "./routes/pulsevault.js";
3
- const DEFAULT_DECORATOR_NAME = "pulseVault";
4
- const DEFAULT_ALLOWED_EXTENSIONS = [".mp4"];
5
- const EXTENSION_REGEX = /^\.[^.\s/\\]+$/;
6
- function validateOptions(opts) {
7
- if (opts.prefix !== "" && (!opts.prefix.startsWith("/") || opts.prefix.endsWith("/"))) {
8
- throw new TypeError("`prefix` must be '' or start with '/' with no trailing slash (e.g. '/pulsevault')");
9
- }
10
- if (!(opts.maxUploadSize > 0)) {
11
- throw new TypeError("`maxUploadSize` must be a positive number (use Infinity for no cap)");
12
- }
13
- if (opts.allowedExtensions) {
14
- if (opts.allowedExtensions.length === 0) {
15
- throw new TypeError("`allowedExtensions` must not be empty");
16
- }
17
- for (const ext of opts.allowedExtensions) {
18
- if (!EXTENSION_REGEX.test(ext)) {
19
- throw new TypeError(`\`allowedExtensions\` entry ${JSON.stringify(ext)} must start with '.' and contain no nested dots, slashes, or whitespace (e.g. '.mp4')`);
20
- }
21
- }
22
- }
23
- }
1
+ import fp from 'fastify-plugin';
2
+ import pulseVaultRoutes, {} from './routes/pulsevault.js';
3
+ import { normalizeAllowedExtensions, validateBasePath, validateMaxUploadSize, validateUploadUnit, validateAllowedExtensions, warnIfUsingDeprecatedProjectHooks, composeValidatePayload, composeOnUploadComplete, } from './lib/options.js';
4
+ const DEFAULT_DECORATOR_NAME = 'pulseVault';
24
5
  const app = async (fastify, opts) => {
25
- validateOptions(opts);
6
+ validateBasePath(opts.prefix, 'prefix');
7
+ validateMaxUploadSize(opts.maxUploadSize);
8
+ validateUploadUnit(opts.uploadUnit);
9
+ validateAllowedExtensions(opts.allowedExtensions);
10
+ warnIfUsingDeprecatedProjectHooks(opts);
26
11
  // Register the shutdown hook *before* awaiting initialize() so any partial
27
12
  // state the adapter allocates mid-init still gets cleaned up if Fastify
28
13
  // later tears the plugin down.
29
- fastify.addHook("onClose", async () => {
14
+ fastify.addHook('onClose', async () => {
30
15
  await opts.storage.shutdown?.();
31
16
  });
32
17
  await opts.storage.initialize?.();
33
18
  const decoratorName = opts.decoratorName ?? DEFAULT_DECORATOR_NAME;
34
- const allowedExtensions = (opts.allowedExtensions ?? DEFAULT_ALLOWED_EXTENSIONS).map((e) => e.toLowerCase());
19
+ const allowedExtensions = normalizeAllowedExtensions(opts.allowedExtensions);
35
20
  fastify.decorate(decoratorName, opts.storage);
36
21
  await fastify.register(pulseVaultRoutes, {
37
22
  prefix: opts.prefix,
38
23
  storage: opts.storage,
39
24
  maxUploadSize: opts.maxUploadSize,
25
+ uploadUnit: opts.uploadUnit ?? 'segment',
40
26
  allowedExtensions,
41
27
  cache: opts.cache,
42
28
  authorize: opts.authorize,
43
- validatePayload: opts.validatePayload,
44
- onUploadComplete: opts.onUploadComplete,
29
+ validatePayload: composeValidatePayload(opts.validatePayload, opts.validateProjectPayload),
30
+ onUploadComplete: composeOnUploadComplete(opts.onUploadComplete, opts.onProjectUploadComplete),
31
+ onArtifactEvent: opts.onArtifactEvent,
45
32
  });
46
33
  };
47
34
  export default fp(app, {
48
- name: "pulsevault",
49
- fastify: "5.x",
35
+ name: 'pulsevault',
36
+ fastify: '5.x',
50
37
  });
51
- export { createLocalStorage } from "./storage/local.js";
52
- export { sniffMp4, createMp4Sniffer } from "./lib/magic.js";
53
- export { buildConfigureDestinationLink, buildUploadLink, } from "./lib/deeplinks.js";
38
+ export { createLocalStorage } from './storage/local.js';
39
+ export { createS3Storage } from './storage/s3.js';
40
+ export { sniffMp4, createMp4Sniffer, createS3Mp4Sniffer } from './lib/magic.js';
41
+ export { buildUploadLink } from './lib/deeplinks.js';
42
+ export { issueCapabilityToken, verifyCapabilityToken, createCapabilityAuthorize, } from './lib/capability-token.js';
43
+ export { createChecksumValidator, createS3ChecksumValidator, parseChecksumMetadata, } from './lib/checksum.js';
54
44
  //# sourceMappingURL=app.js.map
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,gBAAgB,EAAE,EAA4B,MAAM,wBAAwB,CAAC;AAIpF,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,iCAAiC,EACjC,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAqJ1B,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAE5C,MAAM,GAAG,GAAgD,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC/E,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxC,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC1C,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpC,yBAAyB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAClD,iCAAiC,CAAC,IAAI,CAAC,CAAC;IAExC,2EAA2E;IAC3E,wEAAwE;IACxE,+BAA+B;IAC/B,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;IAClC,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,sBAAsB,CAAC;IACnE,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAE7E,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAE9C,MAAM,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE;QACvC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,SAAS;QACxC,iBAAiB;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,eAAe,EAAE,sBAAsB,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,sBAAsB,CAAC;QAC1F,gBAAgB,EAAE,uBAAuB,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,uBAAuB,CAAC;QAC9F,eAAe,EAAE,IAAI,CAAC,eAAe;KACtC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,eAAe,EAAE,CAAC,GAAG,EAAE;IACrB,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,KAAK;CACf,CAAC,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAkBlD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC"}
package/dist/augment.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import type { PulseVaultStorage } from "./storage/types.js";
1
+ import type { PulseVaultStorage, UploadKind } from './storage/types.js';
2
2
  /**
3
3
  * Opt-in TypeScript augmentation for the default `pulseVault` decorator and
4
4
  * the per-request `request.pulseVault` context that the plugin sets when it
5
- * recognizes a videoid on the incoming request. Import for side effects in
6
- * one place in your app when you register the plugin with the default
5
+ * recognizes an artifactId on the incoming request. Import for side effects
6
+ * in one place in your app when you register the plugin with the default
7
7
  * `decoratorName`:
8
8
  *
9
9
  * ```ts
@@ -19,25 +19,32 @@ import type { PulseVaultStorage } from "./storage/types.js";
19
19
  * myCustomName: PulseVaultStorage;
20
20
  * }
21
21
  * interface FastifyRequest {
22
- * pulseVault?: { videoid: string };
22
+ * pulseVault?: { artifactId: string };
23
23
  * }
24
24
  * }
25
25
  * ```
26
+ *
27
+ * **Breaking change**: this field was named `videoid` before this release.
28
+ * It's renamed to `artifactId` here as a deliberate, separate breaking change
29
+ * from the wire-format rename — update any code reading
30
+ * `request.pulseVault.videoid` to `request.pulseVault.artifactId`.
26
31
  */
27
- declare module "fastify" {
32
+ declare module 'fastify' {
28
33
  interface FastifyInstance {
29
34
  pulseVault: PulseVaultStorage;
30
35
  }
31
36
  interface FastifyRequest {
32
37
  /**
33
- * Populated by the plugin when it can extract a videoid from the
38
+ * Populated by the plugin when it can extract an artifactId from the
34
39
  * incoming request (from `Upload-Metadata` on POST, the URL id on
35
40
  * PATCH/HEAD/DELETE, or the route param on GET). Present on every
36
41
  * request the plugin routes serve that refer to a valid UUID — use it
37
42
  * from your own `preHandler` / auth hooks to avoid re-parsing.
38
43
  */
39
44
  pulseVault?: {
40
- videoid: string;
45
+ artifactId: string;
46
+ kind: UploadKind;
47
+ relatedTo?: string;
41
48
  };
42
49
  }
43
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"augment.d.ts","sourceRoot":"","sources":["../src/augment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,UAAU,EAAE,iBAAiB,CAAC;KAC/B;IACD,UAAU,cAAc;QACtB;;;;;;WAMG;QACH,UAAU,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAClC;CACF;AAED,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"augment.d.ts","sourceRoot":"","sources":["../src/augment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,UAAU,EAAE,iBAAiB,CAAC;KAC/B;IACD,UAAU,cAAc;QACtB;;;;;;WAMG;QACH,UAAU,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,UAAU,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3E;CACF;AAED,OAAO,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"augment.js","sourceRoot":"","sources":["../src/augment.ts"],"names":[],"mappings":"AA2CA,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"augment.js","sourceRoot":"","sources":["../src/augment.ts"],"names":[],"mappings":"AAgDA,OAAO,EAAE,CAAC"}
package/dist/core.d.ts ADDED
@@ -0,0 +1,108 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import { type PulseVaultOnUploadComplete, type PulseVaultOnArtifactEvent } from './lib/pulsevaultTus.js';
3
+ import type { PulseVaultValidatePayload } from './lib/magic.js';
4
+ import type { PulseVaultAuthorize } from './lib/authorize.js';
5
+ import { type PulseVaultLogger } from './lib/request.js';
6
+ import type { PulseVaultStorage } from './storage/types.js';
7
+ import { type PulseVaultAllowedExtensionsInput } from './lib/options.js';
8
+ /** Wire protocol version this release implements. See `/capabilities` and `PROTOCOL.md`. */
9
+ export declare const PROTOCOL_VERSION = 1;
10
+ export type PulseVaultCoreCacheOptions = {
11
+ cacheControl?: boolean;
12
+ maxAge?: string | number;
13
+ immutable?: boolean;
14
+ };
15
+ export type PulseVaultCoreOptions = {
16
+ /** Storage adapter. Use `createLocalStorage(...)` for filesystem-backed deployments. */
17
+ storage: PulseVaultStorage;
18
+ /**
19
+ * URL path prefix where the core's routes are mounted, e.g. `"/pulsevault"`.
20
+ * Use `""` to mount at the root. Unlike the Fastify plugin, there's no
21
+ * framework-level prefix mechanism to lean on here — the core needs this
22
+ * explicitly to compute the tus base path and to strip it from incoming
23
+ * request URLs.
24
+ */
25
+ basePath: string;
26
+ /**
27
+ * Whether `handler` should itself match/strip `basePath` from incoming
28
+ * request URLs. Defaults to `true` — correct for a raw
29
+ * `http.createServer` callback, or any host that hands `handler` the
30
+ * request's full, unmodified URL (unmatched paths 404). Set to `false`
31
+ * when mounting via a framework that already strips its own mount prefix
32
+ * before calling middleware — Express's `app.use(basePath, handler)`, or
33
+ * Connect/Meteor's `WebApp.connectHandlers.use(basePath, handler)` — so
34
+ * `handler` treats `req.url` as already relative to `basePath`. Either
35
+ * way, `basePath` is still used to build the tus `Location` header
36
+ * returned to clients.
37
+ */
38
+ stripBasePath?: boolean;
39
+ /** Max TUS upload size in bytes. Required — consumers must choose an explicit cap. Use `Infinity` for no cap. */
40
+ maxUploadSize: number;
41
+ /** Which upload strategy this deployment expects. Purely advertised via `GET /capabilities`. Defaults to `"segment"`. */
42
+ uploadUnit?: 'segment' | 'merged';
43
+ /** File extensions allowed per artifact kind. See the Fastify plugin's `allowedExtensions` for the full shape. */
44
+ allowedExtensions?: PulseVaultAllowedExtensionsInput;
45
+ /** Cache-control options forwarded to `@fastify/send` for the GET route. */
46
+ cache?: PulseVaultCoreCacheOptions;
47
+ /** Optional authorization hook. See the Fastify plugin's `authorize` option for semantics. */
48
+ authorize?: PulseVaultAuthorize;
49
+ /** Optional payload-validation hook. See the Fastify plugin's `validatePayload` option for semantics. */
50
+ validatePayload?: PulseVaultValidatePayload;
51
+ /** Optional post-upload hook. See the Fastify plugin's `onUploadComplete` option for semantics. */
52
+ onUploadComplete?: PulseVaultOnUploadComplete;
53
+ /** Optional low-frequency event hook. See the Fastify plugin's `onArtifactEvent` option for semantics. */
54
+ onArtifactEvent?: PulseVaultOnArtifactEvent;
55
+ /** Logger for internal diagnostics (authorize rejections, tus handler failures). Defaults to `console`. */
56
+ logger?: PulseVaultLogger;
57
+ /** @deprecated Use `validatePayload` instead — see the Fastify plugin's option of the same name. */
58
+ validateProjectPayload?: PulseVaultValidatePayload;
59
+ /** @deprecated Use `onUploadComplete` instead — see the Fastify plugin's option of the same name. */
60
+ onProjectUploadComplete?: PulseVaultOnUploadComplete;
61
+ };
62
+ type ConnectNext = (err?: unknown) => void;
63
+ export type PulseVaultCore = {
64
+ /**
65
+ * Connect-style request handler — mount directly as Express middleware
66
+ * (`app.use(basePath, core.handler)`), Meteor middleware
67
+ * (`WebApp.connectHandlers.use(basePath, core.handler)`), or a bare
68
+ * `http.createServer` callback. `next` is optional so it also works as a
69
+ * raw `http.createServer((req, res) => core.handler(req, res))` handler.
70
+ */
71
+ handler: (req: IncomingMessage, res: ServerResponse, next?: ConnectNext) => Promise<void>;
72
+ /** One-time teardown — calls `storage.shutdown?.()`. */
73
+ shutdown: () => Promise<void>;
74
+ /** Handles a TUS create/patch/head/delete request directly (any method under `/upload`). */
75
+ handleTus: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
76
+ /** Writes the `GET /capabilities` JSON payload. */
77
+ handleCapabilities: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
78
+ /** Resolves and streams/redirects `GET /artifacts/:artifactId`. */
79
+ handleArtifactGet: (req: IncomingMessage, res: ServerResponse, artifactId: string, token: string | undefined) => Promise<void>;
80
+ /** Handles `DELETE /artifacts/:artifactId`. */
81
+ handleArtifactDelete: (req: IncomingMessage, res: ServerResponse, artifactId: string) => Promise<void>;
82
+ };
83
+ /**
84
+ * Build the framework-agnostic core: the same authorize/validatePayload/
85
+ * onUploadComplete/onArtifactEvent orchestration, tus glue, capabilities
86
+ * payload, and artifact GET/DELETE logic the Fastify plugin uses, operating
87
+ * on raw `(req, res)` instead of Fastify's `request`/`reply` wrappers. Both
88
+ * the Fastify plugin and this factory ultimately call into the same
89
+ * `lib/pulsevaultTus.js` tus server, so behavior can't drift between them.
90
+ */
91
+ export declare function createPulseVaultCore(options: PulseVaultCoreOptions): PulseVaultCore;
92
+ export { createLocalStorage } from './storage/local.js';
93
+ export type { LocalStorage, LocalStorageOptions } from './storage/local.js';
94
+ export { createS3Storage } from './storage/s3.js';
95
+ export type { S3Storage, S3StorageOptions } from './storage/s3.js';
96
+ export type { PulseVaultResolution, PulseVaultStorage, ReserveUploadParams, UploadKind, } from './storage/types.js';
97
+ export type { PulseVaultAuthorize, PulseVaultAuthorizeContext, PulseVaultAuthorizePhase, } from './lib/authorize.js';
98
+ export type { PulseVaultOnUploadComplete, PulseVaultOnArtifactEvent, PulseVaultArtifactEvent, } from './lib/pulsevaultTus.js';
99
+ export { sniffMp4, createMp4Sniffer, createS3Mp4Sniffer } from './lib/magic.js';
100
+ export type { PulseVaultValidatePayload } from './lib/magic.js';
101
+ export { buildUploadLink } from './lib/deeplinks.js';
102
+ export type { UploadLinkOptions } from './lib/deeplinks.js';
103
+ export { issueCapabilityToken, verifyCapabilityToken, createCapabilityAuthorize, } from './lib/capability-token.js';
104
+ export type { CapabilityTokenClaims, IssueCapabilityTokenOptions, VerifyCapabilityTokenOptions, LookupSecret, } from './lib/capability-token.js';
105
+ export { createChecksumValidator, createS3ChecksumValidator, parseChecksumMetadata, } from './lib/checksum.js';
106
+ export type { ChecksumAlgorithm, ParsedChecksum } from './lib/checksum.js';
107
+ export { type PulseVaultRequest, type PulseVaultLogger } from './lib/request.js';
108
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}