@mieweb/pulsevault 0.3.0 → 0.4.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.
- package/CHANGELOG.md +113 -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-version.gen.d.ts +6 -0
- package/dist/lib/protocol-version.gen.d.ts.map +1 -0
- package/dist/lib/protocol-version.gen.js +8 -0
- package/dist/lib/protocol-version.gen.js.map +1 -0
- package/dist/lib/protocol.d.ts +31 -0
- package/dist/lib/protocol.d.ts.map +1 -0
- package/dist/lib/protocol.js +64 -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 +16 -4
- 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,1058 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.0.3",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "Pulse upload protocol",
|
|
5
|
+
"description": "The HTTP surface of the Pulse upload protocol, as implemented by @mieweb/pulsevault. Generated from the plugin's route schemas — see PROTOCOL.md for the full contract.",
|
|
6
|
+
"version": "2.2"
|
|
7
|
+
},
|
|
8
|
+
"components": {
|
|
9
|
+
"schemas": {}
|
|
10
|
+
},
|
|
11
|
+
"paths": {
|
|
12
|
+
"/pulsevault/upload": {
|
|
13
|
+
"post": {
|
|
14
|
+
"summary": "TUS resumable upload endpoint",
|
|
15
|
+
"tags": [
|
|
16
|
+
"pulsevault"
|
|
17
|
+
],
|
|
18
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
19
|
+
"responses": {
|
|
20
|
+
"400": {
|
|
21
|
+
"description": "Invalid request.",
|
|
22
|
+
"content": {
|
|
23
|
+
"application/json": {
|
|
24
|
+
"schema": {
|
|
25
|
+
"description": "Invalid request.",
|
|
26
|
+
"type": "object",
|
|
27
|
+
"properties": {
|
|
28
|
+
"ok": {
|
|
29
|
+
"type": "boolean"
|
|
30
|
+
},
|
|
31
|
+
"error": {
|
|
32
|
+
"type": "string"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"required": [
|
|
36
|
+
"ok",
|
|
37
|
+
"error"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"403": {
|
|
44
|
+
"description": "Authorize hook rejected the request.",
|
|
45
|
+
"content": {
|
|
46
|
+
"application/json": {
|
|
47
|
+
"schema": {
|
|
48
|
+
"description": "Authorize hook rejected the request.",
|
|
49
|
+
"type": "object",
|
|
50
|
+
"properties": {
|
|
51
|
+
"ok": {
|
|
52
|
+
"type": "boolean"
|
|
53
|
+
},
|
|
54
|
+
"error": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"required": [
|
|
59
|
+
"ok",
|
|
60
|
+
"error"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"patch": {
|
|
69
|
+
"summary": "TUS resumable upload endpoint",
|
|
70
|
+
"tags": [
|
|
71
|
+
"pulsevault"
|
|
72
|
+
],
|
|
73
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
74
|
+
"responses": {
|
|
75
|
+
"400": {
|
|
76
|
+
"description": "Invalid request.",
|
|
77
|
+
"content": {
|
|
78
|
+
"application/json": {
|
|
79
|
+
"schema": {
|
|
80
|
+
"description": "Invalid request.",
|
|
81
|
+
"type": "object",
|
|
82
|
+
"properties": {
|
|
83
|
+
"ok": {
|
|
84
|
+
"type": "boolean"
|
|
85
|
+
},
|
|
86
|
+
"error": {
|
|
87
|
+
"type": "string"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"required": [
|
|
91
|
+
"ok",
|
|
92
|
+
"error"
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"403": {
|
|
99
|
+
"description": "Authorize hook rejected the request.",
|
|
100
|
+
"content": {
|
|
101
|
+
"application/json": {
|
|
102
|
+
"schema": {
|
|
103
|
+
"description": "Authorize hook rejected the request.",
|
|
104
|
+
"type": "object",
|
|
105
|
+
"properties": {
|
|
106
|
+
"ok": {
|
|
107
|
+
"type": "boolean"
|
|
108
|
+
},
|
|
109
|
+
"error": {
|
|
110
|
+
"type": "string"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"required": [
|
|
114
|
+
"ok",
|
|
115
|
+
"error"
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"head": {
|
|
124
|
+
"summary": "TUS resumable upload endpoint",
|
|
125
|
+
"tags": [
|
|
126
|
+
"pulsevault"
|
|
127
|
+
],
|
|
128
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
129
|
+
"responses": {
|
|
130
|
+
"400": {
|
|
131
|
+
"description": "Invalid request.",
|
|
132
|
+
"content": {
|
|
133
|
+
"application/json": {
|
|
134
|
+
"schema": {
|
|
135
|
+
"description": "Invalid request.",
|
|
136
|
+
"type": "object",
|
|
137
|
+
"properties": {
|
|
138
|
+
"ok": {
|
|
139
|
+
"type": "boolean"
|
|
140
|
+
},
|
|
141
|
+
"error": {
|
|
142
|
+
"type": "string"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"required": [
|
|
146
|
+
"ok",
|
|
147
|
+
"error"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"403": {
|
|
154
|
+
"description": "Authorize hook rejected the request.",
|
|
155
|
+
"content": {
|
|
156
|
+
"application/json": {
|
|
157
|
+
"schema": {
|
|
158
|
+
"description": "Authorize hook rejected the request.",
|
|
159
|
+
"type": "object",
|
|
160
|
+
"properties": {
|
|
161
|
+
"ok": {
|
|
162
|
+
"type": "boolean"
|
|
163
|
+
},
|
|
164
|
+
"error": {
|
|
165
|
+
"type": "string"
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"required": [
|
|
169
|
+
"ok",
|
|
170
|
+
"error"
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"delete": {
|
|
179
|
+
"summary": "TUS resumable upload endpoint",
|
|
180
|
+
"tags": [
|
|
181
|
+
"pulsevault"
|
|
182
|
+
],
|
|
183
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
184
|
+
"responses": {
|
|
185
|
+
"400": {
|
|
186
|
+
"description": "Invalid request.",
|
|
187
|
+
"content": {
|
|
188
|
+
"application/json": {
|
|
189
|
+
"schema": {
|
|
190
|
+
"description": "Invalid request.",
|
|
191
|
+
"type": "object",
|
|
192
|
+
"properties": {
|
|
193
|
+
"ok": {
|
|
194
|
+
"type": "boolean"
|
|
195
|
+
},
|
|
196
|
+
"error": {
|
|
197
|
+
"type": "string"
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"required": [
|
|
201
|
+
"ok",
|
|
202
|
+
"error"
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"403": {
|
|
209
|
+
"description": "Authorize hook rejected the request.",
|
|
210
|
+
"content": {
|
|
211
|
+
"application/json": {
|
|
212
|
+
"schema": {
|
|
213
|
+
"description": "Authorize hook rejected the request.",
|
|
214
|
+
"type": "object",
|
|
215
|
+
"properties": {
|
|
216
|
+
"ok": {
|
|
217
|
+
"type": "boolean"
|
|
218
|
+
},
|
|
219
|
+
"error": {
|
|
220
|
+
"type": "string"
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
"required": [
|
|
224
|
+
"ok",
|
|
225
|
+
"error"
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"options": {
|
|
234
|
+
"summary": "TUS resumable upload endpoint",
|
|
235
|
+
"tags": [
|
|
236
|
+
"pulsevault"
|
|
237
|
+
],
|
|
238
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
239
|
+
"responses": {
|
|
240
|
+
"400": {
|
|
241
|
+
"description": "Invalid request.",
|
|
242
|
+
"content": {
|
|
243
|
+
"application/json": {
|
|
244
|
+
"schema": {
|
|
245
|
+
"description": "Invalid request.",
|
|
246
|
+
"type": "object",
|
|
247
|
+
"properties": {
|
|
248
|
+
"ok": {
|
|
249
|
+
"type": "boolean"
|
|
250
|
+
},
|
|
251
|
+
"error": {
|
|
252
|
+
"type": "string"
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
"required": [
|
|
256
|
+
"ok",
|
|
257
|
+
"error"
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"403": {
|
|
264
|
+
"description": "Authorize hook rejected the request.",
|
|
265
|
+
"content": {
|
|
266
|
+
"application/json": {
|
|
267
|
+
"schema": {
|
|
268
|
+
"description": "Authorize hook rejected the request.",
|
|
269
|
+
"type": "object",
|
|
270
|
+
"properties": {
|
|
271
|
+
"ok": {
|
|
272
|
+
"type": "boolean"
|
|
273
|
+
},
|
|
274
|
+
"error": {
|
|
275
|
+
"type": "string"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"required": [
|
|
279
|
+
"ok",
|
|
280
|
+
"error"
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"/pulsevault/upload/{*}": {
|
|
290
|
+
"post": {
|
|
291
|
+
"summary": "TUS resumable upload endpoint",
|
|
292
|
+
"tags": [
|
|
293
|
+
"pulsevault"
|
|
294
|
+
],
|
|
295
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
296
|
+
"parameters": [
|
|
297
|
+
{
|
|
298
|
+
"schema": {
|
|
299
|
+
"type": "string"
|
|
300
|
+
},
|
|
301
|
+
"in": "path",
|
|
302
|
+
"name": "*",
|
|
303
|
+
"required": true
|
|
304
|
+
}
|
|
305
|
+
],
|
|
306
|
+
"responses": {
|
|
307
|
+
"400": {
|
|
308
|
+
"description": "Invalid request.",
|
|
309
|
+
"content": {
|
|
310
|
+
"application/json": {
|
|
311
|
+
"schema": {
|
|
312
|
+
"description": "Invalid request.",
|
|
313
|
+
"type": "object",
|
|
314
|
+
"properties": {
|
|
315
|
+
"ok": {
|
|
316
|
+
"type": "boolean"
|
|
317
|
+
},
|
|
318
|
+
"error": {
|
|
319
|
+
"type": "string"
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"required": [
|
|
323
|
+
"ok",
|
|
324
|
+
"error"
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
"403": {
|
|
331
|
+
"description": "Authorize hook rejected the request.",
|
|
332
|
+
"content": {
|
|
333
|
+
"application/json": {
|
|
334
|
+
"schema": {
|
|
335
|
+
"description": "Authorize hook rejected the request.",
|
|
336
|
+
"type": "object",
|
|
337
|
+
"properties": {
|
|
338
|
+
"ok": {
|
|
339
|
+
"type": "boolean"
|
|
340
|
+
},
|
|
341
|
+
"error": {
|
|
342
|
+
"type": "string"
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
"required": [
|
|
346
|
+
"ok",
|
|
347
|
+
"error"
|
|
348
|
+
]
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
"patch": {
|
|
356
|
+
"summary": "TUS resumable upload endpoint",
|
|
357
|
+
"tags": [
|
|
358
|
+
"pulsevault"
|
|
359
|
+
],
|
|
360
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
361
|
+
"parameters": [
|
|
362
|
+
{
|
|
363
|
+
"schema": {
|
|
364
|
+
"type": "string"
|
|
365
|
+
},
|
|
366
|
+
"in": "path",
|
|
367
|
+
"name": "*",
|
|
368
|
+
"required": true
|
|
369
|
+
}
|
|
370
|
+
],
|
|
371
|
+
"responses": {
|
|
372
|
+
"400": {
|
|
373
|
+
"description": "Invalid request.",
|
|
374
|
+
"content": {
|
|
375
|
+
"application/json": {
|
|
376
|
+
"schema": {
|
|
377
|
+
"description": "Invalid request.",
|
|
378
|
+
"type": "object",
|
|
379
|
+
"properties": {
|
|
380
|
+
"ok": {
|
|
381
|
+
"type": "boolean"
|
|
382
|
+
},
|
|
383
|
+
"error": {
|
|
384
|
+
"type": "string"
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
"required": [
|
|
388
|
+
"ok",
|
|
389
|
+
"error"
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
"403": {
|
|
396
|
+
"description": "Authorize hook rejected the request.",
|
|
397
|
+
"content": {
|
|
398
|
+
"application/json": {
|
|
399
|
+
"schema": {
|
|
400
|
+
"description": "Authorize hook rejected the request.",
|
|
401
|
+
"type": "object",
|
|
402
|
+
"properties": {
|
|
403
|
+
"ok": {
|
|
404
|
+
"type": "boolean"
|
|
405
|
+
},
|
|
406
|
+
"error": {
|
|
407
|
+
"type": "string"
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
"required": [
|
|
411
|
+
"ok",
|
|
412
|
+
"error"
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
"head": {
|
|
421
|
+
"summary": "TUS resumable upload endpoint",
|
|
422
|
+
"tags": [
|
|
423
|
+
"pulsevault"
|
|
424
|
+
],
|
|
425
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
426
|
+
"parameters": [
|
|
427
|
+
{
|
|
428
|
+
"schema": {
|
|
429
|
+
"type": "string"
|
|
430
|
+
},
|
|
431
|
+
"in": "path",
|
|
432
|
+
"name": "*",
|
|
433
|
+
"required": true
|
|
434
|
+
}
|
|
435
|
+
],
|
|
436
|
+
"responses": {
|
|
437
|
+
"400": {
|
|
438
|
+
"description": "Invalid request.",
|
|
439
|
+
"content": {
|
|
440
|
+
"application/json": {
|
|
441
|
+
"schema": {
|
|
442
|
+
"description": "Invalid request.",
|
|
443
|
+
"type": "object",
|
|
444
|
+
"properties": {
|
|
445
|
+
"ok": {
|
|
446
|
+
"type": "boolean"
|
|
447
|
+
},
|
|
448
|
+
"error": {
|
|
449
|
+
"type": "string"
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
"required": [
|
|
453
|
+
"ok",
|
|
454
|
+
"error"
|
|
455
|
+
]
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
"403": {
|
|
461
|
+
"description": "Authorize hook rejected the request.",
|
|
462
|
+
"content": {
|
|
463
|
+
"application/json": {
|
|
464
|
+
"schema": {
|
|
465
|
+
"description": "Authorize hook rejected the request.",
|
|
466
|
+
"type": "object",
|
|
467
|
+
"properties": {
|
|
468
|
+
"ok": {
|
|
469
|
+
"type": "boolean"
|
|
470
|
+
},
|
|
471
|
+
"error": {
|
|
472
|
+
"type": "string"
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
"required": [
|
|
476
|
+
"ok",
|
|
477
|
+
"error"
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
"delete": {
|
|
486
|
+
"summary": "TUS resumable upload endpoint",
|
|
487
|
+
"tags": [
|
|
488
|
+
"pulsevault"
|
|
489
|
+
],
|
|
490
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
491
|
+
"parameters": [
|
|
492
|
+
{
|
|
493
|
+
"schema": {
|
|
494
|
+
"type": "string"
|
|
495
|
+
},
|
|
496
|
+
"in": "path",
|
|
497
|
+
"name": "*",
|
|
498
|
+
"required": true
|
|
499
|
+
}
|
|
500
|
+
],
|
|
501
|
+
"responses": {
|
|
502
|
+
"400": {
|
|
503
|
+
"description": "Invalid request.",
|
|
504
|
+
"content": {
|
|
505
|
+
"application/json": {
|
|
506
|
+
"schema": {
|
|
507
|
+
"description": "Invalid request.",
|
|
508
|
+
"type": "object",
|
|
509
|
+
"properties": {
|
|
510
|
+
"ok": {
|
|
511
|
+
"type": "boolean"
|
|
512
|
+
},
|
|
513
|
+
"error": {
|
|
514
|
+
"type": "string"
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
"required": [
|
|
518
|
+
"ok",
|
|
519
|
+
"error"
|
|
520
|
+
]
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
"403": {
|
|
526
|
+
"description": "Authorize hook rejected the request.",
|
|
527
|
+
"content": {
|
|
528
|
+
"application/json": {
|
|
529
|
+
"schema": {
|
|
530
|
+
"description": "Authorize hook rejected the request.",
|
|
531
|
+
"type": "object",
|
|
532
|
+
"properties": {
|
|
533
|
+
"ok": {
|
|
534
|
+
"type": "boolean"
|
|
535
|
+
},
|
|
536
|
+
"error": {
|
|
537
|
+
"type": "string"
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
"required": [
|
|
541
|
+
"ok",
|
|
542
|
+
"error"
|
|
543
|
+
]
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
},
|
|
550
|
+
"options": {
|
|
551
|
+
"summary": "TUS resumable upload endpoint",
|
|
552
|
+
"tags": [
|
|
553
|
+
"pulsevault"
|
|
554
|
+
],
|
|
555
|
+
"description": "TUS v1 resumable upload protocol.\n\n- `POST` creates a new upload. The `Upload-Metadata` header must include base64-encoded key/value pairs:\n - `artifactId` (or the legacy `videoid`/`projectid` aliases) — a UUID generated by your server.\n - `filename` — original filename; the extension must match the kind's allowed list.\n - `kind` — `video` (default), `project`, `captions`, or `thumbnail`. Determines the storage subdir and which completion hooks fire.\n - `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 - `checksum` — optional `<algorithm>:<hex digest>` of the finished file, verified post-upload if a checksum validator is configured.\n- `PATCH` appends a chunk at the offset given by `Upload-Offset`, with `Content-Type: application/offset+octet-stream`.\n- `HEAD` returns the current offset for a resumable upload.\n- `DELETE` removes the upload and its artifact, whether in flight (a cancel) or finished. Authorized as `delete`.\n\nSee https://tus.io/protocols/resumable-upload for the full protocol.",
|
|
556
|
+
"parameters": [
|
|
557
|
+
{
|
|
558
|
+
"schema": {
|
|
559
|
+
"type": "string"
|
|
560
|
+
},
|
|
561
|
+
"in": "path",
|
|
562
|
+
"name": "*",
|
|
563
|
+
"required": true
|
|
564
|
+
}
|
|
565
|
+
],
|
|
566
|
+
"responses": {
|
|
567
|
+
"400": {
|
|
568
|
+
"description": "Invalid request.",
|
|
569
|
+
"content": {
|
|
570
|
+
"application/json": {
|
|
571
|
+
"schema": {
|
|
572
|
+
"description": "Invalid request.",
|
|
573
|
+
"type": "object",
|
|
574
|
+
"properties": {
|
|
575
|
+
"ok": {
|
|
576
|
+
"type": "boolean"
|
|
577
|
+
},
|
|
578
|
+
"error": {
|
|
579
|
+
"type": "string"
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
"required": [
|
|
583
|
+
"ok",
|
|
584
|
+
"error"
|
|
585
|
+
]
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
"403": {
|
|
591
|
+
"description": "Authorize hook rejected the request.",
|
|
592
|
+
"content": {
|
|
593
|
+
"application/json": {
|
|
594
|
+
"schema": {
|
|
595
|
+
"description": "Authorize hook rejected the request.",
|
|
596
|
+
"type": "object",
|
|
597
|
+
"properties": {
|
|
598
|
+
"ok": {
|
|
599
|
+
"type": "boolean"
|
|
600
|
+
},
|
|
601
|
+
"error": {
|
|
602
|
+
"type": "string"
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
"required": [
|
|
606
|
+
"ok",
|
|
607
|
+
"error"
|
|
608
|
+
]
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
"/pulsevault/capabilities": {
|
|
617
|
+
"get": {
|
|
618
|
+
"summary": "Discover this deployment's protocol version and configuration",
|
|
619
|
+
"tags": [
|
|
620
|
+
"pulsevault"
|
|
621
|
+
],
|
|
622
|
+
"description": "Unauthenticated — the response carries no secrets. Lets a client detect protocol compatibility, allowed artifact kinds/extensions and the upload size cap before pairing.",
|
|
623
|
+
"responses": {
|
|
624
|
+
"200": {
|
|
625
|
+
"description": "Unauthenticated discovery (PROTOCOL.md §2). A client reads it before pairing and pairs only if its protocol range overlaps [minSupportedVersion, maxSupportedVersion]. Clients must ignore fields they don't recognize.",
|
|
626
|
+
"content": {
|
|
627
|
+
"application/json": {
|
|
628
|
+
"schema": {
|
|
629
|
+
"title": "GET /capabilities response",
|
|
630
|
+
"description": "Unauthenticated discovery (PROTOCOL.md §2). A client reads it before pairing and pairs only if its protocol range overlaps [minSupportedVersion, maxSupportedVersion]. Clients must ignore fields they don't recognize.",
|
|
631
|
+
"type": "object",
|
|
632
|
+
"required": [
|
|
633
|
+
"protocolVersion",
|
|
634
|
+
"protocolRevision",
|
|
635
|
+
"minSupportedVersion",
|
|
636
|
+
"maxSupportedVersion",
|
|
637
|
+
"kinds",
|
|
638
|
+
"allowedExtensions",
|
|
639
|
+
"maxUploadSize",
|
|
640
|
+
"checksum"
|
|
641
|
+
],
|
|
642
|
+
"properties": {
|
|
643
|
+
"protocolVersion": {
|
|
644
|
+
"type": "integer",
|
|
645
|
+
"minimum": 1,
|
|
646
|
+
"description": "Protocol major this server implements. Also sent as the `Protocol-Version` header on every response."
|
|
647
|
+
},
|
|
648
|
+
"protocolRevision": {
|
|
649
|
+
"type": "string",
|
|
650
|
+
"pattern": "^[0-9]+\\.[0-9]+$",
|
|
651
|
+
"description": "Spec revision this server implements, `major.minor`. The minor counts additions older clients can ignore."
|
|
652
|
+
},
|
|
653
|
+
"minSupportedVersion": {
|
|
654
|
+
"type": "integer",
|
|
655
|
+
"minimum": 1,
|
|
656
|
+
"description": "Oldest protocol major this server accepts. Clients whose newest protocol is older get 426 Upgrade Required."
|
|
657
|
+
},
|
|
658
|
+
"maxSupportedVersion": {
|
|
659
|
+
"type": "integer",
|
|
660
|
+
"minimum": 1,
|
|
661
|
+
"description": "Newest protocol major this server accepts."
|
|
662
|
+
},
|
|
663
|
+
"kinds": {
|
|
664
|
+
"type": "array",
|
|
665
|
+
"items": {
|
|
666
|
+
"type": "string",
|
|
667
|
+
"enum": [
|
|
668
|
+
"video",
|
|
669
|
+
"project",
|
|
670
|
+
"captions",
|
|
671
|
+
"thumbnail"
|
|
672
|
+
]
|
|
673
|
+
},
|
|
674
|
+
"description": "Artifact kinds this server accepts."
|
|
675
|
+
},
|
|
676
|
+
"allowedExtensions": {
|
|
677
|
+
"type": "object",
|
|
678
|
+
"additionalProperties": {
|
|
679
|
+
"type": "array",
|
|
680
|
+
"items": {
|
|
681
|
+
"type": "string"
|
|
682
|
+
}
|
|
683
|
+
},
|
|
684
|
+
"description": "Allowed file extensions per kind, lowercase with the leading dot."
|
|
685
|
+
},
|
|
686
|
+
"maxUploadSize": {
|
|
687
|
+
"type": "number",
|
|
688
|
+
"description": "Largest artifact the server accepts, in bytes."
|
|
689
|
+
},
|
|
690
|
+
"checksum": {
|
|
691
|
+
"type": "object",
|
|
692
|
+
"required": [
|
|
693
|
+
"algorithms"
|
|
694
|
+
],
|
|
695
|
+
"properties": {
|
|
696
|
+
"algorithms": {
|
|
697
|
+
"type": "array",
|
|
698
|
+
"items": {
|
|
699
|
+
"type": "string"
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
"description": "Checksum algorithms accepted in `Upload-Metadata.checksum`."
|
|
704
|
+
},
|
|
705
|
+
"viewLinks": {
|
|
706
|
+
"type": "boolean",
|
|
707
|
+
"description": "Whether `POST {prefix}/artifacts/<id>/view-link` mints read-only view links (§6.4). Absent before protocol 2.2, which a client treats as false."
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
"/pulsevault/artifacts/{artifactId}": {
|
|
718
|
+
"delete": {
|
|
719
|
+
"summary": "Delete an uploaded artifact",
|
|
720
|
+
"tags": [
|
|
721
|
+
"pulsevault"
|
|
722
|
+
],
|
|
723
|
+
"description": "Deletes all storage for an artifactId (bytes + sidecar metadata), regardless of kind. Runs the `authorize` hook with `phase: \"delete\"` before the adapter's `remove` is called. Returns 204 on success, 404 if the artifactId was unknown, 501 if the adapter does not implement `remove`.",
|
|
724
|
+
"parameters": [
|
|
725
|
+
{
|
|
726
|
+
"schema": {
|
|
727
|
+
"type": "string",
|
|
728
|
+
"format": "uuid"
|
|
729
|
+
},
|
|
730
|
+
"in": "path",
|
|
731
|
+
"name": "artifactId",
|
|
732
|
+
"required": true,
|
|
733
|
+
"description": "UUID of the upload to delete."
|
|
734
|
+
}
|
|
735
|
+
],
|
|
736
|
+
"responses": {
|
|
737
|
+
"400": {
|
|
738
|
+
"description": "`artifactId` is not a valid UUID.",
|
|
739
|
+
"content": {
|
|
740
|
+
"application/json": {
|
|
741
|
+
"schema": {
|
|
742
|
+
"description": "`artifactId` is not a valid UUID.",
|
|
743
|
+
"type": "object",
|
|
744
|
+
"properties": {
|
|
745
|
+
"ok": {
|
|
746
|
+
"type": "boolean"
|
|
747
|
+
},
|
|
748
|
+
"error": {
|
|
749
|
+
"type": "string"
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
"required": [
|
|
753
|
+
"ok",
|
|
754
|
+
"error"
|
|
755
|
+
]
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
"403": {
|
|
761
|
+
"description": "Authorize hook rejected the request.",
|
|
762
|
+
"content": {
|
|
763
|
+
"application/json": {
|
|
764
|
+
"schema": {
|
|
765
|
+
"description": "Authorize hook rejected the request.",
|
|
766
|
+
"type": "object",
|
|
767
|
+
"properties": {
|
|
768
|
+
"ok": {
|
|
769
|
+
"type": "boolean"
|
|
770
|
+
},
|
|
771
|
+
"error": {
|
|
772
|
+
"type": "string"
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
"required": [
|
|
776
|
+
"ok",
|
|
777
|
+
"error"
|
|
778
|
+
]
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
},
|
|
783
|
+
"404": {
|
|
784
|
+
"description": "Artifact not found.",
|
|
785
|
+
"content": {
|
|
786
|
+
"application/json": {
|
|
787
|
+
"schema": {
|
|
788
|
+
"description": "Artifact not found.",
|
|
789
|
+
"type": "object",
|
|
790
|
+
"properties": {
|
|
791
|
+
"ok": {
|
|
792
|
+
"type": "boolean"
|
|
793
|
+
},
|
|
794
|
+
"error": {
|
|
795
|
+
"type": "string"
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
"required": [
|
|
799
|
+
"ok",
|
|
800
|
+
"error"
|
|
801
|
+
]
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
},
|
|
806
|
+
"501": {
|
|
807
|
+
"description": "Storage adapter does not implement delete.",
|
|
808
|
+
"content": {
|
|
809
|
+
"application/json": {
|
|
810
|
+
"schema": {
|
|
811
|
+
"description": "Storage adapter does not implement delete.",
|
|
812
|
+
"type": "object",
|
|
813
|
+
"properties": {
|
|
814
|
+
"ok": {
|
|
815
|
+
"type": "boolean"
|
|
816
|
+
},
|
|
817
|
+
"error": {
|
|
818
|
+
"type": "string"
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
"required": [
|
|
822
|
+
"ok",
|
|
823
|
+
"error"
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
},
|
|
831
|
+
"get": {
|
|
832
|
+
"summary": "Serve a previously uploaded artifact",
|
|
833
|
+
"tags": [
|
|
834
|
+
"pulsevault"
|
|
835
|
+
],
|
|
836
|
+
"description": "Resolves the `artifactId` through the configured storage adapter and either streams the bytes or redirects (for CDN-backed adapters). The artifact's kind (video, project, or captions) is resolved from storage, not the URL. Runs the `authorize` hook before resolve.",
|
|
837
|
+
"parameters": [
|
|
838
|
+
{
|
|
839
|
+
"schema": {
|
|
840
|
+
"type": "string"
|
|
841
|
+
},
|
|
842
|
+
"in": "query",
|
|
843
|
+
"name": "token",
|
|
844
|
+
"required": false,
|
|
845
|
+
"description": "Optional bearer token for pre-authenticated watch links. Forwarded to the `authorize` hook as `ctx.token` so parent servers can validate it without a separate login step."
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
"schema": {
|
|
849
|
+
"type": "string",
|
|
850
|
+
"format": "uuid"
|
|
851
|
+
},
|
|
852
|
+
"in": "path",
|
|
853
|
+
"name": "artifactId",
|
|
854
|
+
"required": true,
|
|
855
|
+
"description": "UUID returned from the upload flow."
|
|
856
|
+
}
|
|
857
|
+
],
|
|
858
|
+
"responses": {
|
|
859
|
+
"400": {
|
|
860
|
+
"description": "`artifactId` is not a valid UUID.",
|
|
861
|
+
"content": {
|
|
862
|
+
"application/json": {
|
|
863
|
+
"schema": {
|
|
864
|
+
"description": "`artifactId` is not a valid UUID.",
|
|
865
|
+
"type": "object",
|
|
866
|
+
"properties": {
|
|
867
|
+
"ok": {
|
|
868
|
+
"type": "boolean"
|
|
869
|
+
},
|
|
870
|
+
"error": {
|
|
871
|
+
"type": "string"
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
"required": [
|
|
875
|
+
"ok",
|
|
876
|
+
"error"
|
|
877
|
+
]
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
},
|
|
882
|
+
"403": {
|
|
883
|
+
"description": "Authorize hook rejected the request.",
|
|
884
|
+
"content": {
|
|
885
|
+
"application/json": {
|
|
886
|
+
"schema": {
|
|
887
|
+
"description": "Authorize hook rejected the request.",
|
|
888
|
+
"type": "object",
|
|
889
|
+
"properties": {
|
|
890
|
+
"ok": {
|
|
891
|
+
"type": "boolean"
|
|
892
|
+
},
|
|
893
|
+
"error": {
|
|
894
|
+
"type": "string"
|
|
895
|
+
}
|
|
896
|
+
},
|
|
897
|
+
"required": [
|
|
898
|
+
"ok",
|
|
899
|
+
"error"
|
|
900
|
+
]
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
"404": {
|
|
906
|
+
"description": "Artifact not found.",
|
|
907
|
+
"content": {
|
|
908
|
+
"application/json": {
|
|
909
|
+
"schema": {
|
|
910
|
+
"description": "Artifact not found.",
|
|
911
|
+
"type": "object",
|
|
912
|
+
"properties": {
|
|
913
|
+
"ok": {
|
|
914
|
+
"type": "boolean"
|
|
915
|
+
},
|
|
916
|
+
"error": {
|
|
917
|
+
"type": "string"
|
|
918
|
+
}
|
|
919
|
+
},
|
|
920
|
+
"required": [
|
|
921
|
+
"ok",
|
|
922
|
+
"error"
|
|
923
|
+
]
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
"/pulsevault/artifacts/{artifactId}/view-link": {
|
|
932
|
+
"post": {
|
|
933
|
+
"summary": "Mint a read-only view link for a finished artifact",
|
|
934
|
+
"tags": [
|
|
935
|
+
"pulsevault"
|
|
936
|
+
],
|
|
937
|
+
"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.",
|
|
938
|
+
"parameters": [
|
|
939
|
+
{
|
|
940
|
+
"schema": {
|
|
941
|
+
"type": "string",
|
|
942
|
+
"format": "uuid"
|
|
943
|
+
},
|
|
944
|
+
"in": "path",
|
|
945
|
+
"name": "artifactId",
|
|
946
|
+
"required": true,
|
|
947
|
+
"description": "UUID of the finished artifact to link to."
|
|
948
|
+
}
|
|
949
|
+
],
|
|
950
|
+
"responses": {
|
|
951
|
+
"200": {
|
|
952
|
+
"description": "A read-only view link to a finished artifact (PROTOCOL.md §6.4, protocol 2.2). The token opens the artifact, and the artifacts `relatedTo` it, as `GET {prefix}/artifacts/<id>?token=<token>` — nothing more, so it is safe to share. The server decides how long it works.",
|
|
953
|
+
"content": {
|
|
954
|
+
"application/json": {
|
|
955
|
+
"schema": {
|
|
956
|
+
"title": "POST /artifacts/<id>/view-link response",
|
|
957
|
+
"description": "A read-only view link to a finished artifact (PROTOCOL.md §6.4, protocol 2.2). The token opens the artifact, and the artifacts `relatedTo` it, as `GET {prefix}/artifacts/<id>?token=<token>` — nothing more, so it is safe to share. The server decides how long it works.",
|
|
958
|
+
"type": "object",
|
|
959
|
+
"required": [
|
|
960
|
+
"token",
|
|
961
|
+
"expiresAt"
|
|
962
|
+
],
|
|
963
|
+
"additionalProperties": false,
|
|
964
|
+
"properties": {
|
|
965
|
+
"token": {
|
|
966
|
+
"type": "string",
|
|
967
|
+
"minLength": 1,
|
|
968
|
+
"description": "The view token. Opaque to clients."
|
|
969
|
+
},
|
|
970
|
+
"expiresAt": {
|
|
971
|
+
"type": "integer",
|
|
972
|
+
"description": "When the link stops working, in seconds since the Unix epoch."
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
},
|
|
979
|
+
"400": {
|
|
980
|
+
"description": "`artifactId` is not a valid UUID.",
|
|
981
|
+
"content": {
|
|
982
|
+
"application/json": {
|
|
983
|
+
"schema": {
|
|
984
|
+
"description": "`artifactId` is not a valid UUID.",
|
|
985
|
+
"type": "object",
|
|
986
|
+
"properties": {
|
|
987
|
+
"ok": {
|
|
988
|
+
"type": "boolean"
|
|
989
|
+
},
|
|
990
|
+
"error": {
|
|
991
|
+
"type": "string"
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
"required": [
|
|
995
|
+
"ok",
|
|
996
|
+
"error"
|
|
997
|
+
]
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
},
|
|
1002
|
+
"403": {
|
|
1003
|
+
"description": "Authorize hook rejected the request, or the host refused a link for this artifact.",
|
|
1004
|
+
"content": {
|
|
1005
|
+
"application/json": {
|
|
1006
|
+
"schema": {
|
|
1007
|
+
"description": "Authorize hook rejected the request, or the host refused a link for this artifact.",
|
|
1008
|
+
"type": "object",
|
|
1009
|
+
"properties": {
|
|
1010
|
+
"ok": {
|
|
1011
|
+
"type": "boolean"
|
|
1012
|
+
},
|
|
1013
|
+
"error": {
|
|
1014
|
+
"type": "string"
|
|
1015
|
+
}
|
|
1016
|
+
},
|
|
1017
|
+
"required": [
|
|
1018
|
+
"ok",
|
|
1019
|
+
"error"
|
|
1020
|
+
]
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
1025
|
+
"404": {
|
|
1026
|
+
"description": "View links are not enabled, or the artifact is not found or not finished.",
|
|
1027
|
+
"content": {
|
|
1028
|
+
"application/json": {
|
|
1029
|
+
"schema": {
|
|
1030
|
+
"description": "View links are not enabled, or the artifact is not found or not finished.",
|
|
1031
|
+
"type": "object",
|
|
1032
|
+
"properties": {
|
|
1033
|
+
"ok": {
|
|
1034
|
+
"type": "boolean"
|
|
1035
|
+
},
|
|
1036
|
+
"error": {
|
|
1037
|
+
"type": "string"
|
|
1038
|
+
}
|
|
1039
|
+
},
|
|
1040
|
+
"required": [
|
|
1041
|
+
"ok",
|
|
1042
|
+
"error"
|
|
1043
|
+
]
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
},
|
|
1052
|
+
"tags": [
|
|
1053
|
+
{
|
|
1054
|
+
"name": "pulsevault",
|
|
1055
|
+
"description": "Routes mounted by the plugin"
|
|
1056
|
+
}
|
|
1057
|
+
]
|
|
1058
|
+
}
|