@atproto/pds 0.5.26 → 0.5.28
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 +34 -0
- package/dist/actor-store/blob/transactor.d.ts +1 -5
- package/dist/actor-store/blob/transactor.d.ts.map +1 -1
- package/dist/actor-store/blob/transactor.js +72 -43
- package/dist/actor-store/blob/transactor.js.map +1 -1
- package/dist/api/com/atproto/repo/uploadBlob.d.ts.map +1 -1
- package/dist/api/com/atproto/repo/uploadBlob.js +1 -1
- package/dist/api/com/atproto/repo/uploadBlob.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts +3 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts +66 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js +26 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js +6 -0
- package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js.map +1 -0
- package/dist/lexicons/app/bsky/actor.d.ts +1 -0
- package/dist/lexicons/app/bsky/actor.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor.js +1 -0
- package/dist/lexicons/app/bsky/actor.js.map +1 -1
- package/dist/lexicons/app/bsky/authCreatePosts.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/authCreatePosts.defs.js +5 -0
- package/dist/lexicons/app/bsky/authCreatePosts.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.js +5 -0
- package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.js +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/video/abortUpload.d.ts +3 -0
- package/dist/lexicons/app/bsky/video/abortUpload.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts +53 -0
- package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/abortUpload.defs.js +26 -0
- package/dist/lexicons/app/bsky/video/abortUpload.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/video/abortUpload.js +6 -0
- package/dist/lexicons/app/bsky/video/abortUpload.js.map +1 -0
- package/dist/lexicons/app/bsky/video/defs.defs.d.ts +1 -1
- package/dist/lexicons/app/bsky/video/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/video/defs.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/video/finishUpload.d.ts +3 -0
- package/dist/lexicons/app/bsky/video/finishUpload.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts +42 -0
- package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/finishUpload.defs.js +30 -0
- package/dist/lexicons/app/bsky/video/finishUpload.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/video/finishUpload.js +6 -0
- package/dist/lexicons/app/bsky/video/finishUpload.js.map +1 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts +3 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts +73 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js +30 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.js +6 -0
- package/dist/lexicons/app/bsky/video/getUploadStatus.js.map +1 -0
- package/dist/lexicons/app/bsky/video/startUpload.d.ts +3 -0
- package/dist/lexicons/app/bsky/video/startUpload.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts +63 -0
- package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/startUpload.defs.js +36 -0
- package/dist/lexicons/app/bsky/video/startUpload.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/video/startUpload.js +6 -0
- package/dist/lexicons/app/bsky/video/startUpload.js.map +1 -0
- package/dist/lexicons/app/bsky/video/uploadPart.d.ts +3 -0
- package/dist/lexicons/app/bsky/video/uploadPart.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts +37 -0
- package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/video/uploadPart.defs.js +31 -0
- package/dist/lexicons/app/bsky/video/uploadPart.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/video/uploadPart.js +6 -0
- package/dist/lexicons/app/bsky/video/uploadPart.js.map +1 -0
- package/dist/lexicons/app/bsky/video.d.ts +5 -0
- package/dist/lexicons/app/bsky/video.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/video.js +5 -0
- package/dist/lexicons/app/bsky/video.js.map +1 -1
- package/dist/mailer/templates/confirm-email.js +44 -1198
- package/dist/mailer/templates/confirm-email.js.map +1 -7
- package/dist/mailer/templates/delete-account.js +25 -1190
- package/dist/mailer/templates/delete-account.js.map +1 -7
- package/dist/mailer/templates/plc-operation.js +25 -1190
- package/dist/mailer/templates/plc-operation.js.map +1 -7
- package/dist/mailer/templates/reset-password.js +33 -1190
- package/dist/mailer/templates/reset-password.js.map +1 -7
- package/dist/mailer/templates/update-email.js +25 -1190
- package/dist/mailer/templates/update-email.js.map +1 -7
- package/package.json +20 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @atproto/pds
|
|
2
2
|
|
|
3
|
+
## 0.5.28
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#5382](https://github.com/bluesky-social/atproto/pull/5382) [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Update `file-type` dependency
|
|
8
|
+
|
|
9
|
+
- [#5371](https://github.com/bluesky-social/atproto/pull/5371) [`c7f39c5`](https://github.com/bluesky-social/atproto/commit/c7f39c527758ffd5b21b896fac494ecf7e69aa37) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Remove "esbuild" dependency
|
|
10
|
+
|
|
11
|
+
- [#5382](https://github.com/bluesky-social/atproto/pull/5382) [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Propagate back-pressure when uploading blobs (avoiding high memory pressure)
|
|
12
|
+
|
|
13
|
+
- [#5382](https://github.com/bluesky-social/atproto/pull/5382) [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Remove unused `CidNotFound` error class
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`898c469`](https://github.com/bluesky-social/atproto/commit/898c469cf568b941f38f9c3371997a513ac05cfa), [`4e18a00`](https://github.com/bluesky-social/atproto/commit/4e18a00b2de97e36b9b00a7fcb8713efd87964d1)]:
|
|
16
|
+
- @atproto/common@0.8.0
|
|
17
|
+
- @atproto/oauth-provider@0.22.2
|
|
18
|
+
- @atproto/aws@0.3.13
|
|
19
|
+
- @atproto/repo@0.10.11
|
|
20
|
+
- @atproto/xrpc-server@0.12.4
|
|
21
|
+
- @atproto-labs/xrpc-utils@0.1.17
|
|
22
|
+
- @atproto/lex@0.3.6
|
|
23
|
+
|
|
24
|
+
## 0.5.27
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- [#5360](https://github.com/bluesky-social/atproto/pull/5360) [`098cdd7`](https://github.com/bluesky-social/atproto/commit/098cdd7dcf11fc0421278dd768f286ee80399e4f) Thanks [@blackmichael](https://github.com/blackmichael)! - Prevent blob uploads from stalling when MIME detection finishes before the other request-stream consumers.
|
|
29
|
+
|
|
30
|
+
- [#5359](https://github.com/bluesky-social/atproto/pull/5359) [`aadb103`](https://github.com/bluesky-social/atproto/commit/aadb10349497d7c6b6ce5641dbbb1fd940dd5b12) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Remove timing races from WebSocket, background indexing, firehose, and Ozone materialized-view tests.
|
|
31
|
+
|
|
32
|
+
- Updated dependencies []:
|
|
33
|
+
- @atproto/oauth-provider@0.22.1
|
|
34
|
+
- @atproto/xrpc-server@0.12.3
|
|
35
|
+
- @atproto-labs/xrpc-utils@0.1.16
|
|
36
|
+
|
|
3
37
|
## 0.5.26
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
|
@@ -19,7 +19,7 @@ export declare class BlobTransactor extends BlobReader {
|
|
|
19
19
|
backgroundQueue: BackgroundQueue;
|
|
20
20
|
constructor(db: ActorDb, blobstore: BlobStore, backgroundQueue: BackgroundQueue);
|
|
21
21
|
insertBlobs(recordUri: string, blobs: Iterable<BlobRef>): Promise<void>;
|
|
22
|
-
uploadBlobAndGetMetadata(
|
|
22
|
+
uploadBlobAndGetMetadata(blobStream: stream.Readable, fallbackMime?: `${string}/${string}`, maxSize?: number): Promise<BlobMetadata>;
|
|
23
23
|
trackUntetheredBlob(metadata: BlobMetadata): Promise<TypedBlobRef>;
|
|
24
24
|
processWriteBlobs(rev: string, writes: PreparedWrite[]): Promise<void>;
|
|
25
25
|
updateBlobTakedownStatus(cid: Cid, takedown: com.atproto.admin.defs.StatusAttr): Promise<void>;
|
|
@@ -28,8 +28,4 @@ export declare class BlobTransactor extends BlobReader {
|
|
|
28
28
|
insertBlobMetadata(blob: TypedBlobRef): Promise<void>;
|
|
29
29
|
associateBlob(blob: TypedBlobRef, recordUri: AtUri): Promise<void>;
|
|
30
30
|
}
|
|
31
|
-
export declare class CidNotFound extends Error {
|
|
32
|
-
cid: Cid;
|
|
33
|
-
constructor(cid: Cid);
|
|
34
|
-
}
|
|
35
31
|
//# sourceMappingURL=transactor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactor.d.ts","sourceRoot":"","sources":["../../../src/actor-store/blob/transactor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"transactor.d.ts","sourceRoot":"","sources":["../../../src/actor-store/blob/transactor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAerC,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,YAAY,EAIlB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAqB,KAAK,SAAS,EAAiB,MAAM,eAAe,CAAA;AAChF,OAAO,EAAE,KAAK,KAAK,EAAyB,MAAM,iBAAiB,CAAA;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,gBAAgB,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,GAAG,CAAA;IACR,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,qBAAa,cAAe,SAAQ,UAAU;IAEnC,EAAE,EAAE,OAAO;IACX,SAAS,EAAE,SAAS;IACpB,eAAe,EAAE,eAAe;IAHzC,YACS,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,eAAe,EAGxC;IAEK,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,iBAa5D;IAEK,wBAAwB,CAC5B,UAAU,EAAE,MAAM,CAAC,QAAQ,EAC3B,YAAY,GAAE,GAAG,MAAM,IAAI,MAAM,EAA+B,EAChE,OAAO,SAAW,GACjB,OAAO,CAAC,YAAY,CAAC,CAoCvB;IAEK,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAoCvE;IAEK,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,iBAqC3D;IAEK,wBAAwB,CAC5B,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,iBA8B5C;IAEK,uBAAuB,CAC3B,MAAM,EAAE,aAAa,EAAE,EACvB,aAAa,CAAC,EAAE,OAAO,iBAuDxB;IAEK,0BAA0B,CAC9B,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Cf;IAEK,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1D;IAEK,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CASvE;CACF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
const { fromStream: fileTypeFromStream } = FileType;
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { PassThrough, pipeline, } from 'node:stream';
|
|
3
|
+
import { FileTypeParser, } from 'file-type';
|
|
5
4
|
import PQueue from 'p-queue';
|
|
6
|
-
import {
|
|
5
|
+
import { fromStream } from 'strtok3';
|
|
6
|
+
import { HashPassThrough, MaxSizeChecker, SECOND, Tee } from '@atproto/common';
|
|
7
7
|
import { cidForRawHash, getBlobCidString, parseCid, } from '@atproto/lex-data';
|
|
8
8
|
import { BlobNotFoundError, WriteOpAction } from '@atproto/repo';
|
|
9
9
|
import { currentDatetimeString } from '@atproto/syntax';
|
|
@@ -30,19 +30,35 @@ export class BlobTransactor extends BlobReader {
|
|
|
30
30
|
.execute();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
async uploadBlobAndGetMetadata(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
33
|
+
async uploadBlobAndGetMetadata(blobStream, fallbackMime = 'application/octet-stream', maxSize = Infinity) {
|
|
34
|
+
try {
|
|
35
|
+
const hashDuplex = new HashPassThrough('sha256');
|
|
36
|
+
const sizeDuplex = new MaxSizeChecker(maxSize);
|
|
37
|
+
const typeDuplex = new FileTypePassThrough();
|
|
38
|
+
// @NOTE a pipeline of duplex streams is used to ensure that backpressure
|
|
39
|
+
// is properly propagated to the input stream. using inputStream.pipe()
|
|
40
|
+
// with several destinations does **not** propagate backpressure, and
|
|
41
|
+
// **will** high memory consumption (hash and size duplexes consume the
|
|
42
|
+
// stream faster than the blobstore can process it).
|
|
43
|
+
const streams = [blobStream, hashDuplex, sizeDuplex, typeDuplex];
|
|
44
|
+
const blobStoreStream = pipeline(streams, (_err) => {
|
|
45
|
+
// errors will be propagated to the streams, and handled (rethrown) by
|
|
46
|
+
// the blobStore.
|
|
47
|
+
}); // pipeline() returns the last stream
|
|
48
|
+
// Start the pipeline by reading its output
|
|
49
|
+
const tempKey = await this.blobstore.putTemp(blobStoreStream);
|
|
50
|
+
// Fool-proof against faulty blobstore implementations
|
|
51
|
+
assert(streams.every((s) => s.readableEnded), 'blobstore did not fully consume the stream');
|
|
52
|
+
return {
|
|
53
|
+
tempKey,
|
|
54
|
+
size: sizeDuplex.totalSize,
|
|
55
|
+
cid: cidForRawHash(hashDuplex.digest),
|
|
56
|
+
mimeType: typeDuplex.fileTypeResult?.mime || fallbackMime,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
blobStream.destroy();
|
|
61
|
+
}
|
|
46
62
|
}
|
|
47
63
|
async trackUntetheredBlob(metadata) {
|
|
48
64
|
const { tempKey, size, cid, mimeType } = metadata;
|
|
@@ -238,34 +254,47 @@ export class BlobTransactor extends BlobReader {
|
|
|
238
254
|
.execute();
|
|
239
255
|
}
|
|
240
256
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
try {
|
|
250
|
-
for await (const chunk of toHash) {
|
|
251
|
-
hash.write(chunk);
|
|
252
|
-
}
|
|
257
|
+
// "file-type" does not provide a duplex implementation so we create one here
|
|
258
|
+
class FileTypePassThrough extends Tee {
|
|
259
|
+
#fileTypeResult;
|
|
260
|
+
get fileTypeResult() {
|
|
261
|
+
const result = this.#fileTypeResult;
|
|
262
|
+
if (result)
|
|
263
|
+
return result.status === 'fulfilled' ? result.value : undefined;
|
|
264
|
+
throw new Error('FileTypePassThrough result is not yet available');
|
|
253
265
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
266
|
+
constructor(options) {
|
|
267
|
+
const branch = new PassThrough();
|
|
268
|
+
super(branch);
|
|
269
|
+
const parser = new FileTypeParser(options);
|
|
270
|
+
// @NOTE file-type does not support NodeJS Readable and recommends wrapping
|
|
271
|
+
// into a web steam. We use strtok3 to convert the NodeJS Readable into a
|
|
272
|
+
// tokenizer, bypassing that limitation.
|
|
273
|
+
this.fileTypePromise = fromStream(branch)
|
|
274
|
+
.then((tokenizer) => parser.fromTokenizer(tokenizer))
|
|
275
|
+
// file-type won't destroy() the stream. We need to destroy to allow
|
|
276
|
+
// the Tee's main stream to flow freely.
|
|
277
|
+
.finally(() => branch.destroy());
|
|
278
|
+
// avoids unhandled rejections (might be awaited later)
|
|
279
|
+
this.fileTypePromise.then((value) => {
|
|
280
|
+
this.#fileTypeResult = { status: 'fulfilled', value };
|
|
281
|
+
}, (reason) => {
|
|
282
|
+
this.#fileTypeResult = { status: 'rejected', reason };
|
|
283
|
+
});
|
|
257
284
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return fileType?.mime;
|
|
285
|
+
_final(cb) {
|
|
286
|
+
// propagate the result promise to the final callback, so that the stream is
|
|
287
|
+
// not considered finished until the file type has been determined.
|
|
288
|
+
super._final((err) => {
|
|
289
|
+
this.fileTypePromise.then(() => cb(err), () => cb(err));
|
|
290
|
+
});
|
|
265
291
|
}
|
|
266
|
-
|
|
267
|
-
//
|
|
268
|
-
|
|
292
|
+
_destroy(err, cb) {
|
|
293
|
+
// propagate the result promise to the destroy callback, so that the stream
|
|
294
|
+
// is not considered finished until the file type has been determined.
|
|
295
|
+
super._destroy(err, (err) => {
|
|
296
|
+
this.fileTypePromise.then(() => cb(err), () => cb(err));
|
|
297
|
+
});
|
|
269
298
|
}
|
|
270
299
|
}
|
|
271
300
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactor.js","sourceRoot":"","sources":["../../../src/actor-store/blob/transactor.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'node:crypto'\nimport type stream from 'node:stream'\nimport * as FileTypeModule from 'file-type'\nconst FileType = ((m) => m.default ?? m)(FileTypeModule)\nconst { fromStream: fileTypeFromStream } = FileType\nimport PQueue from 'p-queue'\nimport { SECOND, cloneStream, streamSize } from '@atproto/common'\nimport {\n type BlobRef,\n type Cid,\n type TypedBlobRef,\n cidForRawHash,\n getBlobCidString,\n parseCid,\n} from '@atproto/lex-data'\nimport { BlobNotFoundError, type BlobStore, WriteOpAction } from '@atproto/repo'\nimport { type AtUri, currentDatetimeString } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport type { BackgroundQueue } from '../../background.js'\nimport type { com } from '../../lexicons/index.js'\nimport { blobStoreLogger as log } from '../../logger.js'\nimport type { PreparedWrite } from '../../repo/types.js'\nimport type { ActorDb, Blob as BlobTable } from '../db/index.js'\nimport { BlobReader } from './reader.js'\n\nexport type BlobMetadata = {\n tempKey: string\n size: number\n cid: Cid\n mimeType: string\n}\n\nexport class BlobTransactor extends BlobReader {\n constructor(\n public db: ActorDb,\n public blobstore: BlobStore,\n public backgroundQueue: BackgroundQueue,\n ) {\n super(db, blobstore)\n }\n\n async insertBlobs(recordUri: string, blobs: Iterable<BlobRef>) {\n const values = Array.from(blobs, (blob) => ({\n recordUri,\n blobCid: getBlobCidString(blob),\n }))\n\n if (values.length) {\n await this.db.db\n .insertInto('record_blob')\n .values(values)\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n }\n\n async uploadBlobAndGetMetadata(\n userSuggestedMime: string,\n blobStream: stream.Readable,\n ): Promise<BlobMetadata> {\n const [tempKey, size, sha256, sniffedMime] = await Promise.all([\n this.blobstore.putTemp(cloneStream(blobStream)),\n streamSize(cloneStream(blobStream)),\n sha256Stream(cloneStream(blobStream)),\n mimeTypeFromStream(cloneStream(blobStream)),\n ])\n\n return {\n tempKey,\n size,\n cid: cidForRawHash(sha256),\n mimeType: sniffedMime || userSuggestedMime,\n }\n }\n\n async trackUntetheredBlob(metadata: BlobMetadata): Promise<TypedBlobRef> {\n const { tempKey, size, cid, mimeType } = metadata\n const cidStr = cid.toString()\n\n const found = await this.db.db\n .selectFrom('blob')\n .selectAll()\n .where('cid', '=', cidStr)\n .executeTakeFirst()\n if (found?.takedownRef) {\n throw new InvalidRequestError('Blob has been takendown, cannot re-upload')\n }\n\n await this.db.db\n .insertInto('blob')\n .values({\n cid: cidStr,\n mimeType,\n size,\n tempKey,\n createdAt: currentDatetimeString(),\n })\n .onConflict((oc) =>\n oc\n .column('cid')\n .doUpdateSet({ tempKey })\n .where('blob.tempKey', 'is not', null),\n )\n .execute()\n\n return {\n $type: 'blob',\n ref: cid,\n mimeType,\n size,\n }\n }\n\n async processWriteBlobs(rev: string, writes: PreparedWrite[]) {\n await this.deleteDereferencedBlobs(writes)\n\n const ac = new AbortController()\n\n // Limit the number of parallel requests made to the BlobStore by using a\n // a queue with concurrency management.\n type Task = () => Promise<void>\n const tasks: Task[] = []\n\n for (const write of writes) {\n if (isCreate(write) || isUpdate(write)) {\n for (const blob of write.blobs) {\n tasks.push(async () => {\n if (ac.signal.aborted) return\n await this.associateBlob(blob, write.uri)\n await this.verifyBlobAndMakePermanent(blob, ac.signal)\n })\n }\n }\n }\n\n try {\n const queue = new PQueue({\n concurrency: 20,\n // The blob store should already limit the time of every operation. We\n // add a timeout here as an extra precaution.\n timeout: 60 * SECOND,\n throwOnTimeout: true,\n })\n\n // Will reject as soon as any task fails, causing the \"finally\" block\n // below to run, aborting every other pending tasks.\n await queue.addAll(tasks)\n } finally {\n ac.abort()\n }\n }\n\n async updateBlobTakedownStatus(\n cid: Cid,\n takedown: com.atproto.admin.defs.StatusAttr,\n ) {\n const takedownRef = takedown.applied\n ? (takedown.ref ?? currentDatetimeString())\n : null\n await this.db.db\n .updateTable('blob')\n .set({ takedownRef })\n .where('cid', '=', cid.toString())\n .executeTakeFirst()\n\n try {\n // @NOTE find a way to not perform i/o operations during the transaction\n // (typically by using a state in the \"blob\" table, and another process to\n // handle the actual i/o)\n if (takedown.applied) {\n await this.blobstore.quarantine(cid)\n } else {\n await this.blobstore.unquarantine(cid)\n }\n } catch (err) {\n if (!(err instanceof BlobNotFoundError)) {\n log.error(\n { err, cid: cid.toString() },\n 'could not update blob takedown status',\n )\n\n throw err\n }\n }\n }\n\n async deleteDereferencedBlobs(\n writes: PreparedWrite[],\n skipBlobStore?: boolean,\n ) {\n const deletes = writes.filter(isDelete)\n const updates = writes.filter(isUpdate)\n const uris = [...deletes, ...updates].map((w) => w.uri.toString())\n if (uris.length === 0) return\n\n const deletedRepoBlobs = await this.db.db\n .deleteFrom('record_blob')\n .where('recordUri', 'in', uris)\n .returning('blobCid')\n .execute()\n if (deletedRepoBlobs.length === 0) return\n\n const deletedRepoBlobCids = deletedRepoBlobs.map((row) => row.blobCid)\n const duplicateCids = await this.db.db\n .selectFrom('record_blob')\n .where('blobCid', 'in', deletedRepoBlobCids)\n .select('blobCid')\n .execute()\n\n const newBlobCids = writes\n .filter((w) => isUpdate(w) || isCreate(w))\n .flatMap((w) => w.blobs.map((b) => b.ref.toString()))\n\n const cidsToKeep = [\n ...newBlobCids,\n ...duplicateCids.map((row) => row.blobCid),\n ]\n\n const cidsToDelete = deletedRepoBlobCids.filter(\n (cid) => !cidsToKeep.includes(cid),\n )\n if (cidsToDelete.length === 0) return\n\n await this.db.db\n .deleteFrom('blob')\n .where('cid', 'in', cidsToDelete)\n .execute()\n\n if (!skipBlobStore) {\n this.db.onCommit(() => {\n this.backgroundQueue.add(async () => {\n try {\n const cids = cidsToDelete.map((cid) => parseCid(cid))\n await this.blobstore.deleteMany(cids)\n } catch (err) {\n log.error(\n { err, cids: cidsToDelete },\n 'could not delete blobs from blobstore',\n )\n }\n })\n })\n }\n }\n\n async verifyBlobAndMakePermanent(\n blob: TypedBlobRef,\n signal?: AbortSignal,\n ): Promise<void> {\n const found = await this.db.db\n .selectFrom('blob')\n .select(['tempKey', 'size', 'mimeType'])\n .where('cid', '=', blob.ref.toString())\n .where('takedownRef', 'is', null)\n .executeTakeFirst()\n\n signal?.throwIfAborted()\n\n if (!found) {\n throw new InvalidRequestError(\n `Could not find blob: ${blob.ref.toString()}`,\n 'BlobNotFound',\n )\n }\n\n if (found.tempKey) {\n verifyBlob(blob, found)\n\n // @NOTE it is less than ideal to perform async (i/o) operations during a\n // transaction. Especially since there have been instances of the actor-db\n // being locked, requiring to kick the processes.\n\n // The better solution would be to update the blob state in the database\n // (e.g. \"makeItPermanent\") and to process those updates outside of the\n // transaction.\n\n await this.blobstore\n .makePermanent(found.tempKey, blob.ref)\n .catch((err) => {\n log.error(\n { err, cid: blob.ref.toString() },\n 'could not make blob permanent',\n )\n\n throw err\n })\n\n signal?.throwIfAborted()\n\n await this.db.db\n .updateTable('blob')\n .set({ tempKey: null })\n .where('tempKey', '=', found.tempKey)\n .execute()\n }\n }\n\n async insertBlobMetadata(blob: TypedBlobRef): Promise<void> {\n await this.db.db\n .insertInto('blob')\n .values({\n cid: blob.ref.toString(),\n mimeType: blob.mimeType,\n size: blob.size,\n createdAt: currentDatetimeString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n\n async associateBlob(blob: TypedBlobRef, recordUri: AtUri): Promise<void> {\n await this.db.db\n .insertInto('record_blob')\n .values({\n blobCid: blob.ref.toString(),\n recordUri: recordUri.toString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n}\n\nexport class CidNotFound extends Error {\n cid: Cid\n constructor(cid: Cid) {\n super(`cid not found: ${cid.toString()}`)\n this.cid = cid\n }\n}\n\nasync function sha256Stream(toHash: stream.Readable): Promise<Uint8Array> {\n const hash = crypto.createHash('sha256')\n try {\n for await (const chunk of toHash) {\n hash.write(chunk)\n }\n } catch (err) {\n hash.end()\n throw err\n }\n hash.end()\n return hash.read()\n}\n\nasync function mimeTypeFromStream(\n blobStream: stream.Readable,\n): Promise<string | undefined> {\n try {\n const fileType = await fileTypeFromStream(blobStream)\n return fileType?.mime\n } finally {\n // @NOTE Should not be needed\n blobStream.destroy()\n }\n}\n\n/**\n * Ensures that the blob referenced in the record matches the stored blob.\n */\nfunction verifyBlob(\n blob: TypedBlobRef,\n found: Pick<BlobTable, 'size' | 'mimeType'>,\n) {\n if (blob.mimeType !== found.mimeType) {\n throw new InvalidRequestError(\n `Referenced Mimetype does not match stored blob. Expected: ${found.mimeType}, Got: ${blob.mimeType}`,\n 'InvalidMimeType',\n )\n }\n\n if (blob.size !== found.size) {\n throw new InvalidRequestError(\n `Referenced Size does not match stored blob. Expected: ${found.size}, Got: ${blob.size}`,\n 'InvalidSize',\n )\n }\n}\n\nfunction isCreate(write: PreparedWrite) {\n return write.action === WriteOpAction.Create\n}\nfunction isUpdate(write: PreparedWrite) {\n return write.action === WriteOpAction.Update\n}\nfunction isDelete(write: PreparedWrite) {\n return write.action === WriteOpAction.Delete\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transactor.js","sourceRoot":"","sources":["../../../src/actor-store/blob/transactor.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport type stream from 'node:stream'\nimport {\n type Duplex,\n PassThrough,\n type TransformCallback,\n pipeline,\n} from 'node:stream'\nimport {\n type FileTypeOptions,\n FileTypeParser,\n type FileTypeResult,\n} from 'file-type'\nimport PQueue from 'p-queue'\nimport { fromStream } from 'strtok3'\nimport { HashPassThrough, MaxSizeChecker, SECOND, Tee } from '@atproto/common'\nimport {\n type BlobRef,\n type Cid,\n type TypedBlobRef,\n cidForRawHash,\n getBlobCidString,\n parseCid,\n} from '@atproto/lex-data'\nimport { BlobNotFoundError, type BlobStore, WriteOpAction } from '@atproto/repo'\nimport { type AtUri, currentDatetimeString } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport type { BackgroundQueue } from '../../background.js'\nimport type { com } from '../../lexicons/index.js'\nimport { blobStoreLogger as log } from '../../logger.js'\nimport type { PreparedWrite } from '../../repo/types.js'\nimport type { ActorDb, Blob as BlobTable } from '../db/index.js'\nimport { BlobReader } from './reader.js'\n\nexport type BlobMetadata = {\n tempKey: string\n size: number\n cid: Cid\n mimeType: string\n}\n\nexport class BlobTransactor extends BlobReader {\n constructor(\n public db: ActorDb,\n public blobstore: BlobStore,\n public backgroundQueue: BackgroundQueue,\n ) {\n super(db, blobstore)\n }\n\n async insertBlobs(recordUri: string, blobs: Iterable<BlobRef>) {\n const values = Array.from(blobs, (blob) => ({\n recordUri,\n blobCid: getBlobCidString(blob),\n }))\n\n if (values.length) {\n await this.db.db\n .insertInto('record_blob')\n .values(values)\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n }\n\n async uploadBlobAndGetMetadata(\n blobStream: stream.Readable,\n fallbackMime: `${string}/${string}` = 'application/octet-stream',\n maxSize = Infinity,\n ): Promise<BlobMetadata> {\n try {\n const hashDuplex = new HashPassThrough('sha256')\n const sizeDuplex = new MaxSizeChecker(maxSize)\n const typeDuplex = new FileTypePassThrough()\n\n // @NOTE a pipeline of duplex streams is used to ensure that backpressure\n // is properly propagated to the input stream. using inputStream.pipe()\n // with several destinations does **not** propagate backpressure, and\n // **will** high memory consumption (hash and size duplexes consume the\n // stream faster than the blobstore can process it).\n const streams = [blobStream, hashDuplex, sizeDuplex, typeDuplex]\n\n const blobStoreStream = pipeline(streams, (_err) => {\n // errors will be propagated to the streams, and handled (rethrown) by\n // the blobStore.\n }) as Duplex // pipeline() returns the last stream\n\n // Start the pipeline by reading its output\n const tempKey = await this.blobstore.putTemp(blobStoreStream)\n\n // Fool-proof against faulty blobstore implementations\n assert(\n streams.every((s) => s.readableEnded),\n 'blobstore did not fully consume the stream',\n )\n\n return {\n tempKey,\n size: sizeDuplex.totalSize,\n cid: cidForRawHash(hashDuplex.digest),\n mimeType: typeDuplex.fileTypeResult?.mime || fallbackMime,\n }\n } finally {\n blobStream.destroy()\n }\n }\n\n async trackUntetheredBlob(metadata: BlobMetadata): Promise<TypedBlobRef> {\n const { tempKey, size, cid, mimeType } = metadata\n const cidStr = cid.toString()\n\n const found = await this.db.db\n .selectFrom('blob')\n .selectAll()\n .where('cid', '=', cidStr)\n .executeTakeFirst()\n if (found?.takedownRef) {\n throw new InvalidRequestError('Blob has been takendown, cannot re-upload')\n }\n\n await this.db.db\n .insertInto('blob')\n .values({\n cid: cidStr,\n mimeType,\n size,\n tempKey,\n createdAt: currentDatetimeString(),\n })\n .onConflict((oc) =>\n oc\n .column('cid')\n .doUpdateSet({ tempKey })\n .where('blob.tempKey', 'is not', null),\n )\n .execute()\n\n return {\n $type: 'blob',\n ref: cid,\n mimeType,\n size,\n }\n }\n\n async processWriteBlobs(rev: string, writes: PreparedWrite[]) {\n await this.deleteDereferencedBlobs(writes)\n\n const ac = new AbortController()\n\n // Limit the number of parallel requests made to the BlobStore by using a\n // a queue with concurrency management.\n type Task = () => Promise<void>\n const tasks: Task[] = []\n\n for (const write of writes) {\n if (isCreate(write) || isUpdate(write)) {\n for (const blob of write.blobs) {\n tasks.push(async () => {\n if (ac.signal.aborted) return\n await this.associateBlob(blob, write.uri)\n await this.verifyBlobAndMakePermanent(blob, ac.signal)\n })\n }\n }\n }\n\n try {\n const queue = new PQueue({\n concurrency: 20,\n // The blob store should already limit the time of every operation. We\n // add a timeout here as an extra precaution.\n timeout: 60 * SECOND,\n throwOnTimeout: true,\n })\n\n // Will reject as soon as any task fails, causing the \"finally\" block\n // below to run, aborting every other pending tasks.\n await queue.addAll(tasks)\n } finally {\n ac.abort()\n }\n }\n\n async updateBlobTakedownStatus(\n cid: Cid,\n takedown: com.atproto.admin.defs.StatusAttr,\n ) {\n const takedownRef = takedown.applied\n ? (takedown.ref ?? currentDatetimeString())\n : null\n await this.db.db\n .updateTable('blob')\n .set({ takedownRef })\n .where('cid', '=', cid.toString())\n .executeTakeFirst()\n\n try {\n // @NOTE find a way to not perform i/o operations during the transaction\n // (typically by using a state in the \"blob\" table, and another process to\n // handle the actual i/o)\n if (takedown.applied) {\n await this.blobstore.quarantine(cid)\n } else {\n await this.blobstore.unquarantine(cid)\n }\n } catch (err) {\n if (!(err instanceof BlobNotFoundError)) {\n log.error(\n { err, cid: cid.toString() },\n 'could not update blob takedown status',\n )\n\n throw err\n }\n }\n }\n\n async deleteDereferencedBlobs(\n writes: PreparedWrite[],\n skipBlobStore?: boolean,\n ) {\n const deletes = writes.filter(isDelete)\n const updates = writes.filter(isUpdate)\n const uris = [...deletes, ...updates].map((w) => w.uri.toString())\n if (uris.length === 0) return\n\n const deletedRepoBlobs = await this.db.db\n .deleteFrom('record_blob')\n .where('recordUri', 'in', uris)\n .returning('blobCid')\n .execute()\n if (deletedRepoBlobs.length === 0) return\n\n const deletedRepoBlobCids = deletedRepoBlobs.map((row) => row.blobCid)\n const duplicateCids = await this.db.db\n .selectFrom('record_blob')\n .where('blobCid', 'in', deletedRepoBlobCids)\n .select('blobCid')\n .execute()\n\n const newBlobCids = writes\n .filter((w) => isUpdate(w) || isCreate(w))\n .flatMap((w) => w.blobs.map((b) => b.ref.toString()))\n\n const cidsToKeep = [\n ...newBlobCids,\n ...duplicateCids.map((row) => row.blobCid),\n ]\n\n const cidsToDelete = deletedRepoBlobCids.filter(\n (cid) => !cidsToKeep.includes(cid),\n )\n if (cidsToDelete.length === 0) return\n\n await this.db.db\n .deleteFrom('blob')\n .where('cid', 'in', cidsToDelete)\n .execute()\n\n if (!skipBlobStore) {\n this.db.onCommit(() => {\n this.backgroundQueue.add(async () => {\n try {\n const cids = cidsToDelete.map((cid) => parseCid(cid))\n await this.blobstore.deleteMany(cids)\n } catch (err) {\n log.error(\n { err, cids: cidsToDelete },\n 'could not delete blobs from blobstore',\n )\n }\n })\n })\n }\n }\n\n async verifyBlobAndMakePermanent(\n blob: TypedBlobRef,\n signal?: AbortSignal,\n ): Promise<void> {\n const found = await this.db.db\n .selectFrom('blob')\n .select(['tempKey', 'size', 'mimeType'])\n .where('cid', '=', blob.ref.toString())\n .where('takedownRef', 'is', null)\n .executeTakeFirst()\n\n signal?.throwIfAborted()\n\n if (!found) {\n throw new InvalidRequestError(\n `Could not find blob: ${blob.ref.toString()}`,\n 'BlobNotFound',\n )\n }\n\n if (found.tempKey) {\n verifyBlob(blob, found)\n\n // @NOTE it is less than ideal to perform async (i/o) operations during a\n // transaction. Especially since there have been instances of the actor-db\n // being locked, requiring to kick the processes.\n\n // The better solution would be to update the blob state in the database\n // (e.g. \"makeItPermanent\") and to process those updates outside of the\n // transaction.\n\n await this.blobstore\n .makePermanent(found.tempKey, blob.ref)\n .catch((err) => {\n log.error(\n { err, cid: blob.ref.toString() },\n 'could not make blob permanent',\n )\n\n throw err\n })\n\n signal?.throwIfAborted()\n\n await this.db.db\n .updateTable('blob')\n .set({ tempKey: null })\n .where('tempKey', '=', found.tempKey)\n .execute()\n }\n }\n\n async insertBlobMetadata(blob: TypedBlobRef): Promise<void> {\n await this.db.db\n .insertInto('blob')\n .values({\n cid: blob.ref.toString(),\n mimeType: blob.mimeType,\n size: blob.size,\n createdAt: currentDatetimeString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n\n async associateBlob(blob: TypedBlobRef, recordUri: AtUri): Promise<void> {\n await this.db.db\n .insertInto('record_blob')\n .values({\n blobCid: blob.ref.toString(),\n recordUri: recordUri.toString(),\n })\n .onConflict((oc) => oc.doNothing())\n .execute()\n }\n}\n\n// \"file-type\" does not provide a duplex implementation so we create one here\nclass FileTypePassThrough extends Tee {\n readonly fileTypePromise: Promise<FileTypeResult | undefined>\n\n #fileTypeResult?: PromiseSettledResult<FileTypeResult | undefined>\n get fileTypeResult(): FileTypeResult | undefined {\n const result = this.#fileTypeResult\n if (result) return result.status === 'fulfilled' ? result.value : undefined\n throw new Error('FileTypePassThrough result is not yet available')\n }\n\n constructor(options?: FileTypeOptions) {\n const branch = new PassThrough()\n super(branch)\n\n const parser = new FileTypeParser(options)\n\n // @NOTE file-type does not support NodeJS Readable and recommends wrapping\n // into a web steam. We use strtok3 to convert the NodeJS Readable into a\n // tokenizer, bypassing that limitation.\n this.fileTypePromise = fromStream(branch)\n .then((tokenizer) => parser.fromTokenizer(tokenizer))\n // file-type won't destroy() the stream. We need to destroy to allow\n // the Tee's main stream to flow freely.\n .finally(() => branch.destroy())\n\n // avoids unhandled rejections (might be awaited later)\n this.fileTypePromise.then(\n (value) => {\n this.#fileTypeResult = { status: 'fulfilled', value }\n },\n (reason) => {\n this.#fileTypeResult = { status: 'rejected', reason }\n },\n )\n }\n\n _final(cb: TransformCallback) {\n // propagate the result promise to the final callback, so that the stream is\n // not considered finished until the file type has been determined.\n super._final((err) => {\n this.fileTypePromise.then(\n () => cb(err),\n () => cb(err),\n )\n })\n }\n\n _destroy(err: Error | null, cb: (err?: Error | null) => void) {\n // propagate the result promise to the destroy callback, so that the stream\n // is not considered finished until the file type has been determined.\n super._destroy(err, (err) => {\n this.fileTypePromise.then(\n () => cb(err),\n () => cb(err),\n )\n })\n }\n}\n\n/**\n * Ensures that the blob referenced in the record matches the stored blob.\n */\nfunction verifyBlob(\n blob: TypedBlobRef,\n found: Pick<BlobTable, 'size' | 'mimeType'>,\n) {\n if (blob.mimeType !== found.mimeType) {\n throw new InvalidRequestError(\n `Referenced Mimetype does not match stored blob. Expected: ${found.mimeType}, Got: ${blob.mimeType}`,\n 'InvalidMimeType',\n )\n }\n\n if (blob.size !== found.size) {\n throw new InvalidRequestError(\n `Referenced Size does not match stored blob. Expected: ${found.size}, Got: ${blob.size}`,\n 'InvalidSize',\n )\n }\n}\n\nfunction isCreate(write: PreparedWrite) {\n return write.action === WriteOpAction.Create\n}\nfunction isUpdate(write: PreparedWrite) {\n return write.action === WriteOpAction.Update\n}\nfunction isDelete(write: PreparedWrite) {\n return write.action === WriteOpAction.Delete\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadBlob.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/repo/uploadBlob.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,MAAM,EAGZ,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"uploadBlob.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/repo/uploadBlob.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,MAAM,EAGZ,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA+CvD"}
|
|
@@ -18,7 +18,7 @@ export default function (server, ctx) {
|
|
|
18
18
|
const requester = auth.credentials.did;
|
|
19
19
|
const blob = await ctx.actorStore.writeNoTransaction(requester, async (store) => {
|
|
20
20
|
const metadata = await store.repo.blob
|
|
21
|
-
.uploadBlobAndGetMetadata(input.
|
|
21
|
+
.uploadBlobAndGetMetadata(input.body, input.encoding, ctx.cfg.service.blobUploadLimit)
|
|
22
22
|
.catch(throwAbortAsUpstreamError);
|
|
23
23
|
return store.transact(async (actorTxn) => {
|
|
24
24
|
const blobRef = await actorTxn.repo.blob.trackUntetheredBlob(metadata);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadBlob.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/repo/uploadBlob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AACrC,OAAO,EAEL,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE;QACtC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,8BAA8B,CAAC;YACpD,aAAa,EAAE,IAAI;YACnB,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;gBACtC,WAAW,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC5C,CAAC;SACF,CAAC;QACF,SAAS,EAAE;YACT,UAAU,EAAE,GAAG;YACf,MAAM,EAAE,IAAI;SACb;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;YACjC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAEtC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAClD,SAAS,EACT,KAAK,EAAE,KAAK,EAAE,EAAE;gBACd,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI;qBACnC,wBAAwB,CAAC,KAAK,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"uploadBlob.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/repo/uploadBlob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AACrC,OAAO,EAEL,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE;QACtC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,8BAA8B,CAAC;YACpD,aAAa,EAAE,IAAI;YACnB,SAAS,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;gBACtC,WAAW,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC5C,CAAC;SACF,CAAC;QACF,SAAS,EAAE;YACT,UAAU,EAAE,GAAG;YACf,MAAM,EAAE,IAAI;SACb;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;YACjC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAEtC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAClD,SAAS,EACT,KAAK,EAAE,KAAK,EAAE,EAAE;gBACd,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI;qBACnC,wBAAwB,CACvB,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,QAAQ,EACd,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAChC;qBACA,KAAK,CAAC,yBAAyB,CAAC,CAAA;gBAEnC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;oBACvC,MAAM,OAAO,GACX,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAA;oBAExD,qEAAqE;oBACrE,IAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC5D,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAA;oBAC9D,CAAC;oBAED,OAAO,OAAO,CAAA;gBAChB,CAAC,CAAC,CAAA;YACJ,CAAC,CACF,CAAA;YAED,OAAO;gBACL,QAAQ,EAAE,kBAA2B;gBACrC,IAAI,EAAE,EAAE,IAAI,EAAE;aACf,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,GAAY;IAC7C,sEAAsE;IACtE,wEAAwE;IACxE,sEAAsE;IACtE,qDAAqD;IACrD,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,YAAY,KAAK,IAAI,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;QACvE,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACzD,MAAM,IAAI,oBAAoB,CAAC,wCAAwC,CAAC,CAAA;QAC1E,CAAC;QACD,CAAC,GAAG,CAAC,CAAC,KAAK,CAAA;IACb,CAAC;IACD,MAAM,GAAG,CAAA;AACX,CAAC","sourcesContent":["import { DAY } from '@atproto/common'\nimport {\n type Server,\n UpstreamTimeoutError,\n parseReqEncoding,\n} from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(com.atproto.repo.uploadBlob, {\n auth: ctx.authVerifier.authorizationOrUserServiceAuth({\n checkTakedown: true,\n authorize: (permissions, { req }) => {\n const encoding = parseReqEncoding(req)\n permissions.assertBlob({ mime: encoding })\n },\n }),\n rateLimit: {\n durationMs: DAY,\n points: 1000,\n },\n handler: async ({ auth, input }) => {\n const requester = auth.credentials.did\n\n const blob = await ctx.actorStore.writeNoTransaction(\n requester,\n async (store) => {\n const metadata = await store.repo.blob\n .uploadBlobAndGetMetadata(\n input.body,\n input.encoding,\n ctx.cfg.service.blobUploadLimit,\n )\n .catch(throwAbortAsUpstreamError)\n\n return store.transact(async (actorTxn) => {\n const blobRef =\n await actorTxn.repo.blob.trackUntetheredBlob(metadata)\n\n // make the blob permanent if an associated record is already indexed\n if (await actorTxn.repo.blob.hasRecordsForBlob(blobRef.ref)) {\n await actorTxn.repo.blob.verifyBlobAndMakePermanent(blobRef)\n }\n\n return blobRef\n })\n },\n )\n\n return {\n encoding: 'application/json' as const,\n body: { blob },\n }\n },\n })\n}\n\nfunction throwAbortAsUpstreamError(err: unknown): never {\n // Blob store timeouts surface as AbortError (total upload timeout) or\n // TimeoutError (stalled connection), possibly wrapped as an error cause\n // (e.g. S3BlobStore's \"Blob upload timed out\" error). The depth limit\n // guards against (pathological) cyclic cause chains.\n for (let e = err, depth = 0; e instanceof Error && depth < 10; depth++) {\n if (e.name === 'AbortError' || e.name === 'TimeoutError') {\n throw new UpstreamTimeoutError('Operation timed out, please try again.')\n }\n e = e.cause\n }\n throw err\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentVisibilityDeclaration.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/actor/contentVisibilityDeclaration.ts"],"names":[],"mappings":"AAIA,cAAc,wCAAwC,CAAA;AACtD,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,wCAAwC,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { l } from '@atproto/lex';
|
|
2
|
+
declare const $nsid = "app.bsky.actor.contentVisibilityDeclaration";
|
|
3
|
+
type $nsid = typeof $nsid;
|
|
4
|
+
export { $nsid };
|
|
5
|
+
/** A declaration of an account's preferences for appearing in content discovery surfaces. */
|
|
6
|
+
type Main = {
|
|
7
|
+
$type: 'app.bsky.actor.contentVisibilityDeclaration';
|
|
8
|
+
/**
|
|
9
|
+
* Whether the account requests that its posts be hidden from algorithmic recommendations. Consumers must treat a missing record as false.
|
|
10
|
+
*/
|
|
11
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type { Main };
|
|
14
|
+
/** A declaration of an account's preferences for appearing in content discovery surfaces. */
|
|
15
|
+
declare const main: l.RecordSchema<"literal:self", "app.bsky.actor.contentVisibilityDeclaration", l.Validator<Omit<Main, "$type">, Omit<Main, "$type">>>;
|
|
16
|
+
export { main };
|
|
17
|
+
declare const $type = "app.bsky.actor.contentVisibilityDeclaration";
|
|
18
|
+
type $type = typeof $type;
|
|
19
|
+
export { $type };
|
|
20
|
+
export declare const $isTypeOf: <TValue extends {
|
|
21
|
+
$type?: unknown;
|
|
22
|
+
}>(value: TValue) => value is l.TypedRecord<"app.bsky.actor.contentVisibilityDeclaration", TValue>;
|
|
23
|
+
export declare const $build: {
|
|
24
|
+
(input: Omit<Omit<Main, "$type">, "$type">): {
|
|
25
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
26
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
27
|
+
};
|
|
28
|
+
(input: Omit<Omit<Main, "$type">, "$type">): {
|
|
29
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
30
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export declare const $assert: (input: unknown, options?: l.ValidateOptions) => asserts input is {
|
|
34
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
35
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
36
|
+
};
|
|
37
|
+
export declare const $check: (input: unknown, options?: l.ValidateOptions) => void;
|
|
38
|
+
export declare const $cast: <I>(input: I, options?: l.ValidateOptions) => I & {
|
|
39
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
40
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
41
|
+
};
|
|
42
|
+
export declare const $ifMatches: <I>(input: I, options?: l.ValidateOptions) => (I & {
|
|
43
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
44
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
45
|
+
}) | undefined;
|
|
46
|
+
export declare const $matches: <I>(input: I, options?: l.ValidateOptions) => input is I & {
|
|
47
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
48
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
49
|
+
};
|
|
50
|
+
export declare const $parse: (input: unknown, options?: l.ParseOptions) => {
|
|
51
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
52
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
53
|
+
};
|
|
54
|
+
export declare const $safeParse: (input: unknown, options?: l.ParseOptions) => l.ValidationResult<{
|
|
55
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
56
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
57
|
+
}>;
|
|
58
|
+
export declare const $validate: <I>(input: I, options?: l.ValidateOptions) => I & {
|
|
59
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
60
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
61
|
+
};
|
|
62
|
+
export declare const $safeValidate: <I>(input: I, options?: l.ValidateOptions) => l.ValidationResult<I & {
|
|
63
|
+
$type: "app.bsky.actor.contentVisibilityDeclaration";
|
|
64
|
+
hideFromAlgorithmicRecommendations: boolean;
|
|
65
|
+
}>;
|
|
66
|
+
//# sourceMappingURL=contentVisibilityDeclaration.defs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentVisibilityDeclaration.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,gDAAgD,CAAA;AAE3D,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,6FAA6F;AAC7F,KAAK,IAAI,GAAG;IACV,KAAK,EAAE,6CAA6C,CAAA;IAEpD;;OAEG;IACH,kCAAkC,EAAE,OAAO,CAAA;CAC5C,CAAA;AAED,YAAY,EAAE,IAAI,EAAE,CAAA;AAEpB,6FAA6F;AAC7F,QAAA,MAAM,IAAI,sIAMT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,QAAA,MAAM,KAAK,gDAAQ,CAAA;AAEnB,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,eAAO,MAAM,SAAS;;kGAAyC,CAAA;AAC/D,eAAO,MAAM,MAAM;;;4CAvBmB,OAAO;;;;4CAAP,OAAO;;CAuBY,CAAA;AACzD,eAAO,MAAM,OAAO;;wCAxBkB,OAAO;CAwBc,CAAA;AAC3D,eAAO,MAAM,MAAM,uDAAsC,CAAA;AACzD,eAAO,MAAM,KAAK;;wCA1BoB,OAAO;CA0BU,CAAA;AACvD,eAAO,MAAM,UAAU;;wCA3Be,OAAO;cA2BoB,CAAA;AACjE,eAAO,MAAM,QAAQ;;wCA5BiB,OAAO;CA4BgB,CAAA;AAC7D,eAAO,MAAM,MAAM;;wCA7BmB,OAAO;CA6BY,CAAA;AACzD,eAAO,MAAM,UAAU;;wCA9Be,OAAO;EA8BoB,CAAA;AACjE,eAAO,MAAM,SAAS;;wCA/BgB,OAAO;CA+BkB,CAAA;AAC/D,eAAO,MAAM,aAAa;;wCAhCY,OAAO;EAgC0B,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
import { l } from '@atproto/lex';
|
|
5
|
+
const $nsid = 'app.bsky.actor.contentVisibilityDeclaration';
|
|
6
|
+
export { $nsid };
|
|
7
|
+
/** A declaration of an account's preferences for appearing in content discovery surfaces. */
|
|
8
|
+
const main = /*#__PURE__*/ l.record('literal:self', $nsid,
|
|
9
|
+
/*#__PURE__*/ l.object({
|
|
10
|
+
hideFromAlgorithmicRecommendations: /*#__PURE__*/ l.boolean(),
|
|
11
|
+
}));
|
|
12
|
+
export { main };
|
|
13
|
+
const $type = $nsid;
|
|
14
|
+
export { $type };
|
|
15
|
+
export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main);
|
|
16
|
+
export const $build = /*#__PURE__*/ main.build.bind(main);
|
|
17
|
+
export const $assert = /*#__PURE__*/ main.assert.bind(main);
|
|
18
|
+
export const $check = /*#__PURE__*/ main.check.bind(main);
|
|
19
|
+
export const $cast = /*#__PURE__*/ main.cast.bind(main);
|
|
20
|
+
export const $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main);
|
|
21
|
+
export const $matches = /*#__PURE__*/ main.matches.bind(main);
|
|
22
|
+
export const $parse = /*#__PURE__*/ main.parse.bind(main);
|
|
23
|
+
export const $safeParse = /*#__PURE__*/ main.safeParse.bind(main);
|
|
24
|
+
export const $validate = /*#__PURE__*/ main.validate.bind(main);
|
|
25
|
+
export const $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main);
|
|
26
|
+
//# sourceMappingURL=contentVisibilityDeclaration.defs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentVisibilityDeclaration.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,6CAA6C,CAAA;AAI3D,OAAO,EAAE,KAAK,EAAE,CAAA;AAchB,6FAA6F;AAC7F,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CACjC,cAAc,EACd,KAAK;AACL,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IACrB,kCAAkC,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE;CAC9D,CAAC,CACH,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,MAAM,KAAK,GAAG,KAAK,CAAA;AAInB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/D,MAAM,CAAC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC3D,MAAM,CAAC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,MAAM,CAAC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACvD,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjE,MAAM,CAAC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjE,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.actor.contentVisibilityDeclaration'\n\ntype $nsid = typeof $nsid\n\nexport { $nsid }\n\n/** A declaration of an account's preferences for appearing in content discovery surfaces. */\ntype Main = {\n $type: 'app.bsky.actor.contentVisibilityDeclaration'\n\n /**\n * Whether the account requests that its posts be hidden from algorithmic recommendations. Consumers must treat a missing record as false.\n */\n hideFromAlgorithmicRecommendations: boolean\n}\n\nexport type { Main }\n\n/** A declaration of an account's preferences for appearing in content discovery surfaces. */\nconst main = /*#__PURE__*/ l.record<'literal:self', Main>(\n 'literal:self',\n $nsid,\n /*#__PURE__*/ l.object({\n hideFromAlgorithmicRecommendations: /*#__PURE__*/ l.boolean(),\n }),\n)\n\nexport { main }\n\nconst $type = $nsid\n\ntype $type = typeof $type\n\nexport { $type }\n\nexport const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main)\nexport const $build = /*#__PURE__*/ main.build.bind(main)\nexport const $assert = /*#__PURE__*/ main.assert.bind(main)\nexport const $check = /*#__PURE__*/ main.check.bind(main)\nexport const $cast = /*#__PURE__*/ main.cast.bind(main)\nexport const $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main)\nexport const $matches = /*#__PURE__*/ main.matches.bind(main)\nexport const $parse = /*#__PURE__*/ main.parse.bind(main)\nexport const $safeParse = /*#__PURE__*/ main.safeParse.bind(main)\nexport const $validate = /*#__PURE__*/ main.validate.bind(main)\nexport const $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main)\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentVisibilityDeclaration.js","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/actor/contentVisibilityDeclaration.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,wCAAwC,CAAA;AACtD,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,wCAAwC,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * from './contentVisibilityDeclaration.defs.js'\nexport { main as default } from './contentVisibilityDeclaration.defs.js'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/actor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,qBAAqB,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/actor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,4BAA4B,MAAM,yCAAyC,CAAA;AACvF,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,qBAAqB,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
|
|
3
3
|
*/
|
|
4
|
+
export * as contentVisibilityDeclaration from './actor/contentVisibilityDeclaration.js';
|
|
4
5
|
export * as defs from './actor/defs.js';
|
|
5
6
|
export * as getPreferences from './actor/getPreferences.js';
|
|
6
7
|
export * as getProfile from './actor/getProfile.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/actor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,qBAAqB,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as defs from './actor/defs.js'\nexport * as getPreferences from './actor/getPreferences.js'\nexport * as getProfile from './actor/getProfile.js'\nexport * as getProfiles from './actor/getProfiles.js'\nexport * as getSuggestions from './actor/getSuggestions.js'\nexport * as profile from './actor/profile.js'\nexport * as putPreferences from './actor/putPreferences.js'\nexport * as searchActors from './actor/searchActors.js'\nexport * as searchActorsTypeahead from './actor/searchActorsTypeahead.js'\nexport * as status from './actor/status.js'\n"]}
|
|
1
|
+
{"version":3,"file":"actor.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/actor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,4BAA4B,MAAM,yCAAyC,CAAA;AACvF,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,qBAAqB,MAAM,kCAAkC,CAAA;AACzE,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as contentVisibilityDeclaration from './actor/contentVisibilityDeclaration.js'\nexport * as defs from './actor/defs.js'\nexport * as getPreferences from './actor/getPreferences.js'\nexport * as getProfile from './actor/getProfile.js'\nexport * as getProfiles from './actor/getProfiles.js'\nexport * as getSuggestions from './actor/getSuggestions.js'\nexport * as profile from './actor/profile.js'\nexport * as putPreferences from './actor/putPreferences.js'\nexport * as searchActors from './actor/searchActors.js'\nexport * as searchActorsTypeahead from './actor/searchActorsTypeahead.js'\nexport * as status from './actor/status.js'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authCreatePosts.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authCreatePosts.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,6BAA6B,CAAA;AAExC,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"authCreatePosts.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authCreatePosts.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,6BAA6B,CAAA;AAExC,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,uHA+BT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -11,6 +11,11 @@ const main = /*#__PURE__*/ l.permissionSet($nsid, [
|
|
|
11
11
|
'app.bsky.video.uploadVideo',
|
|
12
12
|
'app.bsky.video.getJobStatus',
|
|
13
13
|
'app.bsky.video.getUploadLimits',
|
|
14
|
+
'app.bsky.video.startUpload',
|
|
15
|
+
'app.bsky.video.uploadPart',
|
|
16
|
+
'app.bsky.video.finishUpload',
|
|
17
|
+
'app.bsky.video.abortUpload',
|
|
18
|
+
'app.bsky.video.getUploadStatus',
|
|
14
19
|
],
|
|
15
20
|
}),
|
|
16
21
|
/*#__PURE__*/ l.permission('repo', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authCreatePosts.defs.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authCreatePosts.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,0BAA0B,CAAA;AAIxC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CACxC,KAAK,EACL;IACE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,IAAI;QAChB,GAAG,EAAE;YACH,4BAA4B;YAC5B,6BAA6B;YAC7B,gCAAgC;SACjC;KACF,CAAC;IACF,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE;QACjC,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,UAAU,EAAE;YACV,oBAAoB;YACpB,wBAAwB;YACxB,0BAA0B;SAC3B;KACF,CAAC;CACH,EACD;IACE,KAAK,EAAE,sBAAsB;IAC7B,YAAY,EAAE,EAAE;IAChB,MAAM,EAAE,iCAAiC;IACzC,aAAa,EAAE,EAAE;CAClB,CACF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.authCreatePosts'\n\ntype $nsid = typeof $nsid\n\nexport { $nsid }\n\nconst main = /*#__PURE__*/ l.permissionSet(\n $nsid,\n [\n /*#__PURE__*/ l.permission('rpc', {\n inheritAud: true,\n lxm: [\n 'app.bsky.video.uploadVideo',\n 'app.bsky.video.getJobStatus',\n 'app.bsky.video.getUploadLimits',\n ],\n }),\n /*#__PURE__*/ l.permission('repo', {\n action: ['create'],\n collection: [\n 'app.bsky.feed.post',\n 'app.bsky.feed.postgate',\n 'app.bsky.feed.threadgate',\n ],\n }),\n ],\n {\n title: 'Create Bluesky Posts',\n 'title:lang': {},\n detail: 'Can not update or delete posts.',\n 'detail:lang': {},\n },\n)\n\nexport { main }\n"]}
|
|
1
|
+
{"version":3,"file":"authCreatePosts.defs.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authCreatePosts.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,0BAA0B,CAAA;AAIxC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CACxC,KAAK,EACL;IACE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,IAAI;QAChB,GAAG,EAAE;YACH,4BAA4B;YAC5B,6BAA6B;YAC7B,gCAAgC;YAChC,4BAA4B;YAC5B,2BAA2B;YAC3B,6BAA6B;YAC7B,4BAA4B;YAC5B,gCAAgC;SACjC;KACF,CAAC;IACF,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE;QACjC,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,UAAU,EAAE;YACV,oBAAoB;YACpB,wBAAwB;YACxB,0BAA0B;SAC3B;KACF,CAAC;CACH,EACD;IACE,KAAK,EAAE,sBAAsB;IAC7B,YAAY,EAAE,EAAE;IAChB,MAAM,EAAE,iCAAiC;IACzC,aAAa,EAAE,EAAE;CAClB,CACF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.authCreatePosts'\n\ntype $nsid = typeof $nsid\n\nexport { $nsid }\n\nconst main = /*#__PURE__*/ l.permissionSet(\n $nsid,\n [\n /*#__PURE__*/ l.permission('rpc', {\n inheritAud: true,\n lxm: [\n 'app.bsky.video.uploadVideo',\n 'app.bsky.video.getJobStatus',\n 'app.bsky.video.getUploadLimits',\n 'app.bsky.video.startUpload',\n 'app.bsky.video.uploadPart',\n 'app.bsky.video.finishUpload',\n 'app.bsky.video.abortUpload',\n 'app.bsky.video.getUploadStatus',\n ],\n }),\n /*#__PURE__*/ l.permission('repo', {\n action: ['create'],\n collection: [\n 'app.bsky.feed.post',\n 'app.bsky.feed.postgate',\n 'app.bsky.feed.threadgate',\n ],\n }),\n ],\n {\n title: 'Create Bluesky Posts',\n 'title:lang': {},\n detail: 'Can not update or delete posts.',\n 'detail:lang': {},\n },\n)\n\nexport { main }\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authFullApp.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authFullApp.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"authFullApp.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authFullApp.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,mHAuIT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -103,6 +103,11 @@ const main = /*#__PURE__*/ l.permissionSet($nsid, [
|
|
|
103
103
|
'app.bsky.video.getJobStatus',
|
|
104
104
|
'app.bsky.video.getUploadLimits',
|
|
105
105
|
'app.bsky.video.uploadVideo',
|
|
106
|
+
'app.bsky.video.startUpload',
|
|
107
|
+
'app.bsky.video.uploadPart',
|
|
108
|
+
'app.bsky.video.finishUpload',
|
|
109
|
+
'app.bsky.video.abortUpload',
|
|
110
|
+
'app.bsky.video.getUploadStatus',
|
|
106
111
|
],
|
|
107
112
|
}),
|
|
108
113
|
/*#__PURE__*/ l.permission('repo', {
|