@clioplaylists/clio 0.1.8 → 0.1.9
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/dist/api/com/clioplaylists/alpha/feed/getRecommendedPlaylistsByUser.d.ts +3 -0
- package/dist/api/com/clioplaylists/alpha/feed/getRecommendedPlaylistsByUser.js +70 -0
- package/dist/api/health.js +10 -3
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +40 -2
- package/dist/api/oauth.d.ts +3 -0
- package/dist/api/oauth.js +63 -0
- package/dist/api/util.d.ts +1 -0
- package/dist/api/util.js +11 -6
- package/dist/api/well-known.js +8 -4
- package/dist/auth-verifier.d.ts +17 -4
- package/dist/auth-verifier.js +171 -165
- package/dist/client.js +15 -8
- package/dist/config.d.ts +21 -0
- package/dist/config.js +77 -7
- package/dist/context.d.ts +11 -0
- package/dist/context.js +14 -1
- package/dist/dataplane/client/hosts.js +5 -1
- package/dist/dataplane/client/index.d.ts +2 -0
- package/dist/dataplane/client/index.js +40 -17
- package/dist/dataplane/client/util.d.ts +20 -0
- package/dist/dataplane/client/util.js +92 -0
- package/dist/dataplane/index.js +18 -2
- package/dist/dataplane/server/background.d.ts +1 -1
- package/dist/dataplane/server/background.js +12 -5
- package/dist/dataplane/server/db/database-schema.d.ts +5 -1
- package/dist/dataplane/server/db/database-schema.js +2 -1
- package/dist/dataplane/server/db/db.js +60 -20
- package/dist/dataplane/server/db/index.js +17 -1
- package/dist/dataplane/server/db/migrations/20250515T045948368Z-init.d.ts +3 -0
- package/dist/dataplane/server/db/migrations/20250515T045948368Z-init.js +170 -0
- package/dist/dataplane/server/db/migrations/20260119T210000000Z-song-recommendation.d.ts +3 -0
- package/dist/dataplane/server/db/migrations/20260119T210000000Z-song-recommendation.js +36 -0
- package/dist/dataplane/server/db/migrations/20260119T220000000Z-oauth.d.ts +3 -0
- package/dist/dataplane/server/db/migrations/20260119T220000000Z-oauth.js +25 -0
- package/dist/dataplane/server/db/migrations/index.d.ts +3 -2
- package/dist/dataplane/server/db/migrations/index.js +39 -2
- package/dist/dataplane/server/db/migrations/provider.js +5 -1
- package/dist/dataplane/server/db/pagination.d.ts +1 -1
- package/dist/dataplane/server/db/pagination.js +38 -25
- package/dist/dataplane/server/db/tables/actor-sync.d.ts +2 -2
- package/dist/dataplane/server/db/tables/actor-sync.js +4 -1
- package/dist/dataplane/server/db/tables/actor.d.ts +3 -3
- package/dist/dataplane/server/db/tables/actor.js +4 -1
- package/dist/dataplane/server/db/tables/artist-list-item.d.ts +2 -2
- package/dist/dataplane/server/db/tables/artist-list-item.js +4 -1
- package/dist/dataplane/server/db/tables/artist.js +4 -1
- package/dist/dataplane/server/db/tables/oauth-session.d.ts +9 -0
- package/dist/dataplane/server/db/tables/oauth-session.js +4 -0
- package/dist/dataplane/server/db/tables/oauth-state.d.ts +10 -0
- package/dist/dataplane/server/db/tables/oauth-state.js +4 -0
- package/dist/dataplane/server/db/tables/playlist-idea.d.ts +3 -3
- package/dist/dataplane/server/db/tables/playlist-idea.js +4 -1
- package/dist/dataplane/server/db/tables/playlist-item.js +4 -1
- package/dist/dataplane/server/db/tables/playlist.d.ts +1 -0
- package/dist/dataplane/server/db/tables/playlist.js +4 -1
- package/dist/dataplane/server/db/tables/profile.d.ts +5 -5
- package/dist/dataplane/server/db/tables/profile.js +4 -1
- package/dist/dataplane/server/db/tables/record.d.ts +1 -1
- package/dist/dataplane/server/db/tables/record.js +4 -1
- package/dist/dataplane/server/db/tables/song-recommendation.d.ts +17 -0
- package/dist/dataplane/server/db/tables/song-recommendation.js +4 -0
- package/dist/dataplane/server/db/tables/song.d.ts +2 -2
- package/dist/dataplane/server/db/tables/song.js +4 -1
- package/dist/dataplane/server/db/tables/subscription-cursor.d.ts +9 -0
- package/dist/dataplane/server/db/tables/subscription-cursor.js +4 -0
- package/dist/dataplane/server/db/types.js +2 -1
- package/dist/dataplane/server/db/util.d.ts +7 -3
- package/dist/dataplane/server/db/util.js +26 -18
- package/dist/dataplane/server/index.js +21 -13
- package/dist/dataplane/server/indexing/index.d.ts +2 -0
- package/dist/dataplane/server/indexing/index.js +82 -66
- package/dist/dataplane/server/indexing/plugins/playlist-idea.d.ts +1 -2
- package/dist/dataplane/server/indexing/plugins/playlist-idea.js +50 -41
- package/dist/dataplane/server/indexing/plugins/profile.js +45 -12
- package/dist/dataplane/server/indexing/plugins/song-recommendation.d.ts +9 -0
- package/dist/dataplane/server/indexing/plugins/song-recommendation.js +101 -0
- package/dist/dataplane/server/indexing/processor.js +12 -11
- package/dist/dataplane/server/routes/identity.d.ts +19 -0
- package/dist/dataplane/server/routes/identity.js +32 -25
- package/dist/dataplane/server/routes/index.js +15 -10
- package/dist/dataplane/server/routes/profile.js +17 -25
- package/dist/dataplane/server/routes/records.d.ts +18 -0
- package/dist/dataplane/server/routes/records.js +48 -22
- package/dist/dataplane/server/routes/sync.js +5 -3
- package/dist/dataplane/server/storage/subscription-cursor.d.ts +3 -0
- package/dist/dataplane/server/storage/subscription-cursor.js +25 -0
- package/dist/dataplane/server/subscription.d.ts +6 -3
- package/dist/dataplane/server/subscription.js +73 -63
- package/dist/error.js +9 -5
- package/dist/index.d.ts +6 -3
- package/dist/index.js +91 -28
- package/dist/lexicons/index.d.ts +3 -210
- package/dist/lexicons/index.js +26 -403
- package/dist/lexicons/lexicons.d.ts +409 -8107
- package/dist/lexicons/lexicons.js +134 -4276
- package/dist/lexicons/types/com/atproto/repo/strongRef.d.ts +4 -4
- package/dist/lexicons/types/com/atproto/repo/strongRef.js +13 -9
- package/dist/lexicons/types/com/clioplaylists/alpha/actor/profile.d.ts +10 -8
- package/dist/lexicons/types/com/clioplaylists/alpha/actor/profile.js +13 -9
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/defs.d.ts +20 -11
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/defs.js +29 -14
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/getRecommendedPlaylistsByUser.d.ts +36 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/getRecommendedPlaylistsByUser.js +6 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/playlistIdea.d.ts +11 -14
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/playlistIdea.js +20 -23
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/recommendedPlaylist.d.ts +18 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/recommendedPlaylist.js +15 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/songRecommendation.d.ts +18 -0
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/songRecommendation.js +15 -0
- package/dist/lexicons/util.d.ts +33 -2
- package/dist/lexicons/util.js +32 -4
- package/dist/logger.js +16 -10
- package/dist/oauth/client.d.ts +14 -0
- package/dist/oauth/client.js +126 -0
- package/dist/oauth/pds-agent.d.ts +3 -0
- package/dist/oauth/pds-agent.js +15 -0
- package/dist/rpc/clio_connect.d.ts +101 -11
- package/dist/rpc/clio_connect.js +138 -45
- package/dist/rpc/clio_pb.d.ts +448 -30
- package/dist/rpc/clio_pb.js +967 -272
- package/dist/util/retry.js +10 -9
- package/dist/util/uris.js +6 -3
- package/dist/util.d.ts +0 -1
- package/dist/util.js +61 -20
- package/package.json +26 -5
package/dist/config.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ServerConfig = void 0;
|
|
7
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
+
class ServerConfig {
|
|
3
9
|
cfg;
|
|
4
10
|
assignedPort;
|
|
5
11
|
constructor(cfg) {
|
|
@@ -8,25 +14,46 @@ export class ServerConfig {
|
|
|
8
14
|
static readEnv(overrides) {
|
|
9
15
|
const version = overrides?.version || process.env.CLIO_VERSION || undefined;
|
|
10
16
|
const debugMode = overrides?.debugMode || process.env.NODE_ENV !== 'production';
|
|
17
|
+
const publicUrl = overrides?.publicUrl ?? process.env.CLIO_PUBLIC_URL;
|
|
11
18
|
const serverDid = overrides?.serverDid || process.env.CLIO_SERVER_DID || 'did:example:test';
|
|
12
19
|
const didPlcUrl = overrides?.didPlcUrl || process.env.DID_PLC_URL || 'http://localhost:2582';
|
|
13
20
|
const dataplaneUrls = overrides?.dataplaneUrls ?? envList(process.env.CLIO_DATAPLANE_URLS);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
const handleResolverNameservers = process.env.BSKY_HANDLE_RESOLVER_NAMESERVERS
|
|
22
|
+
? process.env.BSKY_HANDLE_RESOLVER_NAMESERVERS.split(',')
|
|
23
|
+
: [];
|
|
24
|
+
const modServiceDid = overrides?.modServiceDid || process.env.CLIO_MOD_SERVICE_DID || '';
|
|
25
|
+
const adminPasswords = overrides?.adminPasswords ?? envList(process.env.CLIO_ADMIN_PASSWORDS);
|
|
26
|
+
const dbPostgresUrl = overrides?.dbPostgresUrl ?? process.env.CLIO_DB_POSTGRES_URL;
|
|
27
|
+
const dbPostgresSchema = overrides?.dbPostgresSchema ?? process.env.CLIO_DB_POSTGRES_SCHEMA;
|
|
28
|
+
const oauthScope = overrides?.oauthScope ?? process.env.CLIO_OAUTH_SCOPE ?? 'atproto';
|
|
29
|
+
const oauthAllowHttp = overrides?.oauthAllowHttp ?? envBool(process.env.CLIO_OAUTH_ALLOW_HTTP);
|
|
30
|
+
const proxyPreferCompressed = overrides?.proxyPreferCompressed ?? envBool(process.env.CLIO_PROXY_PREFER_COMPRESSED);
|
|
31
|
+
const blobRateLimitBypassKey = overrides?.blobRateLimitBypassKey ?? process.env.CLIO_BLOB_RATELIMIT_BYPASS_KEY;
|
|
32
|
+
const blobRateLimitBypassHostname = overrides?.blobRateLimitBypassHostname ?? process.env.CLIO_BLOB_RATELIMIT_BYPASS_HOSTNAME;
|
|
17
33
|
const envPort = overrides?.port || parseInt(process.env.CLIO_PORT || '', 10);
|
|
18
34
|
const port = isNaN(envPort) ? 2635 : envPort;
|
|
19
35
|
return new ServerConfig({
|
|
20
36
|
version,
|
|
21
37
|
debugMode,
|
|
22
38
|
port,
|
|
39
|
+
publicUrl,
|
|
23
40
|
serverDid,
|
|
24
41
|
didPlcUrl,
|
|
42
|
+
handleResolverNameservers,
|
|
25
43
|
dataplaneUrls,
|
|
44
|
+
dbPostgresUrl,
|
|
45
|
+
dbPostgresSchema,
|
|
46
|
+
modServiceDid,
|
|
47
|
+
adminPasswords,
|
|
48
|
+
oauthScope,
|
|
49
|
+
oauthAllowHttp,
|
|
50
|
+
proxyPreferCompressed,
|
|
51
|
+
blobRateLimitBypassKey,
|
|
52
|
+
blobRateLimitBypassHostname,
|
|
26
53
|
});
|
|
27
54
|
}
|
|
28
55
|
assignPort(port) {
|
|
29
|
-
|
|
56
|
+
(0, node_assert_1.default)(!this.cfg.port || this.cfg.port === port, 'Conflicting port in config');
|
|
30
57
|
this.assignedPort = port;
|
|
31
58
|
}
|
|
32
59
|
get version() {
|
|
@@ -39,9 +66,12 @@ export class ServerConfig {
|
|
|
39
66
|
return this.assignedPort || this.cfg.port;
|
|
40
67
|
}
|
|
41
68
|
get localUrl() {
|
|
42
|
-
|
|
69
|
+
(0, node_assert_1.default)(this.port, 'No port assigned');
|
|
43
70
|
return `http://localhost:${this.port}`;
|
|
44
71
|
}
|
|
72
|
+
get publicUrl() {
|
|
73
|
+
return this.cfg.publicUrl ?? this.localUrl;
|
|
74
|
+
}
|
|
45
75
|
get serverDid() {
|
|
46
76
|
return this.cfg.serverDid;
|
|
47
77
|
}
|
|
@@ -51,9 +81,49 @@ export class ServerConfig {
|
|
|
51
81
|
get dataplaneUrls() {
|
|
52
82
|
return this.cfg.dataplaneUrls;
|
|
53
83
|
}
|
|
84
|
+
get dbPostgresUrl() {
|
|
85
|
+
return this.cfg.dbPostgresUrl;
|
|
86
|
+
}
|
|
87
|
+
get dbPostgresSchema() {
|
|
88
|
+
return this.cfg.dbPostgresSchema;
|
|
89
|
+
}
|
|
90
|
+
get modServiceDid() {
|
|
91
|
+
return this.cfg.modServiceDid;
|
|
92
|
+
}
|
|
93
|
+
get adminPasswords() {
|
|
94
|
+
return this.cfg.adminPasswords;
|
|
95
|
+
}
|
|
96
|
+
get oauthScope() {
|
|
97
|
+
return this.cfg.oauthScope ?? 'atproto';
|
|
98
|
+
}
|
|
99
|
+
get oauthAllowHttp() {
|
|
100
|
+
return !!this.cfg.oauthAllowHttp;
|
|
101
|
+
}
|
|
102
|
+
get handleResolverNameservers() {
|
|
103
|
+
return this.cfg.handleResolverNameservers;
|
|
104
|
+
}
|
|
105
|
+
get proxyPreferCompressed() {
|
|
106
|
+
return !!this.cfg.proxyPreferCompressed;
|
|
107
|
+
}
|
|
108
|
+
get blobRateLimitBypassKey() {
|
|
109
|
+
return this.cfg.blobRateLimitBypassKey;
|
|
110
|
+
}
|
|
111
|
+
get blobRateLimitBypassHostname() {
|
|
112
|
+
return this.cfg.blobRateLimitBypassHostname;
|
|
113
|
+
}
|
|
54
114
|
}
|
|
115
|
+
exports.ServerConfig = ServerConfig;
|
|
55
116
|
function envList(str) {
|
|
56
117
|
if (str === undefined || str.length === 0)
|
|
57
118
|
return [];
|
|
58
119
|
return str.split(',');
|
|
59
120
|
}
|
|
121
|
+
function envBool(str) {
|
|
122
|
+
if (str === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
if (str === 'true' || str === '1')
|
|
125
|
+
return true;
|
|
126
|
+
if (str === 'false' || str === '0')
|
|
127
|
+
return false;
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import { Keypair } from '@atproto/crypto';
|
|
2
|
+
import { IdResolver } from '@atproto/identity';
|
|
3
|
+
import { Dispatcher } from 'undici';
|
|
4
|
+
import { AuthVerifier } from './auth-verifier';
|
|
2
5
|
import { DataPlaneClient } from './client';
|
|
3
6
|
import { ServerConfig } from './config';
|
|
7
|
+
import { HostList } from './dataplane';
|
|
4
8
|
export default class AppContext {
|
|
5
9
|
private opts;
|
|
6
10
|
constructor(opts: {
|
|
7
11
|
cfg: ServerConfig;
|
|
8
12
|
dataplane: DataPlaneClient;
|
|
13
|
+
dataplaneHostList: HostList;
|
|
9
14
|
signingKey: Keypair;
|
|
15
|
+
idResolver: IdResolver;
|
|
16
|
+
authVerifier: AuthVerifier;
|
|
17
|
+
blobDispatcher?: Dispatcher;
|
|
10
18
|
});
|
|
11
19
|
get cfg(): ServerConfig;
|
|
12
20
|
get dataplane(): DataPlaneClient;
|
|
13
21
|
get signingKey(): Keypair;
|
|
22
|
+
get authVerifier(): AuthVerifier;
|
|
23
|
+
get idResolver(): IdResolver;
|
|
24
|
+
get blobDispatcher(): Dispatcher;
|
|
14
25
|
}
|
package/dist/context.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const undici_1 = require("undici");
|
|
4
|
+
class AppContext {
|
|
2
5
|
opts;
|
|
3
6
|
constructor(opts) {
|
|
4
7
|
this.opts = opts;
|
|
@@ -12,4 +15,14 @@ export default class AppContext {
|
|
|
12
15
|
get signingKey() {
|
|
13
16
|
return this.opts.signingKey;
|
|
14
17
|
}
|
|
18
|
+
get authVerifier() {
|
|
19
|
+
return this.opts.authVerifier;
|
|
20
|
+
}
|
|
21
|
+
get idResolver() {
|
|
22
|
+
return this.opts.idResolver;
|
|
23
|
+
}
|
|
24
|
+
get blobDispatcher() {
|
|
25
|
+
return this.opts.blobDispatcher ?? new undici_1.Agent();
|
|
26
|
+
}
|
|
15
27
|
}
|
|
28
|
+
exports.default = AppContext;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BasicHostList = void 0;
|
|
1
4
|
/**
|
|
2
5
|
* Maintains a reactive HostList based on a simple setter.
|
|
3
6
|
*/
|
|
4
|
-
|
|
7
|
+
class BasicHostList {
|
|
5
8
|
hosts;
|
|
6
9
|
handlers = [];
|
|
7
10
|
constructor(hosts) {
|
|
@@ -23,3 +26,4 @@ export class BasicHostList {
|
|
|
23
26
|
this.handlers.push(handler);
|
|
24
27
|
}
|
|
25
28
|
}
|
|
29
|
+
exports.BasicHostList = BasicHostList;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Client, Code, ConnectError } from '@connectrpc/connect';
|
|
2
2
|
import { ClioService } from '../../rpc/clio_connect';
|
|
3
3
|
import { HostList } from './hosts';
|
|
4
|
+
export * from './hosts';
|
|
5
|
+
export * from './util';
|
|
4
6
|
export type DataPlaneClient = Client<typeof ClioService>;
|
|
5
7
|
type HttpVersion = '1.1' | '2';
|
|
6
8
|
export declare const createDataPlaneClient: (hostList: HostList, opts: {
|
|
@@ -1,25 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.isDataplaneError = exports.Code = exports.createDataPlaneClient = void 0;
|
|
21
|
+
const connect_1 = require("@connectrpc/connect");
|
|
22
|
+
Object.defineProperty(exports, "Code", { enumerable: true, get: function () { return connect_1.Code; } });
|
|
23
|
+
const connect_node_1 = require("@connectrpc/connect-node");
|
|
24
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
25
|
+
const node_crypto_1 = require("node:crypto");
|
|
26
|
+
const clio_connect_1 = require("../../rpc/clio_connect");
|
|
27
|
+
__exportStar(require("./hosts"), exports);
|
|
28
|
+
__exportStar(require("./util"), exports);
|
|
6
29
|
const MAX_RETRIES = 3;
|
|
7
|
-
|
|
30
|
+
const createDataPlaneClient = (hostList, opts) => {
|
|
8
31
|
const clients = new DataPlaneClients(hostList, opts);
|
|
9
|
-
return makeAnyClient(ClioService, (method) => {
|
|
32
|
+
return (0, connect_1.makeAnyClient)(clio_connect_1.ClioService, (method) => {
|
|
10
33
|
return async (...args) => {
|
|
11
34
|
let tries = 0;
|
|
12
35
|
let error;
|
|
13
36
|
let remainingClients = clients.get();
|
|
14
37
|
while (tries < MAX_RETRIES) {
|
|
15
38
|
const client = randomElement(remainingClients);
|
|
16
|
-
|
|
39
|
+
(0, node_assert_1.default)(client, 'no clients available');
|
|
17
40
|
try {
|
|
18
41
|
return await client[method.localName](...args);
|
|
19
42
|
}
|
|
20
43
|
catch (err) {
|
|
21
|
-
if (err instanceof ConnectError &&
|
|
22
|
-
(err.code === Code.Unavailable || err.code === Code.Aborted)) {
|
|
44
|
+
if (err instanceof connect_1.ConnectError && (err.code === connect_1.Code.Unavailable || err.code === connect_1.Code.Aborted)) {
|
|
23
45
|
tries++;
|
|
24
46
|
error = err;
|
|
25
47
|
remainingClients = getRemainingClients(remainingClients, client);
|
|
@@ -29,12 +51,12 @@ export const createDataPlaneClient = (hostList, opts) => {
|
|
|
29
51
|
}
|
|
30
52
|
}
|
|
31
53
|
}
|
|
32
|
-
|
|
54
|
+
(0, node_assert_1.default)(error);
|
|
33
55
|
throw error;
|
|
34
56
|
};
|
|
35
57
|
});
|
|
36
58
|
};
|
|
37
|
-
|
|
59
|
+
exports.createDataPlaneClient = createDataPlaneClient;
|
|
38
60
|
/**
|
|
39
61
|
* Uses a reactive HostList in order to maintain a pool of DataPlaneClients.
|
|
40
62
|
* Each DataPlaneClient is cached per host so that it maintains connections
|
|
@@ -69,21 +91,22 @@ class DataPlaneClients {
|
|
|
69
91
|
return createBaseClient(host, this.clientOpts);
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
|
-
|
|
73
|
-
if (err instanceof ConnectError) {
|
|
94
|
+
const isDataplaneError = (err, code) => {
|
|
95
|
+
if (err instanceof connect_1.ConnectError) {
|
|
74
96
|
return !code || err.code === code;
|
|
75
97
|
}
|
|
76
98
|
return false;
|
|
77
99
|
};
|
|
100
|
+
exports.isDataplaneError = isDataplaneError;
|
|
78
101
|
const createBaseClient = (baseUrl, opts) => {
|
|
79
102
|
const { httpVersion = '2', rejectUnauthorized = true } = opts;
|
|
80
|
-
const transport = createGrpcTransport({
|
|
103
|
+
const transport = (0, connect_node_1.createGrpcTransport)({
|
|
81
104
|
baseUrl,
|
|
82
105
|
httpVersion,
|
|
83
106
|
acceptCompression: [],
|
|
84
107
|
nodeOptions: { rejectUnauthorized },
|
|
85
108
|
});
|
|
86
|
-
return createClient(ClioService, transport);
|
|
109
|
+
return (0, connect_1.createClient)(clio_connect_1.ClioService, transport);
|
|
87
110
|
};
|
|
88
111
|
const getRemainingClients = (clients, lastClient) => {
|
|
89
112
|
if (clients.length < 2)
|
|
@@ -93,5 +116,5 @@ const getRemainingClients = (clients, lastClient) => {
|
|
|
93
116
|
const randomElement = (arr) => {
|
|
94
117
|
if (arr.length === 0)
|
|
95
118
|
return;
|
|
96
|
-
return arr[randomInt(arr.length)];
|
|
119
|
+
return arr[(0, node_crypto_1.randomInt)(arr.length)];
|
|
97
120
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Code, ConnectError } from '@connectrpc/connect';
|
|
2
|
+
export declare const isDataplaneError: (err: unknown, code?: Code) => err is ConnectError;
|
|
3
|
+
export declare const unpackIdentityServices: (servicesBytes: Uint8Array) => UnpackedServices;
|
|
4
|
+
export declare const unpackIdentityKeys: (keysBytes: Uint8Array) => UnpackedKeys;
|
|
5
|
+
export declare const getServiceEndpoint: (services: UnpackedServices, opts: {
|
|
6
|
+
id: string;
|
|
7
|
+
type: string;
|
|
8
|
+
}) => string | undefined;
|
|
9
|
+
export declare const getKeyAsDidKey: (keys: UnpackedKeys, opts: {
|
|
10
|
+
id: string;
|
|
11
|
+
}) => string | undefined;
|
|
12
|
+
type UnpackedServices = Record<string, {
|
|
13
|
+
Type: string;
|
|
14
|
+
URL: string;
|
|
15
|
+
}>;
|
|
16
|
+
type UnpackedKeys = Record<string, {
|
|
17
|
+
Type: string;
|
|
18
|
+
PublicKeyMultibase: string;
|
|
19
|
+
}>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getKeyAsDidKey = exports.getServiceEndpoint = exports.unpackIdentityKeys = exports.unpackIdentityServices = exports.isDataplaneError = void 0;
|
|
37
|
+
const identity_1 = require("@atproto/identity");
|
|
38
|
+
const connect_1 = require("@connectrpc/connect");
|
|
39
|
+
const ui8 = __importStar(require("uint8arrays"));
|
|
40
|
+
const isDataplaneError = (err, code) => {
|
|
41
|
+
if (err instanceof connect_1.ConnectError) {
|
|
42
|
+
return !code || err.code === code;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
};
|
|
46
|
+
exports.isDataplaneError = isDataplaneError;
|
|
47
|
+
const unpackIdentityServices = (servicesBytes) => {
|
|
48
|
+
const servicesStr = ui8.toString(servicesBytes, 'utf8');
|
|
49
|
+
if (!servicesStr)
|
|
50
|
+
return {};
|
|
51
|
+
return JSON.parse(servicesStr);
|
|
52
|
+
};
|
|
53
|
+
exports.unpackIdentityServices = unpackIdentityServices;
|
|
54
|
+
const unpackIdentityKeys = (keysBytes) => {
|
|
55
|
+
const keysStr = ui8.toString(keysBytes, 'utf8');
|
|
56
|
+
if (!keysStr)
|
|
57
|
+
return {};
|
|
58
|
+
return JSON.parse(keysStr);
|
|
59
|
+
};
|
|
60
|
+
exports.unpackIdentityKeys = unpackIdentityKeys;
|
|
61
|
+
const getServiceEndpoint = (services, opts) => {
|
|
62
|
+
const endpoint = services[opts.id] && services[opts.id].Type === opts.type && validateUrl(services[opts.id].URL);
|
|
63
|
+
return endpoint || undefined;
|
|
64
|
+
};
|
|
65
|
+
exports.getServiceEndpoint = getServiceEndpoint;
|
|
66
|
+
const getKeyAsDidKey = (keys, opts) => {
|
|
67
|
+
const key = keys[opts.id] &&
|
|
68
|
+
(0, identity_1.getDidKeyFromMultibase)({
|
|
69
|
+
type: keys[opts.id].Type,
|
|
70
|
+
publicKeyMultibase: keys[opts.id].PublicKeyMultibase,
|
|
71
|
+
});
|
|
72
|
+
return key || undefined;
|
|
73
|
+
};
|
|
74
|
+
exports.getKeyAsDidKey = getKeyAsDidKey;
|
|
75
|
+
const validateUrl = (urlStr) => {
|
|
76
|
+
let url;
|
|
77
|
+
try {
|
|
78
|
+
url = new URL(urlStr);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
if (!['http:', 'https:'].includes(url.protocol)) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
else if (!url.hostname) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
return urlStr;
|
|
91
|
+
}
|
|
92
|
+
};
|
package/dist/dataplane/index.js
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./client"), exports);
|
|
18
|
+
__exportStar(require("./server"), exports);
|
|
@@ -2,7 +2,7 @@ import PQueue from 'p-queue';
|
|
|
2
2
|
import { Database } from './db';
|
|
3
3
|
export declare class BackgroundQueue {
|
|
4
4
|
db: Database;
|
|
5
|
-
queue: PQueue<import("p-queue/dist/priority-queue").default, import("p-queue").
|
|
5
|
+
queue: PQueue<import("p-queue/dist/priority-queue").default, import("p-queue").QueueAddOptions>;
|
|
6
6
|
destroyed: boolean;
|
|
7
7
|
constructor(db: Database);
|
|
8
8
|
add(task: Task): void;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BackgroundQueue = void 0;
|
|
7
|
+
const p_queue_1 = __importDefault(require("p-queue"));
|
|
8
|
+
const logger_1 = require("../../logger");
|
|
3
9
|
// A simple queue for in-process, out-of-band/backgrounded work
|
|
4
|
-
|
|
10
|
+
class BackgroundQueue {
|
|
5
11
|
db;
|
|
6
|
-
queue = new
|
|
12
|
+
queue = new p_queue_1.default();
|
|
7
13
|
destroyed = false;
|
|
8
14
|
constructor(db) {
|
|
9
15
|
this.db = db;
|
|
@@ -15,7 +21,7 @@ export class BackgroundQueue {
|
|
|
15
21
|
this.queue
|
|
16
22
|
.add(() => task(this.db))
|
|
17
23
|
.catch((err) => {
|
|
18
|
-
dbLogger.error(err, 'background queue task failed');
|
|
24
|
+
logger_1.dbLogger.error(err, 'background queue task failed');
|
|
19
25
|
});
|
|
20
26
|
}
|
|
21
27
|
async processAll() {
|
|
@@ -28,3 +34,4 @@ export class BackgroundQueue {
|
|
|
28
34
|
await this.queue.onIdle();
|
|
29
35
|
}
|
|
30
36
|
}
|
|
37
|
+
exports.BackgroundQueue = BackgroundQueue;
|
|
@@ -3,11 +3,15 @@ import * as actorTable from './tables/actor';
|
|
|
3
3
|
import * as actorSyncTable from './tables/actor-sync';
|
|
4
4
|
import * as artistTable from './tables/artist';
|
|
5
5
|
import * as artistListItemTable from './tables/artist-list-item';
|
|
6
|
+
import * as oauthSessionTable from './tables/oauth-session';
|
|
7
|
+
import * as oauthStateTable from './tables/oauth-state';
|
|
6
8
|
import * as playlistTable from './tables/playlist';
|
|
7
9
|
import * as playlistIdeaTable from './tables/playlist-idea';
|
|
8
10
|
import * as playlistItemTable from './tables/playlist-item';
|
|
9
11
|
import * as profileTable from './tables/profile';
|
|
10
12
|
import * as recordTable from './tables/record';
|
|
11
13
|
import * as songTable from './tables/song';
|
|
12
|
-
|
|
14
|
+
import * as songRecommendationTable from './tables/song-recommendation';
|
|
15
|
+
import * as subscriptionCursorTable from './tables/subscription-cursor';
|
|
16
|
+
export type DatabaseSchemaType = actorTable.PartialDB & actorSyncTable.PartialDB & artistTable.PartialDB & artistListItemTable.PartialDB & oauthSessionTable.PartialDB & oauthStateTable.PartialDB & playlistTable.PartialDB & playlistIdeaTable.PartialDB & playlistItemTable.PartialDB & profileTable.PartialDB & recordTable.PartialDB & songTable.PartialDB & songRecommendationTable.PartialDB & subscriptionCursorTable.PartialDB;
|
|
13
17
|
export type DatabaseSchema = Kysely<DatabaseSchemaType>;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1,16 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Database = void 0;
|
|
40
|
+
const kysely_1 = require("kysely");
|
|
41
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
42
|
+
const node_events_1 = __importDefault(require("node:events"));
|
|
43
|
+
const pg_1 = require("pg");
|
|
44
|
+
const logger_1 = require("../../../logger");
|
|
45
|
+
const migrations = __importStar(require("./migrations"));
|
|
46
|
+
const provider_1 = require("./migrations/provider");
|
|
47
|
+
class Database {
|
|
9
48
|
opts;
|
|
10
49
|
pool;
|
|
11
50
|
db;
|
|
12
51
|
migrator;
|
|
13
|
-
txEvt = new
|
|
52
|
+
txEvt = new node_events_1.default();
|
|
14
53
|
destroyed = false;
|
|
15
54
|
constructor(opts, instances) {
|
|
16
55
|
this.opts = opts;
|
|
@@ -24,14 +63,14 @@ export class Database {
|
|
|
24
63
|
// else create a pool & connect
|
|
25
64
|
const { schema, url } = opts;
|
|
26
65
|
const pool = opts.pool ??
|
|
27
|
-
new
|
|
66
|
+
new pg_1.Pool({
|
|
28
67
|
connectionString: url,
|
|
29
68
|
max: opts.poolSize,
|
|
30
69
|
maxUses: opts.poolMaxUses,
|
|
31
70
|
idleTimeoutMillis: opts.poolIdleTimeoutMs,
|
|
32
71
|
});
|
|
33
72
|
// Select count(*) and other pg bigints as js integer
|
|
34
|
-
|
|
73
|
+
pg_1.types.setTypeParser(pg_1.types.builtins.INT8, (n) => parseInt(n, 10));
|
|
35
74
|
// Setup schema usage, primarily for test parallelism (each test suite runs in its own pg schema)
|
|
36
75
|
if (schema && !/^[a-z_]+$/i.test(schema)) {
|
|
37
76
|
throw new Error(`Postgres schema must only contain [A-Za-z_]: ${schema}`);
|
|
@@ -47,13 +86,13 @@ export class Database {
|
|
|
47
86
|
}
|
|
48
87
|
});
|
|
49
88
|
this.pool = pool;
|
|
50
|
-
this.db = new Kysely({
|
|
51
|
-
dialect: new PostgresDialect({ pool }),
|
|
89
|
+
this.db = new kysely_1.Kysely({
|
|
90
|
+
dialect: new kysely_1.PostgresDialect({ pool }),
|
|
52
91
|
});
|
|
53
|
-
this.migrator = new Migrator({
|
|
92
|
+
this.migrator = new kysely_1.Migrator({
|
|
54
93
|
db: this.db,
|
|
55
94
|
migrationTableSchema: opts.schema,
|
|
56
|
-
provider: new CtxMigrationProvider(migrations, 'pg'),
|
|
95
|
+
provider: new provider_1.CtxMigrationProvider(migrations, 'pg'),
|
|
57
96
|
});
|
|
58
97
|
}
|
|
59
98
|
get schema() {
|
|
@@ -87,10 +126,10 @@ export class Database {
|
|
|
87
126
|
return this.db.isTransaction;
|
|
88
127
|
}
|
|
89
128
|
assertTransaction() {
|
|
90
|
-
|
|
129
|
+
(0, node_assert_1.default)(this.isTransaction, 'Transaction required');
|
|
91
130
|
}
|
|
92
131
|
assertNotTransaction() {
|
|
93
|
-
|
|
132
|
+
(0, node_assert_1.default)(!this.isTransaction, 'Cannot be in a transaction');
|
|
94
133
|
}
|
|
95
134
|
onCommit(fn) {
|
|
96
135
|
this.assertTransaction();
|
|
@@ -129,9 +168,10 @@ export class Database {
|
|
|
129
168
|
this.destroyed = true;
|
|
130
169
|
}
|
|
131
170
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const
|
|
171
|
+
exports.Database = Database;
|
|
172
|
+
exports.default = Database;
|
|
173
|
+
const onPoolError = (err) => logger_1.dbLogger.error({ err }, 'db pool error');
|
|
174
|
+
const onClientError = (err) => logger_1.dbLogger.error({ err }, 'db client error');
|
|
135
175
|
// utils
|
|
136
176
|
// -------
|
|
137
177
|
class LeakyTxPlugin {
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./db"), exports);
|